首页 > 代码库 > Unity的棋盘格剔除Shader

Unity的棋盘格剔除Shader

unity似乎是在5.3之后更新了文档页面,其中有一处棋盘格剔除的脚本

https://docs.unity3d.com/Manual/SL-ShaderSemantics.html

 

技术分享

 

我加了点注释和参数控制,代码如下:

Shader "Unlit/Screen Position"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _SizeFactor("SizeFactor", float) = 0.25
    }
    SubShader
    {
        CULL Off
        Blend SrcAlpha OneMinusSrcAlpha

        tags
        {
            "Queue" = "Transparent"
            "RenderType" = "Transparent"
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 3.0

            struct v2f {
                float2 uv : TEXCOORD0;
            };

            v2f vert(
                float4 vertex : POSITION,
                float2 uv : TEXCOORD0,
                out float4 outpos : SV_POSITION
            )
            {
                v2f o;
                o.uv = uv;
                outpos = mul(UNITY_MATRIX_MVP, vertex);
                return o;
            }

        sampler2D _MainTex;
        float _SizeFactor;

        fixed4 frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
        {
            //大概是unity5.3之后增加了一组参数传递,可以在顶点着色器中传入顶点id,或者传入屏幕位置等等。
            //这里用到的screenPos并非0-1的区间,而是960x480之类的真实位置。
            //还有许多新增加的内容,具体查阅文档.

            screenPos.xy = floor(screenPos.xy * _SizeFactor) * 0.5;//乘以0.5就是除以2,这样只有两种余数结果.5和0。
            float checker = -frac(screenPos.r + screenPos.g);//这里frac是取得余数部分,取负数是因为下面clip函数。
            //这样结果就是 -5和0。

            // clip函数只判断正数或者负数,如果为负则不渲染.这样-5的值就会不被渲染.
            clip(checker);

            fixed4 c = tex2D(_MainTex, i.uv);
            return c;
        }
        ENDCG
        }
    }
}

 

 

最终效果(改变_SizeFactor可以调节棋盘格大小):

技术分享

 

 

既可以把这种剔除效果用在相机近处,也可以用在远处低lod的物体上(树木等),以提高性能。

Unity的棋盘格剔除Shader