蛮牛:最近群友反馈,希望多发一些Shader的内容和其他进阶的内容,所以...

本篇将图解每个步骤,让大家都可以看懂~

效果预览

现在我们先做涟漪部分

首先Shader 需要一个 材质时间 ,Frac 函数可以让我们得到这样一条曲线

float3 emissive = Frac((_Time *_speed));



unity图片成梯形 unity图片切换特效_github unity 图片切换效果

我们先直接返回到屏幕可以看到这样的黑白渐变效果 return float4(emissive,1);



unity图片成梯形 unity图片切换特效_贴图_02

下面我们需要准备一张这样的图片(如何生成这张图片那就是在水一篇了,滑稽.jpg)

文章底部打包下载链接



unity图片成梯形 unity图片切换特效_Time_03

用刚才的那张黑白渐变图 反向后 减去这张,会得到下图的效果

float3 emissive = 1-(Frac((_Time *_speed)));
float3 _Texture_var = tex2D(_Texture,TRANSFORM_TEX(i.uv0, _Texture)).rgb;
return float4(emissive - _Texture_var,1);



unity图片成梯形 unity图片切换特效_github unity 图片切换效果_04

接着 使用距离函数 distance 来进一步计算得到圆环形状,原理如下

distance 和 0.05 比较

0.05 = 0 黑 0.05< 灰/白 0.05 > 灰/白

float3 emissive = 1-(Frac((_Time *_speed)));
float3 _Texture_var = tex2D(_Texture,TRANSFORM_TEX(i.uv0, _Texture)).rgb;
float maskColor = distance(emissive.r - _Texture_var.r,0.05);
return float4(maskColor,maskColor,maskColor,1);



unity图片成梯形 unity图片切换特效_Time_05

然后我们会得到这样一张图



unity图片成梯形 unity图片切换特效_github unity 图片切换效果_06

然后再让这张图除以 0.05

float3 emissive = 1-(Frac((_Time *_speed)));
float3 _Texture_var = tex2D(_Texture,TRANSFORM_TEX(i.uv0, _Texture)).rgb;
float maskColor = subtract(distance(emissive.r - _Texture_var.r,0.05)/0.05);
return float4(maskColor,maskColor,maskColor,1);



unity图片成梯形 unity图片切换特效_github unity 图片切换效果_07

会得到下图效果,此时基础的涟漪Mask 就有了



unity图片成梯形 unity图片切换特效_unity图片成梯形_08

通过偏移时间并对刚才过程如法炮制并偏移一点UV 将两张图Add到一起,混合的时候可以引入sin曲线 让两图图交替淡入



unity图片成梯形 unity图片切换特效_Time_09

float3 emissive = 1-(Frac((_Time *_speed)));
float3 emissive2 = 1-(Frac((_Time *_speed)+ 0.5));//偏移一点时间,让涟漪扩散时间错开float3 _Texture_var = tex2D(_Texture,TRANSFORM_TEX(i.uv0, _Texture)).rgb;
//UV 也偏移一点,让两张图错开一些float3 _Texture_var2 = tex2D(_Texture,TRANSFORM_TEX(i.uv0 + float2(0.5,0.5), _Texture)).rgb;
float maskColor = saturate(1 - distance(emissive.r - _Texture_var.r,0.05)/0.05);
float maskColor2 = saturate(1 - distance(emissive2.r - _Texture_var2.r,0.05)/0.05);
float maskSwitch = saturate(abs(sin((_Time * 0.5))));//两张图交替淡入float finalColor = lerp(maskColor , maskColor2 ,maskSwitch );
return float4(finalColor ,finalColor ,finalColor ,1);



unity图片成梯形 unity图片切换特效_github_10

涟漪现在有了,我们开始制作 墙面/玻璃 流水的效果 ,首先流水的部分肯定是垂直于地面,我们可以用世界空间位置来投影

我们使用这张图 水痕图



unity图片成梯形 unity图片切换特效_贴图_11

以世界空间xy ,zy投影后 再使用 世界空间abs(normalDir)方向 来控制投影的范围 可以得到这样的效果

struct VertexInput {
                float4 vertex : POSITION;
                float2 texcoord0 : TEXCOORD0;
                float3 normal : NORMAL;
            };
struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv0 : TEXCOORD0;
                float4 posWorld : TEXCOORD1;
                float3 normalDir : TEXCOORD2;
                float4 objectPos : TEXCOORD3;
            };
VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.uv0 = v.texcoord0;
                o.pos = UnityObjectToClipPos( v.vertex );
                o.posWorld = mul(unity_ObjectToWorld, v.vertex);
                o.normalDir = normalize(UnityObjectToWorldNormal(v.normal));
                o.objectPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
return o;
            }
 float4 frag(VertexOutput i) : COLOR {
               float2 verticalUv = float2(i.posWorld.x, i.posWorld.y) * _Tiling;
               float2 verticalUv2 = float2(i.posWorld.z, i.posWorld.y) * _Tiling;
               float4 Texture_var = tex2D(_Texture, TRANSFORM_TEX(verticalUv, _Texture) );
               float4 Texture_var2 = tex2D(_Texture, TRANSFORM_TEX(verticalUv2, _Texture) );
               float4 finalColor = lerp(Texture_var ,Texture_var2 , abs(i.normalDir.x));
return float4(finalColor);
}

unity图片成梯形 unity图片切换特效_Time_12

这时我们移动球,贴图是在世界方向固定的



unity图片成梯形 unity图片切换特效_github unity 图片切换效果_13

如果想跟随球体只需要 物体坐标 减去 世界坐标 即可

float2 verticalUv = float2(i.objectPos.x - i.posWorld.x, i.objectPos.y - i.posWorld.y) * _Intensity;
                float2 verticalUv2 = float2(i.objectPos.z - i.posWorld.z, i.objectPos.y - i.posWorld.y) * _Intensity;



unity图片成梯形 unity图片切换特效_github unity 图片切换效果_14

我们这时需要再增加一张Mask贴图



unity图片成梯形 unity图片切换特效_github unity 图片切换效果_15

然后乘以刚才的水痕图 并控制UV 移动得到这样的流动效果



unity图片成梯形 unity图片切换特效_贴图_16

最后再用 i.normalDir.y 来区分顶面和侧面



unity图片成梯形 unity图片切换特效_unity图片成梯形_17

unity图片成梯形 unity图片切换特效_贴图_18

接下来你可以把这个黑白图 当成高光,转换为法线,增亮Diffuse 等等,

如果你用的是一些光照模型,例如PBR 只需要传入相应的通道就可以了

关于法线还有一些特殊的地方 由于是世界空间投影所以 在背面UV会是反向的,对于Diffuse来说 重复的纹理反向的也没什么问题,但对于法线来说给人的凹凸感就是反的 ,所以需要特殊处理一下 ,两个投影面xy ,zy分别是

if(i.normalDir.z < 0)
{
return UV;
}
else
{
float x = UV.x;
    x = -x + 1;
return float2(x, UV.y);
}

if(i.normalDir.x > 0)
{
return UV;
}
else
{
float x = UV.x;
    x = -x + 1;

return float2(x, UV.y);
}



unity图片成梯形 unity图片切换特效_Time_19

我们增加上法线后的效果 ,现在根题图效果只差 后处理,粒子系统 了

https://github.com/Unity-Technologies/PostProcessing

使用到的后处理有:

  • 屏幕空间反射
  • 屏幕空间AO
  • 景深
  • Color Grading(ACES )
  • Bloom
  • 粒子系统 :略

贴图打包下载:

链接: pan.baidu.com/s/1jyD5yE 提取码: hmjg

参考:

Rainy Surface Shader Part 1: Ripples

https://deepspacebanana.github.io/deepspacebanana.github.io/blog/shader/art/unreal%20engine/Rainy-Surface-Shader-Part-1

来源知乎作者:面向搜索引擎编程