移动端阴影的实现有很多种方式,用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 } } }
时间: 2024-11-05 18:52:45