官網的shader stencilBuffer篇(續)
阿新 • • 發佈:2019-01-01
<span style="font-family: Arial, Helvetica, sans-serif;">上一篇寫到一個自負不能被擋的球,最後被擋了。</span>
這一篇做一些聯想,先對那個檔他的球的shader做一個修改,shader採用那個半黃半紅的code
先貼一張上次的圖,就是把上次的擋它的球的shader換成另外一個,效果如下Shader "HolePrepare" { SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry+3"}//這裡修改一個渲染次序,把這個球的渲染次序放在那個擋不住的球之後 //ColorMask 0 ZWrite off Stencil { Ref 1 Comp always Pass replace } CGINCLUDE struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); return o; } half4 frag(v2f i) : SV_Target { return half4(1,1,0,1); } half4 frag2(v2f i) : SV_Target { return half4(1,0,0,1); } ENDCG Pass { Cull Front ZTest Less CGPROGRAM #pragma vertex vert #pragma fragment frag ENDCG } Pass { Cull Back ZTest Greater CGPROGRAM #pragma vertex vert #pragma fragment frag2 ENDCG } } }
然後再看看這次的效果
嗯,中間那塊不一樣了
根據之前的理論,這個雙色球顯示的原理是,沒有被擋,顯示內表面的顏色(黃色),被擋,顯示正面的顏色(紅色)
推測一下,黃色區域產生的原因是,這個雙色球在這個紅色球之前,因為紅色球有一個cull front 的語句,所以,它只渲染內表面的朝向視角部分,就是說,它在深度測試通過之後應該是對深度值進行了賦值,所以depth buffer變成了它的。那對於雙色球而言,那個交叉部分就是在它之前,所以顯示為黃色。
所以說渲染順序很重要,它決定了depth buffer的值
這裡還有一個有趣的現象是,當你換個角度。
這裡中間交叉部分,紅球內表面在雙色球內外表面中間,所以雙色球不發揮作用,另一邊是雙色球內表面在紅色球之前,所以能通過深度測試,顯示出來
再換個角度,把這個紅色球放在前面。
同樣的理論,中間是紅色球在雙色球內,雙色球不發揮作用,紅色圈圈是因為雙色球被擋,所以顯示紅色
然後,對於深度測試後賦值這個推論,還要進行考證。
為此,另外製作了一個球,藍色球
Shader "Custom/ShaderForDepth" { SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry+3"} LOD 200 CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = half3(0,0,1); o.Alpha = 1.0; } ENDCG } FallBack "Diffuse" }
這個球和普通的球一樣,可以被平面遮擋,但是,僅有一個不同是它的渲染次序也在那個擋不住的球之後
如圖
所以,將它們放在一起
可以看到藍色球可以被平面切割,與紅色球相交部分可以遮擋紅色球
所以推論成功,深度測試之後會對深度buffer進行賦值,所以上面的渲染順序是很重要的。