untiy 3d ShaderLab_第9章_1_平面阴影(三) 点光源对平面的投影

9.3 阴影的淡出
9.3.1 有效利用计算平面阴影过程中的数据

      一般情况下,比如用Shadow Mapping和Shadow Volumes计算阴影的衰减是比较困难的,但是在此例中,我们己经知道投射阴影物体的顶点在计算前和计算后的位置,根据这两个位置的距离,我们还是可以考虑计算一下阴影的衰减问题的。




      可以明显看出圆柱体投射在平而上的阴影随着距离而逐渐变淡。如果这是你所希望的效果,可以看一下代码:
<pre name="code" class="csharp">Shader "Tut/Shadow/PlanarShadow_3" {
	Properties{
	_Intensity("atten",range(1,16))=1
	}
	SubShader {
	pass {      
		Tags { "LightMode" = "ForwardBase" }
		Material{Diffuse(1,1,1,1)}
		Lighting On
		}//
	pass {   
		Tags { "LightMode" = "ForwardBase" } 
		Cull Front
		Blend DstColor SrcColor
		Offset -1,-1
		CGPROGRAM
		#pragma vertex vert 
		#pragma fragment frag
		#include "UnityCG.cginc"
		float4x4 _World2Ground;
		float4x4 _Ground2World;
		float _Intensity;
		struct v2f{
			float4 pos:SV_POSITION;
			float atten:TEXCOORD0;
		};
		v2f vert(float4 vertex: POSITION)
		{
		v2f o;
		float3 litDir;
			litDir=normalize(WorldSpaceLightDir(vertex));  
			litDir=mul(_World2Ground,float4(litDir,0)).xyz;
		float4 vt;
			vt= mul(_Object2World, vertex);
			vt=mul(_World2Ground,vt);
		vt.xz=vt.xz-(vt.y/litDir.y)*litDir.xz;
		vt.y=0;
		vt=mul(_Ground2World,vt);//back to world
		vt=mul(_World2Object,vt);
		o.pos=mul(UNITY_MATRIX_MVP, vt);
		o.atten=distance(vertex,vt)/_Intensity;
		return o;
		}
 		float4 frag(v2f i) : COLOR 
		{
			return smoothstep(0,1,i.atten/2);
		}
 		ENDCG 
		}//
		pass {   
		Tags { "LightMode" = "ForwardAdd" } 
		Cull Front
		Blend DstColor SrcColor
		Offset -2,-1
		CGPROGRAM
		#pragma vertex vert 
		#pragma fragment frag
		#include "UnityCG.cginc"
		float4x4 _World2Ground;
		float4x4 _Ground2World;
		float _Intensity;
		struct v2f{
			float4 pos:SV_POSITION;
			float atten:TEXCOORD0;
		};
		v2f vert(float4 vertex:POSITION)
		{
		v2f o;
		float3 litDir;
			litDir=normalize(WorldSpaceLightDir(vertex)); 
			litDir=mul(_World2Ground,float4(litDir,0)).xyz;
		float4 vt;
			vt= mul(_Object2World, vertex);
			vt=mul(_World2Ground,vt);
		vt.xz=vt.xz-(vt.y/litDir.y)*litDir.xz;
		vt.y=0;
		vt=mul(_Ground2World,vt);//back to world
		vt=mul(_World2Object,vt);
		o.pos= mul(UNITY_MATRIX_MVP, vt);
		o.atten=distance(vertex,vt)/_Intensity;
		return o;
		}
 		float4 frag(v2f i) : COLOR 
		{
			return smoothstep(0,1,i.atten*i.atten);
		}
 		ENDCG 
		}
   }
}

 9.3.2潜在的问题 

        这个方法还有一个显而易见的问题,那就是物体本身是立体的,不是一个平面,因此这个计算前后的点的距离是包括物体本身厚度的,这个厚度就会表现在阴影上。要解决这个问题,我们可以先把物体变换到灯光空间,使用_World2Light矩阵沿着灯光方向把物体压扁,然后投射物体,这样计算出来的阴影衰减就不会包括物体的厚度了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值