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