Shader波动效果

本文围绕Shader展开,作者学习Shader后常思考效果实现方式。介绍了用Shader实现简单波动效果,通过让UV值随时间变化,用Sin运算使取值点在原位置周边移动做出平等水波效果。还讲解了环形波动效果,用distance算UV点与中心点距离,结合时间增量做Sin运算实现。

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

自从学了Shader以后,看到什么效果都会在脑海里,偷偷的想着这个效果用Shader怎么实现呢?哈哈真是服了自己…

为什么写了那么多各种复杂的内容又跑回来写这些基础的内容呢?

我发现Shader的是一个很神奇的东西,差一个数值,数值的大小效果的千变万化的,很多有趣的效果的实现并不需要太多的代码量…比如下面这个。

说下一个很简单实现的波动效果吧,先上图。
在这里插入图片描述

原图:
在这里插入图片描述
在这里插入图片描述
先说最右边的图那的,先是把图片辅好:
顶点着色器代码,这个应该没什么好讲了:

v2f vert(a2v v){
	v2f o;
	o.pos_VS = UnityObjectToClipPos(v.pos);
	o.uv=TRANSFORM_TEX(v.uv,_MainTex);
	return o;
}

然后是让UV值随着时间的变化而变化,重点是使用了Sin这样能使值徘徊在-1~1之间。
用自身位置与时间增量做Sin运算,这样其实就是让取值的点在原来点周边做来回移动。
从而做出平等水波的效果,下面是片元着色器的代码:

float4 frag(v2f o):SV_TARGET{
	float2 uv = o.uv;
	o.uv.x+= 0.01*sin(uv.x*3.14*_Scale+_Time.y);
	o.uv.y+= 0.01*sin(uv.y*3.14*_Scale+_Time.y);
	fixed4 color = tex2D(_MainTex,o.uv);
	return color;
}

但上面效果只是左右的位移显然不够逼真,我们要以试试下面的效果:
在这里插入图片描述
环形的波动,这个是怎么做的呢?
这里写死了0.5,0.5为UV的中心点运行波动偏移,先是用一个distance算出该UV点与中心点的距离,然后用这个距离与时间增量的和做Sin运算,再把值加给UV,即可以得到如图效果。
顶点着色器代码和上面一样,下面是片元着色器代码:

float4 frag(v2f o):SV_TARGET{
	float2 uv = o.uv;
	float dic = distance(uv,float2(0.5,0.5));
	o.uv.x+= 0.01*sin(dic*3.14*_Scale+_Time.y);
	o.uv.y+= 0.01*sin(dic*3.14*_Scale+_Time.y);

	fixed4 color = tex2D(_MainTex,o.uv);
	return color;
}

下面是两个Shader完整代码:

Shader "Custom/Material1" {
	Properties {
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_Scale("Scale",Range(0,50))=1
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		Pass{
			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				#include "Lighting.cginc"

				sampler2D _MainTex;
				float4 _MainTex_ST;
				float _Scale;

				struct a2v{
					float4 pos:POSITION;
					float4 uv:TEXCOORD0;
				};

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

				v2f vert(a2v v){
					v2f o;
					o.pos_VS = UnityObjectToClipPos(v.pos);
					o.uv=TRANSFORM_TEX(v.uv,_MainTex);
					return o;
				}

				float4 frag(v2f o):SV_TARGET{
					float2 uv = o.uv;
					o.uv.x+= 0.01*sin(uv.x*3.14*_Scale+_Time.y);
					o.uv.y+= 0.01*sin(uv.y*3.14*_Scale+_Time.y);
					fixed4 color = tex2D(_MainTex,o.uv);
					return color;
				}
			ENDCG
		}
	}
}

Shader "Custom/Material2" {
	Properties {
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_Scale("Scale",Range(0,50))=1
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		Pass{
			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				#include "Lighting.cginc"

				sampler2D _MainTex;
				float4 _MainTex_ST;
				float _Scale;

				struct a2v{
					float4 pos:POSITION;
					float4 uv:TEXCOORD0;
				};

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

				v2f vert(a2v v){
					v2f o;
					o.pos_VS = UnityObjectToClipPos(v.pos);
					o.uv=TRANSFORM_TEX(v.uv,_MainTex);
					return o;
				}

				float4 frag(v2f o):SV_TARGET{
					float2 uv = o.uv;
					float dic = distance(uv,float2(0.5,0.5));
					o.uv.x+= 0.01*sin(dic*3.14*_Scale+_Time.y);
					o.uv.y+= 0.01*sin(dic*3.14*_Scale+_Time.y);

					fixed4 color = tex2D(_MainTex,o.uv);
					return color;
				}
			ENDCG
		}
	}
}

### Unity Shader 实现波动效果 在Unity中实现波动效果可以通过编写自定义Shader来完成。下面提供一段基于表面着色器(Surface Shader)的代码示例,该示例展示了如何利用正弦函数`sin()`创造简单的浪形变形效果。 ```c Shader "Custom/WaveEffect" { Properties { _MainTex ("Texture", 2D) = "white" {} _WaveStrength ("Wave Strength", Range(0,1)) = 0.5 _Speed ("Animation Speed", Float) = 1.0 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert vertex:vert addshadow sampler2D _MainTex; float _WaveStrength; float _Speed; struct Input { float2 uv_MainTex; }; void vert(inout appdata_full v) { float time = _Time.y * _Speed; float waveOffset = sin(v.vertex.x + time) * cos(v.vertex.z + time); v.vertex.y += waveOffset * _WaveStrength; } void surf (Input IN, inout SurfaceOutput o) { fixed4 col = tex2D(_MainTex, IN.uv_MainTex); o.Albedo = col.rgb; o.Alpha = col.a; } ENDCG } FallBack "Diffuse" } ``` 这段代码中的关键部分在于顶点着色器(`vert`)里对顶点坐标的修改[^3]。通过引入时间变量 `_Time.y` 和速度参数 `_Speed` 来改变 `waveOffset` 的值,进而影响模型的高度 (`vertex.y`) ,从而形成随时间变化而起伏的效果[^4]。 为了使此Shader更易于理解和应用,建议熟悉以下几个概念: - **Properties**: 定义了可以由用户调整的属性,如纹理、强度和速度等。 - **SubShader**: 描述渲染管线的具体细节,包括标签(Tags),LOD级别(Level of Detail),以及使用的编程语言(Cg/HLSL)。 - **CGPROGRAM/ENDCG**: 包含实际执行图形处理逻辑的地方;这里指定了使用的是表面着色器(surf)并允许添加阴影(addshadow)。 - **Vertex Function (vert)**: 对网格数据进行预处理的位置,在这里是用来计算每个顶点的新位置以模拟水波荡漾的感觉。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小盖子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值