UnityShader中级篇——顶点动画的阴影效果

本文介绍了一种使用Unity Shader实现动态河流效果的方法,并通过顶点动画实现水流波动,同时介绍了如何为这种动态效果正确地渲染阴影。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 11/Vertex Animation With Shadow"
{
	Properties
	{
		//河流纹理
		_MainTex ("Main Tex", 2D) = "white" {}
	    //控制整体颜色
	    _Color ("Color Tint", Color) = (1,1,1,1)
		//控制水流波动的幅度
		_Magnitude ("Distortion Magnitude", Float) = 1
		//控制水流波动的频率
		_Frequency ("Distortion Frequency", Float) = 1
		//控制波长的倒数,倒数越大,波长越小
		_InvWaveLength ("Distortion Inverse Wave Length", Float) = 10
		//河流纹理的移动速度
		_Speed ("Speed",Float) = 0.5
	}
	SubShader
	{
		//由于序列帧图像通常是透明背景,所以需要设置pass的相关状态,以渲染透明效果
		//半透明“标配”,DisableBatching指明是否对该SubShader使用批处理,批处理会合并所有相关模型,模型各自的模型空间就会丢失
		Tags{ "Queue" = "Transparent" "IgnoreProject" = "True" "RenderType" = "Transparent" "DisableBatching" = "True"}

		//此Pass用于顶点动画
		Pass
		{
			Tags{ "LightMode" = "ForwardBase" }
			//为了让水流的每个面都能显示
			//关闭深度写入
			ZWrite off
			//开启并设置混合模式
			Blend SrcAlpha OneMinusSrcAlpha
			//关闭剔除功能
			Cull Off


			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			
			#include "UnityCG.cginc"

			sampler2D _MainTex;
		    float4 _MainTex_ST;
			float4 _Color;
			float _Magnitude;
			float _Frequency;
			float _InvWaveLength;
			float _Speed;

			struct a2v
	    	{
			   float4 vertex : POSITION;
			   float4 texcoord : TEXCOORD0;
	    	};

	      	struct v2f
	    	{
			   float4 pos : SV_POSITION;
			   float2 uv : TEXCOORD0;
		    };

			
			
			v2f vert (a2v v)
			{
				v2f o;
				float4 offset;
				offset.yzw = float3(0.0, 0.0, 0.0);
				//_Frequency*_Time.y控制正弦函数频率
				//加上模型空间下的分量乘以_InvWaveLength位置控制不同位置具有不同的位移
				//乘以_Magnitude控制波动幅度
				offset.x = sin(_Frequency * _Time.y + v.vertex.x * _InvWaveLength + v.vertex.y * _InvWaveLength + v.vertex.z * _InvWaveLength) * _Magnitude;
				//把位移量添加到顶点位置上
				o.pos = UnityObjectToClipPos(v.vertex + offset);
				//进行纹理动画,使用_Time.y和_Speed控制水平方向上的位移
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
				o.uv += float2(0.0, _Time.y * _Speed);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				//对纹理进行简单采样
				fixed4 c = tex2D(_MainTex, i.uv);
				// 添加颜色控制
			    c.rgb *= _Color.rgb;
				return c;
			}
				ENDCG
	    }

		    //此Pass用于渲染动画的阴影
			Pass
		{
			//绘制阴影都需要调用ShadowCaster
			Tags { "LightMode"="ShadowCaster" }

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_comlile_shadowCaster

			#include "UnityCG.cginc"

			float _Magnitude;
			float _Frequency;
			float _InvWaveLength;
			float _Speed;

			struct a2v {
				//使用TRANSFER_SHADOW_CASTER_NORMALOFFSET必须包含v.vertex和v.normal
				float4 vertex : POSITION;
				float4 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
			};

			struct v2f {
				//定义阴影投射需要的变量
				V2F_SHADOW_CASTER;
			};

			v2f vert(a2v v) {
				v2f o;
				//按顶点动画Pass中的处理方法计算顶点偏移值
				float4 offset;
				offset.yzw = float3(0, 0, 0);
				offset.x = sin(_Frequency * _Time.y + v.vertex.x * _InvWaveLength + v.vertex.y * _InvWaveLength + v.vertex.z * _InvWaveLength) * _Magnitude;
				//直接把偏移值加到顶点位置变量中
				v.vertex = v.vertex + offset;
				//使用宏完成阴影偏移
				TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target{
				//使用宏完成阴影投射
				SHADOW_CASTER_FRAGMENT(i);
			}
			ENDCG
	     }
	}
			Fallback"VertexLit"
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值