基本原理:使用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 }