![56ccc91853d98463bccfe31a11fa9fc3.png](https://i-blog.csdnimg.cn/blog_migrate/a36a509130492112ba517fa2c83af04d.jpeg)
本文作者为雷火内资深的引擎开发工程师 @GoldenGoat
欢迎大家在评论区提问和我们互动哦!
-------------------------------------------------------------------
无论是“清风徐来,水波不兴”的平静澄澈,还是“满川风雨看潮生”的波澜壮阔,水在游戏中总能起到至关重要的作用。想要让游戏中的阴晴变幻如真实生活般细致微妙,优秀的水渲染不可或缺。反之,则会让原本身临其境的玩家一秒出戏。
目前市面上的游戏制作水面的技术流程已经很成熟了,也提供了各种水面的解决方案,在此就不再花篇幅讲解。这篇文章将分享雷火事业群某单机项目在渲染水面和水面互动上的技术细节和一些实用的小技巧,希望大家都能有所收获和启发。
本文涉及的要点如下:
1. 水面渲染
1) 水体基础颜色混合
2) 法线
3) 折射
4) 焦散
5) 水体明暗
6) 反射
7) 高光
8) 点光源
2. 水面互动
1) 水波纹的生成
a. 扩散方程
b. 配置和流程
c. 白浪和泡沫的生成
2) 触发器的制作
a. 正确触发水波纹
b. 正确播放特效
水面渲染
先来看一下整体效果
![0828cd66bc768601c797d60d3f177456.png](https://i-blog.csdnimg.cn/blog_migrate/e7d9e929f4b095b9d4e39302bc06e025.png)
水体基础颜色混合
第一步就是绘制水体颜色,水体基础颜色由以下几个参数决定
l 屏幕深度
l 浅水颜色
l 深水颜色
l 过渡深度
l 过渡系数
通过获取当前摄像机的深度图,再用配置好的深水浅水颜色,然后加上过度深度参数和过度系数以控制深水浅水颜色的融合,最终画出水体基础颜色。
用到的公式很简单
深度系数= pow( saturate ( 屏幕深度/ 过渡深度), 过渡系数)
水体基础颜色= lerp( 浅水颜色, 深水颜色, 深度系数)
大致效果流程如图所示:
![079a9cd657d7049ecf02f5e99f275adb.png](https://i-blog.csdnimg.cn/blog_migrate/5763d1bc7e66d2ff2b18eb7dc56ac9ef.jpeg)
![829440bcb12989645104d8f3a739f261.png](https://i-blog.csdnimg.cn/blog_migrate/520601c7bf4f8fd17d07c09826982a12.jpeg)
![f44d4d7e2d718ce64a260a8d1ca370ba.png](https://i-blog.csdnimg.cn/blog_migrate/35b55fce1b29e832257e100b800f0ea4.jpeg)
法线
第二步就是生成水面法线,法线是整个水面效果最重要的一部分,因为接下来的各种表现都会与法线效果相关。
我们尝试了两种方式来获取水面法线,其中一种就是现在常用的解决方案,使用fft来生成水面高度图,然后来获取水面法线。
效果如下所示:
![e77eb319017bac86a871a59103606795.png](https://i-blog.csdnimg.cn/blog_migrate/7607c03acebee5e558a167ab1cb1073b.jpeg)
Fft海洋+曲面细分+反射+高光+白浪
另外一种是通过变化tiling、偏移和强度来多次采样一张法线贴图进行叠加,同时加上视差效果和风力对水面的影响来获取最终的水面法线。
知乎上面已经有较多介绍生成fft的文章了,这里就着重介绍第二种方法。
大致要素有:
l 法线贴图
l 叠加
l 视差
l 风力影响
首先是在shader里面获取到水面顶点的世界坐标再按一定的缩放比例,然后转换成采样的uv坐标并对法线贴图进行采样。注意,法线贴图的分辨率可以大一些,这里使用的法线贴图分辨率为2048*2048。
![e562063ccd2e2d3e0687b3e02b11db5c.png](https://i-blog.csdnimg.cn/blog_migrate/1093bcbf01f6541ea108fbd47ba8942a.jpeg)
这是进行叠加之后的效果:
![0872f7ce7f604e23aa6876fae86d0aef.png](https://i-blog.csdnimg.cn/blog_migrate/df16896c234bd1ae8986c5e221c68bd6.jpeg)
添加上视差效果(也可以通过曲面细分,然后通过位移顶点位置来达到类似的效果)可以使水面更加立体。简单来说,视差效果就是让现实生活中应该看不到的地方在游戏里也看不到,尤其是在原本mesh就是平面的情况下,这会让表现效果更立体更真实。视差效果的技术细节就不赘述了,这里用到的就是浮雕视察映射,效果如下所示:
![4ad1cf4eba23900574224019b9459ed6.png](https://i-blog.csdnimg.cn/blog_migrate/8971826c76d20959096780abd9287105.jpeg)
最后添加风力对水面的影响,风力的做法目前也是通过采样法线贴图(不同的tiling和位移),然后通过一张noise贴图(或者算法生成)来进行强弱控制。最后叠加的效果如下所示: