Shader波动效果

自从学了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
		}
	}
}

猜你喜欢

转载自blog.csdn.net/ww1351646544/article/details/90646205