本日はShader学習枠です。
先日はMRTK(MRGT)Standardシェーダーを使用してオブジェクトが重なっていたとしても最前面に描画されるシェーダーを書いていきました。
今回はコードとして実装していきます。
こんかいは次のようなプリミティブオブジェクトを配置したシーンを用意しました。
画像で選択中(オレンジラインが出ている)球を最前面描画するシェーダーを書いていきます。
〇シェーダーの描画順
シェーダーでは基本的に次のルールで描画順が決まっています。
・不透明なもの→半透明なもの
・レンダーキューの順番(数値が低いものほど先に描画されます。)
・カメラから見た際に遠くにある→近くにある
・その他(ステンシル等)
その他複雑な条件はあるものの上記の条件を押さえておけば大体対応可能です。
基本的にシェーダーでは上書きするように塗りつぶしているため後に描画されるものほど手前に描画されるように見えます。
半透明なオブジェクトが不透明なオブジェクトの後に描画されるのは半透明なオブジェクトはすでに描画された画像に混ぜるように描画を行っているためです。
〇最前面描画を行う
最前面描画を行う一番早い方法はZTest Offを記述することです。
Shader "Unlit/Shader" { Properties { } SubShader { ZTest Off//追加 Pass { CGPROGRAM ・・・ ENDCG } } }
Zとは深度すなわち奥行のことで奥行を比較して描画を行っていると前述しましたが、この比較をZTestと呼びます。
Offにすることで無効になり、遠くあっても近くにあっても遮るものに関係なく描画されます。
この状態ではオブジェクトの位置関係に依存せず描画が行われますが、Render Queueの影響は受けます。
例えば画像で見て重なって見えるキューブのマテリアルのキューが2001と最前面描画されてほしい球(2000)より一つ大きい場合は次のようになります。
これは深度の問題がなくても別のRenderQueueの影響を受ける条件があるため2000の球よりも2001のキューブが後に描画され、塗りつぶされてしまっているからです。
この場合は球のRenderQueueを2450に指定することで最前面描画が行われます。
この場合もキューブが2401などのキューを持つ場合は同様に最前面描画されなくなりますが、このような状況はほとんどありません。
以上がUnityで最前面描画を行うシェーダーでした。