1.初めに
Unityで鏡を実装してみたくなり、ちょっと調べたところ、鏡面反射を実装するためにリフレクションプローブというものを用いるとありました。ところが、このリフレクションプローブにはカメラが6個含まれ、処理が重そうです。
球体や立方体等の反射ならともかく、平面の鏡にそこまでたくさんのカメラは必要ないと思われます。そこで、リフレクションプローブを使用せず、カメラ1個で鏡を実装してみました。
2.用意するもの
a.鏡として用いるオブジェクト
平面でも、ほぼ平面状のでこぼこしたものでもいいです。反射面が一方向を向いているものしか対応できません。
b.鏡用のカメラ
鏡に映る景色用のテクスチャをレンダリングするためのカメラです。
aの前に置いて、鏡の子にします。
c.レンダーテクスチャ
bのカメラでレンダリングした風景が格納されます。
d.鏡用のマテリアル
bのカメラから得たテクスチャcをaに貼り付けます。
e.鏡用のカメラを反射方向に向けるスクリプト
bのカメラを反射方向に向けて鏡を再現します。
3.作業手順
(1)鏡用のオブジェクト(a)を設置
ここではヒエラルキーでマウスの右ボタンを押して、3D Object>Planeを選びます。
必要なら、適当にスケールを変えたり、移動させたり、回転させたりしてください。
(2)レンダーテクスチャ(c)を作成
プロジェクトウインドウでマウスの右ボタンを押し、Create>Render Textureを選びます。
(3)鏡用のカメラ(b)を設置
ヒエラルキーでマウスの右ボタンで作成します。Target Textureにレンダーテクスチャ(c)を指定してください。また、Target Displayはメインカメラとは異なるものを選択してください。
鏡用のオブジェクト(a)の前に置き、鏡用のオブジェクト(a)の子にします。
(4)鏡用のマテリアル(d)の作成と適用
プロジェクトウインドウでマウスの右ボタンを押し、Create>Material。テクスチャとしてレンダーテクスチャ(c)を指定してください。
このマテリアル(d)をヒエラルキーの鏡用のオブジェクト(a)にドラッグ&ドロップします。
この時点で、鏡用のカメラ(b)からみた風景が鏡用のオブジェクト(a)に映っているはずです。
(5)鏡用カメラのスクリプト(e)を作成
このスクリプトで鏡用のカメラ(b)をメインカメラから鏡に向かうベクトルが鏡で反射される方向に向けます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MirrorReflectionCam : MonoBehaviour {
public Transform mainCam;
public Transform mirror;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
Vector3 A = mirror.position - mainCam.position;
Vector3 refVec = Vector3.Reflect(A, mirror.up);
Quaternion rot = Quaternion.LookRotation(refVec,mainCam.up);
gameObject.transform.rotation = rot;
}
}
このようなスクリプトを鏡用のカメラにアタッチします。インスペクタから、mirrorに鏡用のオブジェクト(a)を指定し、mainCamにメインカメラを指定します。
Vector3.Reflectは、入射ベクトルと反射面の法線を指定すると、反射ベクトルを返してくれる便利な関数です。
これで実行させれば、鏡用のオブジェクト(a)が鏡のように機能しているはずです。
上のスクリーンショットのメインカメラと鏡、及び、その他のオブジェクトの位置関係は下のスクリーンショットのようになっています。移動用のピボットが出ているのが鏡用のカメラ(b)で、右下のカメラがメインカメラです。このスクリーンショットは実行中に一時停止したもので、鏡用のカメラ(b)が反射方向に向いていることがわかります。