GLSL in Unity 系列文章(七):遮挡X光透视效果

今天使用GLSL在Unity3D中实现一个遮挡X光透视效果,老规矩,先上效果:


遮挡X光透视效果

这个效果的原理也比较简单,首先使用正常的一个pass来绘制物体,然后新增一个pass用于绘制被遮挡部分的效果,主要是通过深度测试来实现,正常的深度测试是小于当前深度缓冲中的值的片元会通过测试,而我们为绘制被遮挡的部分,所以改为大于当前深度缓冲中的值的片元才通过测试,并关闭深度写入,避免影响正常的绘制pass。

ZTest Greater
ZWrite Off

以下是shader的完整代码:

Shader "GLSL/XRay"
{
    Properties
    {
        _MainTex("Base 2D", 2D) = "white" {}
        _XRayColor("XRay Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Pass // 正常绘制
        {
            Tags{ "RenderType"="Opaque" }
            ZTest LEqual//default
            ZWrite On//default
            GLSLPROGRAM
            //gl_Vertex 顶点
            //gl_MultiTexCoord0 uv
            //gl_Normal 顶点法线
            //gl_Position 裁剪空间坐标输出到片元着色器
            //gl_FragColor 输出颜色
            #include "UnityCG.glslinc"

            uniform vec4 _MainTex_ST;
            struct v2f {
                vec2 textureCoord;
            };

            #ifdef VERTEX
            out v2f v;
            void main()
            {            
                gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
                v.textureCoord = TRANSFORM_TEX_ST(gl_MultiTexCoord0, _MainTex_ST);//处理tiling和offset
            }
            #endif
            #ifdef FRAGMENT
            uniform sampler2D _MainTex;
            in v2f v;
            void main()
            {
                gl_FragColor = texture2D(_MainTex, v.textureCoord);
            }
            #endif
            ENDGLSL  
        }
        Pass // xRay 绘制
        {
            Tags{ "RenderType"="Transparent" "Queue"="Transparent"}
            Blend SrcAlpha One
            ZTest Greater//深度测试,大于当前的通过测试
            ZWrite Off//关闭深度写入
            Cull Back//default
            GLSLPROGRAM
            #include "UnityCG.glslinc"
            #ifdef VERTEX
            uniform vec4 _XRayColor;
            out vec4 xRayColor;            
            void main()
            {            
                gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
                vec3 viewDir = ObjSpaceViewDir(gl_Vertex);//模型空间下的视方向
                vec3 normal = normalize(gl_Normal);
                viewDir = normalize(viewDir);
                float rim = 1.0 - dot(normal, viewDir);//边缘颜色更深,正面颜色更浅
                xRayColor = _XRayColor * rim;
            }
            #endif
            #ifdef FRAGMENT
            in vec4 xRayColor;
            void main()
            {
                gl_FragColor = xRayColor;
            }
            #endif
            ENDGLSL
        }        
    }
}

github:https://github.com/eangulee/GLSLInUnity.git

你可能感兴趣的:(GLSL in Unity 系列文章(七):遮挡X光透视效果)