最近在开资料的时候发现了unityshader中一些扰动图的使用很有趣,这里做个记录,这篇文章主要涉及到两个小案例:
- 扰动火焰
- 闪烁灯光
扰动火焰
原理就是通过采样一张扰动图的RG通道,作为UV与MainTex的贴图相加进行偏移,然后通过改变扰动图的offset进行模拟扰动效果,大概效果如下。
关键代码
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.noise_uv = TRANSFORM_TEX(v.uv, _NoiseTex);
o.noise_uv.y -= _Time.x;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 noiseCol = tex2D(_NoiseTex, i.noise_uv);
half2 noiseuv = {noiseCol.r,noiseCol.g};
//颜色值是(0,1),而扰动需要(-1,1)
noiseuv = (noiseuv-0.5)*2;
fixed4 col = tex2D(_MainTex, i.uv + noiseuv*0.02);
return col;
}
闪烁灯光
原理跟火焰的而类似,通过一张扰动图把扰动信息存在RG通道中,与火焰不同的事,火焰干扰的事uv,这个干扰的是颜色。
首先扰动图采样的UV直接用_SinTime函数进行计算,采样完的颜色与MainTex Color进行计算。还可以进行各通道的计算。模拟的效果如下:
关键代码:
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
float sinTan = _SinTime * 20;
o.noise_uv = float2(sinTan,sinTan);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 noiseCol = tex2D(_NoiseTex, i.noise_uv);
fixed4 col = tex2D(_MainTex, i.uv);
float4 ghjcolor = col.g * saturate(noiseCol.r + _Luminance)*_Color1;
float4 ghjcolor1 = col.r * noiseCol.g*_Color2;
float4 main = col.b * _Color3;
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return ghjcolor + ghjcolor1 + main;
}
这个算法也是来自某插件,实际效果如下:
场景中实际没灯
网友评论