读一读

有些模型多层需要深度写入和深度测试才能正常显示,但是又不去希望这个深度去影响到其他物体,就可以写多一个pass清除深度

例如模型上的ui,在3D相机下,UI不希望有偏移,只用sortorder去控制下

Pass {
    Name "Z Clear"
    ColorMask 0
    ZWrite On
    ZTest Always
 
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"
 
    float4 vert (float4 vertex : POSITION) : SV_Position
    {
        float4 pos = UnityObjectToClipPos(vertex);
    #if defined(UNITY_REVERSED_Z)
        pos.z = 1.0e-9f;
    #else
        pos.z = pos.w - 1.0e-6f;
    #endif
        return pos;
    }
 
    void frag() {}
    ENDCG
}



第二个Pass将模型压扁,偏移,渲染成透明的黑色

Shader "chicai/MeshShadow"
{
    Properties
    {
        _DiffuseIntensity("Diffuse Intensity", float) = 1
        _SpecularIntensity("Specular Intensity", float) = 1
        _Gloss("Gloss", float) = 1
        _ShadowPos("ShadowPos", vector) = (0,0,0,0)
    }
   
    SubShader
    {
        Tags { "RenderType"="Opaque"}
        LOD 100
        Pass{}

        //只能在平面上用
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha
            //透明渲染,会穿透渲染两层,过滤只一层
            Stencil
            {
                Ref 100
                Comp NotEqual
                Pass Replace
            }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
            };

            float4 _ShadowPos;

            v2f vert(appdata v)
            {
                v2f o;
                float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
                float tempPosy = worldPos.y - _ShadowPos.y;//将脚上到头顶的顶点计算到从0开始
                worldPos.y = _ShadowPos.y;//地面在世界坐标中的高度,压扁
                worldPos.xz += _ShadowPos.xz * tempPosy;//偏移影子
                o.pos = mul(UNITY_MATRIX_VP, worldPos);
                return o;
            }

            fixed4 frag(v2f i):SV_TARGET
            {
                return fixed4(0,0,0,_ShadowPos.w) ;
            }

            ENDCG
        }
    }
}



可以在SubShader中定义LOD的数值,然后根据设备性能情况设置LOD的值,调用指定的SubShader

SubShader
{
    LOD 300
}

SubShader
{
    LOD 200
}

SubShader
{
    LOD 100
}


在C#中进行设置
Shader.globalMaximumLOD = 100;



Tags { "RenderType"="Opaque" }
LOD 100
Offset -1,-1 //深度偏移 负数推近,正数推远



Properties
{
    [Enum(On,0,Off,1)]_ZWrite("ZWrite",int) = 0
    [Enum(UnityEngine.Rendering.CompareFunction)]_ZTest("ZTest",int) = 0
}
    
ZWrite [_ZWrite]
ZTest [_ZTest] //默认小于等于



Shader "chicai/LightMode"
{
    Properties
    {
        _DiffuseIntensity("Diffuse Intensity", float) = 1
        _SpecularIntensity("Specular Intensity", float) = 1
        _Gloss("Gloss", float) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque"}
        LOD 100

        Pass
        {
            Tags { "LightMode"="ForwardBase" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"


            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                half3 normal:NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                half3 worldNormal:TEXCOORD1;
                float3 worldPos:TEXCOORD2;
            };

            half _DiffuseIntensity;
            float _SpecularIntensity;
            float _Gloss;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = 0;
                fixed4 Ambient = unity_AmbientSky;
                half Kd = _DiffuseIntensity;
                fixed4 LightColor = _LightColor0;
                fixed3 N = normalize( i.worldNormal );
                fixed3 L = _WorldSpaceLightPos0;
                fixed4 diffuse = Ambient + Kd * LightColor * max(0,dot(N,L));
                col += diffuse;

                //Phong高光
                //float3 reflectDir = reflect(-L, N);
                fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);
                // fixed4 specularColor = _LightColor0 * _SpecularIntensity * (pow( max( dot(reflectDir,viewDir) ,0),_Gloss) );
                // col += specularColor;

               
                //Bilnn-Phong高光
                fixed4 specularColor = _LightColor0 * _SpecularIntensity * (pow( max(dot(i.worldNormal, normalize(L+viewDir)),0), _Gloss));
                col += specularColor;
                return col;
            }
            ENDCG
        }

        Pass
        {
            Tags { "LightMode"="ForwardAdd" }
            Blend One One
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdadd //Builtin keywords used: POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE
            #pragma skip_variants DIRECTIONAL POINT_COOKIE DIRECTIONAL_COOKIE//剔除不要的变体

            #include "UnityCG.cginc"
            #include "Lighting.cginc"//_LightColor0 _WorldSpaceLightPos0
            #include "AutoLight.cginc"//unity_WorldToLight _LightTexture0 衰减贴图

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                half3 normal:NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                half3 worldNormal:TEXCOORD1;
                float3 worldPos:TEXCOORD2;
            };

            half _DiffuseIntensity;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.uv = v.uv;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 LightColor = _LightColor0;
                fixed3 N = normalize( i.worldNormal );
                fixed3 L = _WorldSpaceLightPos0;

                //float3 lightCoord = mul(unity_WorldToLight, float4(i.worldPos.xyz,1)).xyz;//距离灯光位置 点光源的
                //float atten = tex2D(_LightTexture0, dot(lightCoord,lightCoord));
                UNITY_LIGHT_ATTENUATION(atten, 0, i.worldPos);//光照衰减 第二参数计算阴影的



                fixed4 diffuse = LightColor * max(0,dot(N,L)) * atten;

                return diffuse;
            }
            ENDCG
        }
    }
}



Shader "chicai/UIRectClip"
{
    Properties
    {
        [PerRendererData]_MainTex ("MainTex", 2D) = "white" {}
        _Ref("Ref",int) = 0
        [Enum(UnityEngine.Rendering.CompareFunction)]_StencilComp("Stencil Comp",int) = 0
        [Enum(UnityEngine.Rendering.StencilOp)]_StencilOp("Stencil OP",int) = 0
    }

    SubShader
    {
        Tags { "Queue"="Transparent" "RenderType"="Transparent" }
        LOD 100
        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask RGBA

        Stencil
        {
            Ref [_Ref]
            ReadMask 3
            Comp [_StencilComp]
            Pass [_StencilOp]
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #pragma multi_compile _ UNITY_UI_CLIP_RECT//内置的宏定义,有RectMask2D会自动对它修改

            #include "UnityCG.cginc"
            #include "UnityUI.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                fixed4 color : COLOR;//UI的颜色 传过来的是顶点颜色 
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR;
                fixed4 worldPos : TEXCOORD1;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _ClipRect;//内置变量 RectMask2D组件

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.color = v.color;
                o.worldPos = v.vertex;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                col *= i.color;

                #if UNITY_UI_CLIP_RECT
                    fixed2 rect = clip(_ClipRect.xy, i.worldPos.xy) * clip(i.worldPos.xy, _ClipRect.zw);
                    col.a *= rect.x * rect.y;
                    //col.a *= UnityGet2DClipping(i.worldPos, _ClipRect);
                #endif

                return col;
            }
            ENDCG
        }
    }
}



//Inside C# Monobehaviour script
materialPropertyBlock.Clear();
sr.GetPropertyBlock(materialPropertyBlock);
materialPropertyBlock.AddFloat(dissolvePropertyID, dissolveValue);
sr.SetPropertyBlock(materialPropertyBlock);
 
//Inside the shader
Properties{
[PerRendererData] _SliceAmount("Slice Amount", Float) = 0.5
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
}

针对多个相同材质,不同属性参数设置,减少性能消耗



Shader "chicai/HotDistort2"
{
    Properties
    {
        _DistortTex ("DistortTex", 2D) = "white" {}
        _Distort ("Distort",Range(0,1)) = 0
        _DistortUVSpeedX("DistortUVSpeedX",float) = 0
        _DistortUVSpeedY("DistortUVSpeedY",float) = 0
    }
    SubShader
    {
        Tags { "Queue"="Transparent" }

        GrabPass{"_GrabTex"}

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex:POSITION;
                fixed2 uv:TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                float4 screenPos :TEXCOORD1;
            };

            sampler2D _DistortTex;
            float4 _DistortTex_ST;
            sampler2D _GrabTex;
            fixed _Distort;
            float _DistortUVSpeedX,_DistortUVSpeedY;

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.screenPos = ComputeScreenPos(o.pos);//转换到[0到w],当uv用需要除以w分量
                o.uv = TRANSFORM_TEX(v.uv, _DistortTex) + float2(_DistortUVSpeedX, _DistortUVSpeedY) * _Time.y;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 distortCol = tex2D(_DistortTex, i.uv);
                fixed2 uv = lerp(i.screenPos.xy / i.screenPos.w, distortCol, _Distort);
                fixed4 col = tex2D(_GrabTex, uv);
                return col;
            }
            ENDCG
        }
    }
}


Shader "chicai/HotDistort3"
{
    Properties
    {
        _DistortTex ("DistortTex", 2D) = "white" {}
        _Distort ("Distort",Range(0,1)) = 0
        _DistortUVSpeedX("DistortUVSpeedX",float) = 0
        _DistortUVSpeedY("DistortUVSpeedY",float) = 0
    }
    SubShader
    {
        Tags { "Queue"="Transparent" }

        GrabPass{"_GrabTex"}

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex:POSITION;
                fixed2 uv:TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
            };

            sampler2D _DistortTex;
            float4 _DistortTex_ST;
            sampler2D _GrabTex;
            fixed _Distort;
            float _DistortUVSpeedX,_DistortUVSpeedY;

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);//裁剪空间下的
                o.uv = TRANSFORM_TEX(v.uv, _DistortTex) + float2(_DistortUVSpeedX, _DistortUVSpeedY) * _Time.y;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //i.pos 屏幕的像素坐标 硬件转换
                float2 uv = i.pos.xy/_ScreenParams.xy;
                fixed4 distortCol = tex2D(_DistortTex, i.uv);
                uv = lerp(uv, distortCol, _Distort);
                fixed4 col = tex2D(_GrabTex, uv);
                return col;
            }
            ENDCG
        }
    }
}



混合因子:

One

Zero

SrcColor 源颜色

SrcAlpha 源的Alpha值

DstColor 目标颜色

DstAlpha 目标Alpha值

OneMinusSrcColor

OneMinusSrcAlpha

OneMinusDstColor

OneMinusDstAlpha


常用混合类型

Blend SrcAlpha OneMinusSrcAlpha //传统透明混合

Blend One OneMinusSrcAlpha //预乘透明混合

Blend One One

Blend OneMinusDstColor One //Soft Additive

Blend DstColor Zero //Multiplicative

Blend DstColor SrcColor //2x Multiplicative