官网的shader stencilBuffer篇(续)

来源:互联网 发布:mac 最近使用字体 编辑:程序博客网 时间:2024/06/04 05:14

<span style="font-family: Arial, Helvetica, sans-serif;">上一篇写到一个自负不能被挡的球,最后被挡了。</span>

这一篇做一些联想,先对那个档他的球的shader做一个修改,shader采用那个半黄半红的code

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        }    } }
先贴一张上次的图,就是把上次的挡它的球的shader换成另外一个,效果如下


然后再看看这次的效果



嗯,中间那块不一样了

根据之前的理论,这个双色球显示的原理是,没有被挡,显示内表面的颜色(黄色),被挡,显示正面的颜色(红色)

推测一下,黄色区域产生的原因是,这个双色球在这个红色球之前,因为红色球有一个cull front 的语句,所以,它只渲染内表面的朝向视角部分,就是说,它在深度测试通过之后应该是对深度值进行了赋值,所以depth buffer变成了它的。那对于双色球而言,那个交叉部分就是在它之前,所以显示为黄色。

所以说渲染顺序很重要,它决定了depth buffer的值

这里还有一个有趣的现象是,当你换个角度。


这里中间交叉部分,红球内表面在双色球内外表面中间,所以双色球不发挥作用,另一边是双色球内表面在红色球之前,所以能通过深度测试,显示出来

再换个角度,把这个红色球放在前面。


同样的理论,中间是红色球在双色球内,双色球不发挥作用,红色圈圈是因为双色球被挡,所以显示红色


然后,对于深度测试后赋值这个推论,还要进行考证。

为此,另外制作了一个球,蓝色球

Shader "Custom/ShaderForDepth" {SubShader {Tags { "RenderType"="Opaque" "Queue"="Geometry+3"}LOD 200CGPROGRAM#pragma surface surf Lambertstruct 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进行赋值,所以上面的渲染顺序是很重要的。

0 0