shader之——移动端阴影实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shader之——移动端阴影实现相关的知识,希望对你有一定的参考价值。

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

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

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

技术分享图片

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

 

代码如下:

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之——移动端阴影实现的主要内容,如果未能解决你的问题,请参考以下文章

shader之——移动端次时代

shader之——多光源漫反射以及阴影

移动端实时阴影+自投影技术实现

RenderDoc[02] 修改Shader,分析目标游戏阴影实现

Unity无光照假阴影Shader实现及常见问题总结

RenderDoc[02] 修改Shader,分析目标游戏阴影实现