【Unity Shader实例】水体WaterEffect(一) 设计
发表于2018-07-15
本篇文章主要给大家介绍如何通过shader设计水体效果,在介绍之前,我们先参考一下大神们写好的精彩的例子,比如DCG Water Shader的效果,这也是我们努力的目标。
好!~ 现在开始实现自己的水体shader!
环境
项目:水体拟真Shader
引擎:Unity3D
编程语言:Unity Shader(ShaderLab + CG language)
概述
想要模拟水体效果,首先要了解水体的特性,并理解这些特性背后的物理原理,然后通过程序对这些物体挺行进行模拟。
水的特性
首先,简单了解一下我们要模拟的水的特性:
- 水在常温常压下为无色无味的透明液体(颜色)
- 平静的水面犹如镜面能映照周围的环境(光的反射)。
- 水是透明物体,我们可以透过水看到水中的物体(光的投射)。
- 如果水面非常广阔,你站在水边,低头看脚下的水,你会发现水是透明的,反射不是特别强烈;如果你看远处的湖面,你会发现水并不是透明的,反射非常强烈(菲涅尔效应)。
- 水面不是静止的,会受到风力等外力影响发生波动(水的波动)。
- 水面是动态的,可以看成很多小镜子,光照在上面,除少许穿透形成折射外,多数都返回空气中,人看起来会有波光粼粼、一闪一闪的感觉。
- 当水冲刷水中物体时,会在交界处产生细碎的泡沫。
- 太阳光中波长较短的蓝光、紫光穿透能力弱,遇到纯净海水时,最易被散射和反射。又由于人们眼睛对紫光很不敏感,往往视而不见,而对蓝光比较敏感。于是,我们所见到的海洋就呈现出一片蔚蓝色或深蓝色了。
- 阳光可以穿透的海水深度有限,水深的地方黑暗,水浅的地方可见性高。
设计实现方案
我们做对水体效果的模拟,随着拟真效果的提高,shader程序也变得越来越复杂,性能消耗也越来越大。因此可以根据设备不同的性能,设计相应的水体效果实现方案,从而实现理想中的水体效果。
一、简单水体shader(Fake Water shader)
用贴图和uv动画模拟水效实现”假”水。
设计
找一张水波的贴图,处理它的uv值,让贴图流动起来。这样就用静态纹理和uv动画模拟出了动态水流动的效果。
实现要点
贴图流动
贴图流动的实质就是uv偏移,图片各个部分的偏移程度有区别就实现了扭曲效果。让偏移程度与时间相关,就会有种贴图随着时间发生流动的感觉。 更多关于贴图流动的实现和原理看这里:贴图流动。
效果展示
为什么说这是Fake Water呢?
因为它的效果非常假,很容易有穿帮的感觉,只适用于对真实度要求不高的场景,比如2D游戏场景中的广场装饰喷泉。
我们只是通过贴图和uv动画实现水波贴图流动的效果,我们既没有对水的模型处理使她动态波动,也没有对折射和反射效果做处理。好处是,这种shader性能消耗非常低。
二、真实感的水体shader
设计
为了让水体效果更具真实感,我们要尽可能多的模拟出水的物体特性,包括水的反射、折射、菲涅尔反射效应、水的深度对水颜色的影响、水与其他物体碰撞时产生的泡沫等等。
实现要点
- 环境映射与菲涅尔反射
- 水的折射
- 计算水与地形之间的深度距离
- 模拟水的波动
- 法线贴图模拟水面波光
- 计算物体与水面的交界范围并贴上泡沫的贴图
实现效果
前面的shader只做了水体的水面效果,还有水下shader没有实现。
另外如果想让水体效果更加拟真,还可以添加更多水的物体特性,比如水的焦散等等。
来自:https://blog.csdn.net/v_xchen_v/article/details/79676008