基本原理:使用Projector和Camera结合实现的动态阴影,使用Camera渲染出一张模型轮廓图,再用Projector投射到场景的接收物体上。

思路:

1、创建一个GameObject用来挂载Projector和Camera。

2、生成一张RenderTexture贴图,命名为mShadowRT。

3、创建一个单独渲染主角轮廓的相机,挂在GameObject上,为相机替换一个简单shader(ShadowCaster),只渲染模型的轮廓图, 渲染的结果targetTexture 保存到mShadowRT中。

4、创建一个投射器Projector,挂在GameObject上,为Projector设置一个投影shader(ShadowReceive), 该shader的材质贴图使用保存有相机渲染的mShadowRT。

5、GameObject随主角位置的移动而更新。

 

两个Shader:

ShadowCaster:

 1 Shader "xj/ModelEffect/ShadowReceive" 
 2 {
 3     Properties {
 4         _ShadowTex ("ShadowTex", 2D) = "gray" {}
 5         _bulerWidth ("BulerWidth", float) = 1
 6         _shadowfactor ("Shadowfactor", Range(0,1)) = 0.3
 7         _ShadowMask ("ShadowMask",2D) = "white"{}
 8     }
 9     SubShader {
10         Tags { "Queue"="AlphaTest+1" }
11         Pass {
12             ZWrite Off
13             ColorMask RGB
14             Blend DstColor Zero
15             Offset -1, -1
16 
17             CGPROGRAM
18             #pragma vertex vert
19             #pragma fragment frag
20             #include "UnityCG.cginc"
21 
22             struct v2f {
23                 float4 pos:POSITION;
24                 float4 sproj:TEXCOORD0;
25             };
26 
27             float4x4 _Projector;
28             sampler2D _ShadowTex;
29             sampler2D _ShadowMask;
30             uniform half4 _ShadowTex_TexelSize;
31             float _bulerWidth;
32             float _shadowfactor;
33 
34             v2f vert(float4 vertex:POSITION){
35                 v2f o;
36                 o.pos = mul(UNITY_MATRIX_MVP,vertex);
37                 o.sproj = mul(_Projector, vertex);
38                 return o;
39             }
40 
41             float4 frag(v2f i):COLOR{
42                 
43                 half4 shadowCol = tex2Dproj(_ShadowTex, UNITY_PROJ_COORD(i.sproj));
44                 half maskCol = tex2Dproj(_ShadowMask, UNITY_PROJ_COORD(i.sproj)).r;
45                 half a = (shadowCol * maskCol).a;
46                 if(a > 0)
47                 {
48                     return  float4(1,1,1,1) * (1 - _shadowfactor * a);
49                 }
50                 else
51                 {
52                     return float4(1,1,1,1) ;
53                 }
54             }
55 
56             ENDCG
57         }
58     } 
59     FallBack "Diffuse"
60 }
View Code

相关文章: