shader之——移动端阴影实现

移动端阴影的实现有很多种方式,用shader实现个人觉得是比较省的方法。原理比较简单,

将模型的沿着y方向压扁,然后按照一个方向把zx做延伸,相当于多渲染一次模型,也多了一个dc

但是比起昂贵的实时阴影,还是相当省的。

shader之——移动端阴影实现_第1张图片

阴影相当于一个平面,即使是这样,也可以适应稍有起伏的地形

 

代码如下:

 

Shader "Game-X/PlanarShadow" {

    Properties {
        _Strength ("Strength", Range(0.1, 10)) = 3
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Projplane ("_Projplane", Float) = 0
        _Lightdir ("_Lightdir", Vector) = (0, 0.707, 0.707)
    }
    SubShader {
        
        Tags { "Queue" = "Geometry+1" "RenderType" = "Opaque" }
        
        pass {   
            Tags { "LightMode" = "ForwardBase" } 
            Blend One SrcAlpha
            ZWrite Off
            ZTest Off

        
            
            CGPROGRAM
            #pragma vertex vert 
            #pragma fragment frag
            #pragma multi_compile _BLEND_ALPHA_ON _BLEND_ALPHA_OFF
            #pragma multi_compile _BLEND_ADDITIVE_ON _BLEND_ADDITIVE_OFF
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            struct vsIn
            {
                float4 vertex   : POSITION;
                #if defined (_BLEND_ALPHA_ON) || defined (_BLEND_ADDITIVE_ON)
                float2 texcoord : TEXCOORD0;
                #endif
            };

            struct vsOut
            {
                float4 wpos        : SV_POSITION;
                #if defined (_BLEND_ALPHA_ON) || defined (_BLEND_ADDITIVE_ON)
                float2 texcoord : TEXCOORD0;     
                #endif 
            };
            
            float _Strength;
            float _Projplane;
            float3 _Lightdir;

            sampler2D _MainTex;
            float4 _MainTex_ST;
            
            vsOut vert(vsIn In)
            {
                vsOut o;
                float4 wp = mul(unity_ObjectToWorld, In.vertex);
                if (wp.y < _Projplane)
                    wp.y = _Projplane;

                wp.xz = wp.xz - ((wp.y - _Projplane) / _Lightdir.y) * _Lightdir.xz; 
                wp.y = _Projplane;
                o.wpos = mul(UNITY_MATRIX_VP, wp);
                #if defined (_BLEND_ALPHA_ON) || defined (_BLEND_ADDITIVE_ON)
                o.texcoord = TRANSFORM_TEX(In.texcoord, _MainTex);
                #endif
                return o;
            }
            
             float4 frag(vsOut In) : COLOR 
            {
                float4 ambient = UNITY_LIGHTMODEL_AMBIENT * 2;
                float k = (ambient.r + ambient.g + ambient.b) / _Strength; 
                #ifdef _BLEND_ALPHA_ON
                float a = tex2D(_MainTex, In.texcoord).a;
                k = lerp(1, k, a);
                if (a <= 0)
                    clip(-1);
                #endif
                #ifdef _BLEND_ADDITIVE_ON
                float3 t = tex2D(_MainTex, In.texcoord).rgb;
                float q = (t.r + t.g + t.b) / 3;
                if (q <= 0)
                    clip(-1);
                #endif
                return float4(0,0,0,k);
            }
            
             ENDCG 
        }
   }
}

 

亲,如果您觉得本文不错,愿意给我一些动力的话,请用手机扫描二维码即可向我打赏

                                         打赏

 

 

 

你可能感兴趣的:(shader效果)