ShaderForge-水中倒影效果
发表于2018-07-11
效果


原理
- 将原图均分为月亮部分和水面部分两张图,其他区域用透明色填充
- 倒影:就是将uv的v值翻转一下,
- 倒影在水的扭曲效果:就是让图片不同部位uv值的增量不同,如果不太熟悉扭曲效果的,可以参见unity shader 贴图流动
- 最后利用透明度用Lerp操作将原图和倒影图合成到一起
ShaderForege实现
分解
- 倒影
uv值是从(0,0)到(1,1)的二位数组,我们将v值从0到1重映射到1到0,就得到了y方向上的倒影图

font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
- 将水波图与倒影图混合

- 流动效果

- 透过透明度与月亮图混合

到这里已经基本上实现了水中倒影的效果!
我在以上基础上根据自己的喜好追加了一些细节,开篇的效果的shaderforge节点树如下

手写unity shader实现水中倒影
Shader "Custom/daoying_u"
{
Properties
{
_MainTex ("Shadow Tex", 2D) = "white" {}
_WaterTex("Water Tex", 2D) = "white" {}
_NoiseTex("Noise Tex", 2D) = "white" {}
_MoonTex("Moon Tex", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _WaterTex;
sampler2D _NoiseTex;
sampler2D _MoonTex;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// 流动值
fixed4 noise_col = tex2D(_NoiseTex, i.uv + float2(_Time.y*0.1, 0.0));
fixed2 floatUV = float2(noise_col.r*0.03, 0);
// uv的v值从0到1重映射到1到0
float2 shadow_uv = float2(i.uv.r+floatUV.r, (i.uv.g+floatUV.g)*-1.0 + 1.0);
fixed4 col = tex2D(_MainTex, shadow_uv);
fixed4 water_col = tex2D(_WaterTex, i.uv+floatUV);
// 混合倒影和水波
fixed4 lerp1 = lerp(col, water_col, 0.5);
fixed4 moon_col = tex2D(_MoonTex, i.uv);
// 混合月亮图和倒影
fixed4 final = lerp(moon_col, lerp1, 1.0 - moon_col.a);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return final;
}
ENDCG
}
}
}

