概要
UnityでVR対応のどこでもドア実現を目指す その1 Depth Mask編
上記ページにて利用してる知識やテクニックについての解説を記載します
備考
- 今回のどこでもドア実装に関してのポイント部分は太字で記載します
Unityにカメラの仕様
※以下は将来的に変更される可能性があるかもしれません
Target Texture 指定の有無
カメラのTarget Textureの指定の有無で、挙動が一部変更される
非VR | VR Support | |
---|---|---|
指定無し | Screenに描画 | 両目用カメラが生成され、両目それぞれのScreenに描画 |
指定有り | TargetのRender Textureに描画 | 非VRと同様、単体カメラとして動作し、TargetのRender Textureに描画 |
※上記挙動はMainCameraタグの有無に関わらず、どのカメラにも適用される
VRでも両目用が生成されることが今回のポイントの1つ
カメラが複数存在する場合の描画順
カメラが複数存在する場合 カメラの設定項目のDepthの値が 小さい -> 大きい の順番でScreenに描画される
※後述のDepth Bufferと混同する可能性があるため、以降「カメラのDepth」と記載
Depth Test
あるメッシュの描画時にカメラからの距離を保存し、次のメッシュを描画するときに
- カメラから見て奥であれば描画しない
- カメラから見て手前であれば描画する
を行う仕組み。
Depth Buffer
あるメッシュを描画した際、カメラからの距離をピクセル単位で保存した情報。
この情報をもとに次のメッシュを描画するときにカメラから見て奥、手前どちらにあるかを比較することができる
カメラの Clear Flags
Clear Flagsとは自分より前回のカメラ(「カメラのDepth」が自分より小さいカメラ)が描画した情報のうち、どの情報をClearするかを指定するフラグです。
簡易的に説明を書きますが、詳細は公式ドキュメントを参照してください。
フラグ名 | 説明 | 備考 |
---|---|---|
Solid color | 描画開始前にBackground設定色で塗りつぶし、Depth Bufferもクリアする | 前回のカメラの描画を引き継がない |
Skybox | 描画開始前にDepth Bufferをクリアし、不透明メッシュの最後にskyboxメッシュを描画 | 描画開始時、前回のカメラの描画したメッシュはそのまま |
Depth only | 描画開始前にDepth Bufferをクリアする。Skyboxは描画しない | 画開始時、前回のカメラの描画したメッシュはそのまま |
Don't Clear | 前回カメラが描画した情報をすべて引き継ぐ | 前回カメラの描画完了後の状態で現在のカメラの描画を開始 |
Skybox
Skyboxメッシュは以下の特徴があります。
- **不透明メッシュの最後(Render Queue 2500より後)**に描画
- Depth Bufferが初期値の領域に描画
※Render Queueについては後述
以下に画像を例にすると、
- 赤カメラ(カメラのDepthは-1)が先に描画
- Sceneビュー(画像の左上)のプレビューが描画したもの
- 青カメラ(カメラのDepthは0)が次に描画
- 前回のカメラの情報を青球、そしてskyboxメッシュで上書き
- 青カメラの描画開始時にDepth Bufferがクリアされたため
よってSkyboxで上書きされたくない場合は、先にその領域のDepth Bufferを更新すれば良いことになります。
Depth Mask
Depht Mask Material はこのテクニックを利用しています。
Depth Mask Material を利用すると以下のことが実現できます。
- スクリーン上の色を変更することなく、そのメッシュの領域のDepth Bufferを更新
以下の画像で言えば、明るい部分にDepth Maskをかけています。
※参考:http://wiki.unity3d.com/index.php?title=DepthMask (英語ですが、右部の画像はDepth Maskを使って、船の内部に水面が描画されないようにしています)
Render Queue
Unity のカメラは描画対象のメッシュ(「Culling Mask」で設定)を描画するとき、
Materialの設定「Render Queue」を参考にして、描順が決められます。
Render Queueの値が 小 -> 大 の順番で描画されます。
Depth Mask用ShaderをアタッチしたMaterialを作成 ではDepth Maskを先にかけるために、他メッシュより小さい値に変更しています。
SkyboxのRender Queueについて
Unity 5.6.1f1では、Skyboxメッシュの描画はRender Queue 2500より後に実施されました。
よってDepth Mask MaterialのRender Queueを2500より前にすれば、少なくともskyboxには上書きされないということになります。