参考:ShaderLab syntax: Culling & Depth Testing
英語の'cull'は「選びとる・間引く」という意味だが、CGの世界では「除外する」ととらえるとわかりすい。たとえば、「バックフェース・カリング」はポリゴンの裏面を表示しない処理になる。また、オブジェクトのもっとも近いサーフィス以外を表示しない「デプス・テスト」もカリングの一種。
Cull Back|Front|Off
ポリゴンのどの面をカリングするかの指定。
デフォルトは'Back'で、裏面を表示しない。'Off'は両面を表示。
ZWrite On | Off
このオブジェクトのからのピクセルをDepth Bufferに書き込むかどうか。デフォルトはOn。
ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always
Depth Testの方法。デフォルトは'LEequal' = 存在するオブジェクトより近いものと同じ距離にあるものは表示、それより背後にあるものは非表示)
Offset Factor, Units
Depthパラメータのオフセット。FactorはZの最大値を、X,Y値に対してスケーリングする。UnitsはDepth Buffer値の最小値をスケーリングする。
これによって、あるポリゴンを常に上側に表示できる。たとえば、'Offset 0, -1'は、ポリゴンの傾きを無視してポリゴンをカメラに近づける。一方、'Offset -1, -1'は、ポリゴンをさらに近くに表示する。
サンプル
1. オブジェクトの裏面のみをレンダリングする
Shader "Show Insides" { SubShader { Pass { Material { Diffuse (1,1,1,1) } Lighting On Cull Front } } }
2. 深度を考慮したトランスペアレント・シェーダ
通常のトランスペアレント・シェーダではDepthを考慮せず、単純に描画順で前後が決まるらしい。これを回避するには、深度情報を考慮したトランスペアレント・シェーダを作る必要がある。下がその例。 参考:Unity で Transparent/Diffuse で描画順が崩れてしまう際の対処法
ZWrite On
でDepth Bufferに書き込み、ColorMask 0
でレンダリングはしない。そのかわりに
Shader "Transparent/Diffuse ZWrite" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} } SubShader { Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} LOD 200 // extra pass that renders to depth buffer only Pass { ZWrite On ColorMask 0 } // paste in forward rendering passes from Transparent/Diffuse UsePass "Transparent/Diffuse/FORWARD" } Fallback "Transparent/VertexLit" }
3. 法線ベクトルの修正
最初のパスでは通常のVertex Lightingでレンダリングし、2番めのパスでオブジェクトの背面をピンク色でレンダリングする。裏向きポリゴンを発見する際に便利なシェーダ。
Shader "Reveal Backfaces" { Properties { _MainTex ("Base (RGB)", 2D) = "white" { } } SubShader { // Render the front-facing parts of the object. // We use a simple white material, and apply the main texture. Pass { Material { Diffuse (1,1,1,1) } Lighting On SetTexture [_MainTex] { Combine Primary * Texture } } // Now we render the back-facing triangles in the most // irritating color in the world: BRIGHT PINK! Pass { Color (1,0,1,1) Cull Front } } }
4. グラス・カリング
ガラスのような半透明なオブジェクトでは、オブジェクトの裏面が透けて見えるようにしたい。そのためのシェーダ。裏面と表面を2パスでレンダリングする。 spheres, cubes, car windscreensなどの凸形状のオブジェクト適用できる。
Shader "Simple Glass" { Properties { _Color ("Main Color", Color) = (1,1,1,0) _SpecColor ("Spec Color", Color) = (1,1,1,1) _Emission ("Emmisive Color", Color) = (0,0,0,0) _Shininess ("Shininess", Range (0.01, 1)) = 0.7 _MainTex ("Base (RGB)", 2D) = "white" { } } SubShader { // We use the material in many passes by defining them in the subshader. // Anything defined here becomes default values for all contained passes. Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] Emission [_Emission] } Lighting On SeparateSpecular On // Set up alpha blending Blend SrcAlpha OneMinusSrcAlpha // Render the back facing parts of the object. // If the object is convex, these will always be further away // than the front-faces. Pass { Cull Front SetTexture [_MainTex] { Combine Primary * Texture } } // Render the parts of the object facing us. // If the object is convex, these will be closer than the // back-faces. Pass { Cull Back SetTexture [_MainTex] { Combine Primary * Texture } } } }