GPU Gems1 - 1 用物理模型进行高效的水模拟(Effective Water Simulation from Physical Models)

该读书笔记大多内容参照了大神浅墨的该篇文章https://zhuanlan.zhihu.com/p/35974789

本章介绍了一种在GPU中模拟和渲染大的水体的系统。它把基本网格的集合波动于动态发现贴图的生成结合起来。

1.1 目标和范围

这章里,我们将由计算简单正弦函数之和开始,逐步扩展到更复杂的函数如Gerstner波,也扩展到像素着色器。主要思路是使用周期波的加和,来创建动态的平铺(tiling)凹凸贴图,从而获得优质的水面细节。

1.2 正弦近似值的加和

1.2.1 波的选择

我们需要运行两个表面模拟:一个是表面网格的几何波动,另一个是网格上法线图的扰动。两个模拟本质上是相同的。水面高度由简单的周期波叠加表示,正弦函数叠加后得到了一个连续函数,这个函数描述了水面上所有点的高度和方向。在处理顶点时,我们基于每个顶点的水平位置对函数取样,使得网格细分成连续水面。在几何分辨率下,通过对近似正弦叠加的法线取样,别通过shader渲染到render target texture,就得到了表面的法线贴图。

水纹理的波纹好坏决定着模拟的逼真度,对纹理波纹我们有不同的几何选择标准:

  • 波长Wavelength (L):世界空间中波峰到波峰之间的距离。波长L与角频率ω的关系为
    ω=2π/L。
  • 振幅Amplitude (A):从水平面到波峰的高度。
  • 速度Speed (S):每秒种波峰移动的距离。为了方便,把速度表示成相位常数 φ=S x
    2π/L。
  • 方向Direction (D):垂直于波峰沿波前进方向的水平矢量。

1.2.2 法线与切线

因为我们的表面有定义明确的函数,所以可以直接计算任意给定点处的曲面方向,而不是依赖于有限差分技术。

副法线(Binormal)B和正切矢量T分别是x和y方向上的偏导数。
对于2D水平面中的任意点(x,y),表面上的三维位置P为:

 

求副法线(Binormal)B方向,即对上式对x方向求偏导。而求正切矢量T方向,即对上式对y方向求偏导。

而法线N由副法线B和切线T的叉积给出:

1.3 波的几何特征

首先文中将几何波限制为4个,因为添加更多的波并不能增加新的概念,只不过增加更多相同的顶点Shader处理指令和常数而已。

1.3.1 方向波或圆形波的选择

需要对下图所示的方向波或圆形波进行选择。

                                                                                        图 方向波和圆形波

 

对于两种类型的波,视觉特性和复杂性都是由干涉条纹引起的。

方向波需要的顶点shader处理指令较少,但是究竟选择何种波需要取决于模拟的场景。对于大的水体,方向波往往更好,因为它们是风吹动产生的波较好的模型。对于较小的池塘的水,产生波的原因不是由于风,而是诸如例如瀑布,水中的鱼,圆形波则更好一些。对于方向波,波的方向是在风向的一定范围内任意绘制的;对于圆形波,波中心是在某些限定的范围内任意绘制的。

1.3.2 Gerstner波

正弦波看起来圆滑,用于渲染平静的,田园诗般的池塘很合适。而对于粗犷的海洋,需要形成较尖的浪头和较宽的浪槽,则可以选择Gerstner波。

Gerstner波早在计算机图形学出现之前就已经被研发了出来,用于物理学基础上为海水建模。Gerstner波可以提供一些表面的微妙运动,虽然不是很明显但是却很可信(具体可见[Tessendorf 2001])。

另外,Gerstner波有一种经常被忽略的性质:它将顶点朝着每个浪头顶部移动,从而形成更尖锐的波峰。因为波峰是我们水表面上最锐利的(即最高频率,最主要)特征,所以我们正希望顶点可以集中在此处。

                                                                                      图 Gerstner波

 

1.3.3 波长等参数的选择

 

波长等参数的选择方法:

  • 波长的选择,要点是不要追求波在真实世界中的分布,而是要使用现在的少数几个波达到最大效果。对波长相似的波进行叠加可以突显水面的活力。于是文中选择中等的波长,然后从它的1/2至两倍之间产生任意波长。
  • 波的速度,通过波长,基于公式即可计算得出。
  • 振幅方面,主要是在Shader中指定一个系数,由美术同学对波长指定对应的合适振幅。
  • 波的方向,运动方向与其他参数完全独立,因此可以自由选择。

 

1.4 波的纹理特征

加和到纹理中的波也像上文说到的顶点一样需要参数化,但是其具有不同的约束条件。首先,在纹理中得到宽频谱更为重要。其次,在纹理中更容易形成不像天然波纹的图案。第三,对给定波长只有某些波方向能保证全部纹理的平铺(tiling)。也就是说,不像在世界空间中仅仅需要注意距离,在纹素(texel)中要注意所有的量。

文中的思路是在2到4个通道中,使用15个频率和方位不同的波进行处理。虽然4个通道听起来有点多,但是它们是进行256 x 256分辨率的渲染目标纹理的处理,而不是处理主帧的帧缓冲。实际上,生成法线贴图的填充率所造成的影响小到可以忽略不计。

 

1.5 关于深度

首先,把在顶点上的水深度作为一个输入参数,这样,在着色器碰到岸边这样的微妙区域时,便可以自动进行校正。

因为水的高度需要计算,所以顶点位置的z分量就没什么用了。虽然我们可以利用这点来压缩顶点的数据量,但是选择把水深度编码在z分量中,是一个更好的选择。

更确切地说,就是把水体底部的高度放在顶点的z分量中,作为常数带入水的高度表中,这样通过相减,即可得到水深度。而同样,这里假定了一个恒定高度的水位表(constant-height
water table)。

我们也使用水深度来控制水的不透明度、反射强度和几何波振幅。简单来说,即水浅的地方颜色浅,水深的地方颜色深。有了适当的水深度,也就可以去光的传播效果进行更完善的建模。

 

【核心要点总结】

文中提出的水体渲染方法,总结起来有三个要点:

1)使用周期波(正弦波、Gerstner波)的加和

2)创建动态的平铺(tiling)贴图

3)使用凹凸环境映射(Bump-Environment Mapping)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值