UnityShader·水面

静水效果主要由波纹,折射和边缘效果这三个部分组成。

动态波纹

使用vertex displacement营造水面的波浪浮动。可控波浪幅度、高度和速度。

CPU保留原始顶点数据,但是在将这些数据传向GPU前对顶点数据进行修改——这个技巧被称为Vertex Displacement。常用于制造水面、地形、爆炸和扭曲效果。简单来说就是在shaderlab的vertex function通过数学公式或者位移贴图修改顶点位置。

v2f vert(appdata v)
{
	v2f o;
	v.vertex.y += sin(_Time.z * _Speed + (v.vertex.x * v.vertex.z * _Amount)) * _Height; //用sin函数制造波浪
	o.vertex = UnityObjectToClipPos(v.vertex);
	return o;
}

这一步的完整代码戳这里

水的透明度

Blend的默认状态是Blend Off,不设置Blend参数只会显示非透明颜色。修改Blend参数使贴图透明看起来更像水,注意水体的颜色透明度不能为1

Blend SrcAlpha OneMinusSrcAlpha

边缘浮沫

接下来添加接触物边缘效果。因为阳光照射的原因,深处的水颜色会较深,而近处的水颜色则较浅。如果有物体浸入水中,则物体边缘处的水颜色较浅,甚至会积累白色浮沫。

这里需要用到深度值(Depth)计算。根据“深度”计算水应呈现的颜色。

Camera可以生成深度贴图(depth texture),深度贴图是一张G-Buffer贴图,储存了每个像素的深度值,常用于后期效果和自定义光照制作。这里需要介绍几个内置变量/方法:

Pass
{
  //...
  sampler2D _CameraDepthTexture;//unity内置变量,无需在Properties中声明
  //...
  fixed4 frag(v2f i) : SV_Target
  {
      float4 depthSample = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, (i.screenPos));
	    float depth = LinearEyeDepth(depthSample);
	    float foamLine = 1 - saturate(_FoamThickness * (depth - i.screenPos.w));
	    half4 col = _Tint + foamLine * _EdgeColor * 0.5;
	    return col;
  }
}

注意:要打开灯光的shadow效果,否则无法获取depth值。

这一步的完整代码戳这里

添加折射

水下物体因为折射和水面波动会呈现出扭曲的效果。这里使用GrabPass和一张扭曲贴图来制造这种折射效果。

GrabPass是一个特殊的pass类型,它可以抓取屏幕上显示的内容然后将这个对象绘制到一个纹理中。在这里可以抓取物体成纹理,然后对其扭曲处理形成水下折射的图像。

GrabPass{}
//...
v2f vert(appdata v)
{
  //...
  o.grabtex = ComputeGrabScreenPos(o.vertex);		
  return o;
}

fixed4 frag(v2f i) : SV_Target
{   
  float2 dism = UnpackNormal(tex2D(_DistortionMap, i.dismap + (_Time.x * 0.2)));
	float2 offset = dism * (_DistortionFactor * 10) * _GrabTexture_TexelSize.xy;
	i.grabtex.xy = offset+ i.grabtex.xy;;
	float4 dis = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.grabtex)) * _EdgeColor;
  //...
}

添加distortion贴图后的效果:

这里用到的noise贴图:

加上贴图

最后一步加上一张贴图,可以营造各种风格的水面。

这里例子用的贴图↓

这一步的完整代码戳这里

其他

ps1:非常偶然地试了一张毫无关联的图,乘了一个没什么道理的参数,画面却意外还不错(感觉比水酷炫多了啊喂…戳这里

ps2:颜色调成非透明白色可以获得blingbling的发光片…戳这里

参考

  1. Unity3D中的深度纹理和法线纹理

  2. Foam Line using Depth

  3. Unity Stylized Water