8.平面阴影

public class CastShadow : MonoBehaviour {

    public Transform rec;//接受阴影的物体
                         // Use this for initialization
    void Start () {
        GetComponent<Renderer>().sharedMaterial.SetMatrix("_World2Ground", rec.GetComponent<Renderer>().worldToLocalMatrix);
        GetComponent<Renderer>().sharedMaterial.SetMatrix("_Ground2World", rec.GetComponent<Renderer>().localToWorldMatrix);
    }
    void Update()
    {
        
    }
}
这个脚本主要是为了设置需要接受阴影的地面的坐标系,如果没有这个脚本,物体产生的阴影的坐标系是原始坐标系(0,0,0)

// shader,放在需要显示阴影的对象上
Shader "Study/8_PlanarShadow" {
	Properties{
		_Instensity("Shininess", Range(2, 4)) = 2.1
	}
		SubShader{
		pass {
		Tags{ "LightMode" = "ForwardBase" }
			Material{ Diffuse(1,1,1,1) }
			Lighting On
	}
	Pass{
		Tags{ "LightMode" = "ForwardBase" }
		Blend DstColor SrcColor
		Offset -1,-1
		CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
		float4x4 _World2Ground;
	float4x4 _Ground2World;
	float _Instensity;
	struct v2f {
		float4 pos:SV_POSITION;
		float atten : TEXCOORD0;
	};
	v2f vert(float4 vertex:POSITION)
	{
		float3 litDir;
	litDir = WorldSpaceLightDir(vertex);//世界空间主光照相对于当前物体的方向
	float4 litDir_4 = float4(litDir,0);
	litDir_4 = mul(_World2Ground, litDir_4);//光源方向转换到接受阴影的平面空间
	litDir_4 = normalize(litDir_4);// 归一
	float4 vt;
	vt = mul(_Object2World,vertex); //将当前物体转换到世界空间
	vt = mul(_World2Ground,vt); // 将物体在世界空间的矩阵转换到地面空间
	vt.xz = vt.xz - (vt.y / litDir_4.y)*litDir_4.xz;// 用三角形相似计算沿光源方向投射后的XZ
	vt.y = 0;// 使阴影保持在接受平面上
	vt = mul(_Ground2World, vt); // 阴影顶点矩阵返回到世界空间
	vt = mul(_World2Object, vt); // 返回到物体的坐标
	v2f o;
	o.pos = mul(UNITY_MATRIX_MVP, vt);//输出到裁剪空间
	o.atten = distance(vertex, vt) / _Instensity;// 根据物体顶点到阴影的距离计算衰减
	return o;
	}
		float4 frag(v2f i) :COLOR
	{
		return smoothstep(0,1,i.atten / 2);
	}
		ENDCG
	}
	}
}

这个shader只是讲解下平面阴影的产生原理,核心的原理就是通过三角形相似,根据光照方向将顶点投影到地面上。

其中第一个Pass是渲染物体本体,第二个Pass渲染阴影。渲染阴影的原理是将坐标系转换成接受阴影的地面坐标系后,根据三角形相似,计算出物体顶点在x方向和z方向的投影坐标。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值