GPU_GEMS_自然态_物理模型水模拟


前言

休息了一天开始啃GPU这块硬骨头了。
开学后马上大三了,感觉时间好紧。
因为大一大二的时候有些基础必备知识没有学,没有信心去面对这一块的内容。
大三也只有一年啊,不知道能啃到什么程度,能学到什么样子。
得加油!!!
在学习完后,我希望我可以复刻一遍,用现代引擎。
好了好了进入正题吧!


一、基本介绍

This chapter describes a system for simulating and rendering large bodies of water on the GPU. The system combines geometric undulations of a base mesh with generation of a dynamic normal map.

这一章是为了仿真渲染大型的水系统,它把网格体的几何起伏和生成动态法线贴图结合到一起。

在GPU上运行的简单水模拟模型在不断发展,2002年时,有人提出了在顶点着色器中对四个正弦波求和以计算表面高度和方向,还有人提出了用三个 Gerstner 波计算表面高度。

本章重点介绍系统参数的物理意义,表明用正弦波之和逼近水面并不像通常提出的那么特别。特别注意将我们从底层模型带到实际实现的数学运算;数学是扩展实现的关键。

二、用波模拟表面

我们运行两种表面模拟:一种用于表面网格的几何波动模拟,另一种用于该网格上法线贴图中的波纹模拟。两种模拟基本相同。水面的高度由简单周期性波的总和表示(大学物理内容:从源发出的波假设在没有阻力的情况下会不断叠加,由此得出在某一点的高度)。

几何波动模拟: 正弦之和给出了描述所有点的水的高度和表面方向的连续函数。在处理顶点时,我们根据每个顶点的水平位置对该函数进行采样,使网格符合其镶嵌到连续水面的限制。

法线贴图中的波纹模拟:我们通过在渲染到渲染目标纹理时通过简单的像素着色器操作对正弦近似和的法线进行采样,为表面生成法线贴图。

2.1 正弦波

在这里插入图片描述

  • 波长L,用频率标识 w = 2 / L . w = 2/L. w=2/L.
  • 振幅A
  • 速度S,用 φ \varphi φ 相位标识, φ = 2 S / L \varphi = 2S/L φ=2S/L
  • 方向D:垂直于波峰行进的波前的水平向量。

每个波的状态定义为
W i ( x , y , t ) = A i × S i n ( w i × D i × ( x , y ) + t × φ i ) W_i(x,y,t) = A_i \times Sin(w_i \times D_i \times (x,y) + t\times \varphi_i) Wi(x,y,t)=Ai×Sin(wi×Di×(x,y)+t×φi)

在某个点上的高度为
H i ( x , y , t ) = ∑ ( A i × S i n ( w i × D i × ( x , y ) + t × φ i ) ) H_i(x,y,t) = \sum(A_i \times Sin(w_i \times D_i \times (x,y) + t\times \varphi_i)) Hi(x,y,t)=(Ai×Sin(wi×Di×(x,y)+t×φi))

由此,我们拥有了一个关于表面网格的隐函数。隐式的表达很难直接看出它的形状是什么,但是判断点的位置关系,在内在外在表面很方便,这就有利于我们接下来求法线和切线。

我们可以直接计算任意点的表面方向,我们的副法线(binormal)B和切线(tangent)T向量分别是x和y方向的偏导数。

  • 这一块查了一些资料,主要涉及到高数中的偏导,但是定义有些地方尚不明确,他提到的公式(指空间偏导求法切)也与我在课本上习得的内容不同
  • 然后我二次阅读的时候发现他是从二维出发到三维的:对于2D 水平面中的任意 ( x , y ),表面上的 3D 位置P…
  • 二维(即平面曲线)的副法线和切线就可以用他给的公式的得出来了
  • 一个比较有意思的但是我耗了一些时间的点,也稍微记一下吧

Binormal是垂直于Normal、Tangent平面的直线。Normal、Binormal、Tangent三条线构成一个坐标系。
在这里插入图片描述

从上图结合这一篇文章,应该可以理解以下的公式:
对于空间中的任意一点P:
P ( x , y , t ) = ( x , y , H ( x , y , t ) ) P(x,y,t) = (x,y,H(x,y,t)) P(x,y,t)=(x,y,H(x,y,t))

在这里插入图片描述
不太确定的一段:

This is a direct consequence of our using a height field to approximate our surface. That is, P(x, y).x = x and P(x, y).y = y, which become the zeros and ones in the partial derivatives. It is only valid for such a height field, but is general for any function H(x, y, t) we choose.

  • 我们近似表示表面: P ( x , y ) . x = x P(x,y).x = x P(x,y).x=x, P ( x , y ) . y = y P(x,y).y = y P(x,y).y=y,这两个值在偏导数中只为0或者1(注意看上面的公式),它只在特定的高度函数有效,但是我们选择的几乎每一个高度函数都是应验的

而我们可以得到关于H(x,y,t)的函数:
在这里插入图片描述
为了解决正弦函数的波峰波谷平均的问题(真正的海浪的波往往波峰尖,波谷宽)我们会使用正弦的变体:
在这里插入图片描述
求偏导的结果
在这里插入图片描述
长这样:
在这里插入图片描述

2.2 Geometric Waves几何波

  • 他这个几何波是不是指的正弦波的变体啊

我们只用四个几何波模拟波浪。
可以选择平面波或者球面波(忘记概念看一眼
球面波的方向D时需要用顶点计算的,它是从波的中心 C i C_i Ci到顶点的归一化向量
在这里插入图片描述
在这里插入图片描述

对于大型水体,定向波浪通常更可取,因为它们是风驱动波浪的更好模型。对于波浪源不是风的较小水池(例如瀑布的底部),最好使用圆形波浪。圆形波还具有其干涉图案从不重复的优良特性。这两种波的实现非常相似。对于定向波浪,波浪方向是从风向的某些方向范围内随机绘制的。对于圆形波浪,波浪中心是从某个有限范围(例如瀑布撞击水面的线)中随机绘制的。本次讨论的其余部分集中在定向波上。

2.3 Gerstner波

为了模拟波涛汹涌的大海,我们在这里选择 Gerstner 波,因为它们具有经常被忽视的特性:它们通过将顶点移向每个波峰形成更尖锐的波峰。因为波峰是我们表面上最尖锐(即最高频率)的特征,这正是我们希望顶点集中的地方,如图 所示。
在这里插入图片描述
它的波函数是:
在这里插入图片描述

  • 这个函数在棘突出现之前就出现了
  • Q i Q_i Qi是控制波浪陡度的参数,0级波就是普通的正弦波, Q i = 1 / ( w i A i ) Q_i = 1/( w_ i A _i ) Qi=1/(wiAi)为尖峰 。 应避免使用较大的Qi值,因为它们会导致波浪在尖尖处联通,形成环路。使用Qi = Q /(wi Ai x numWaves)可以实现从完全平滑的波浪到陡峭的波浪的变化。
  • Q i Q_i Qi的取值范围应该是从0-1。

切向空间基向量:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
并且有以下公式:
在这里插入图片描述

参数选择和调整

  • 波长:我们选择一个中间波长并生成一半到两倍长度之间的随机波长。我们无法变更已经做完的波的波长,只能更改还没有放出来的波的波长。

    给出等式:
    在这里插入图片描述
    其中w是频率,g是引力常数(例如 9.8 m/s 2),L是波长。

  • 速度:有了波长,速度很好得出来

  • 振幅:对于任何大小的波,其幅度与其波长的比率将与中值幅度与中值波长的比率相匹配。

  • 方向:波浪传播的方向完全独立于其他参数,自由选择吧

2.4 Texture Waves纹理波

上面的步骤都是为了导出纹理波(或者波浪纹理?)汇总到纹理中的波与生成它们的顶点具有相同的参数。
(稍微吐槽一下,这一节的英语有点难懂)

我们目前使用大约 15 个不同频率和方向的波,做两到四次计算。四遍听起来可能有点过分,但它们是在 256x256 渲染目标纹理中,而不是在主帧缓冲区上。
(实在是看不懂这些英语了,挑一个有意思的点出来)
texel纹素这篇讲清楚了
uv空间表示和纹理查找:
用uv坐标表示:
在这里插入图片描述
其中u和v在渲染目标上从 0 变化到 1,cos()里面的项是在顶点着色器中计算的,讲结果作为uv坐标传递给像素着色器中的纹理查找,外部项( D i x w i A i D_i x w_i A_i DixwiAi)作为常量传入

  • 按照顶点在三维世界空间中的点的坐标来查找其对应的纹理图片中的值,核心是一个三维xyz到二维纹理空间中uv坐标(纹理空间中通常用uv来表示横轴和)的映射(来自这篇文章

三、创作

我们使用顶点处的水深作为输入参数,着色器可以根据该参数自动修改其在水与海岸相遇的微妙区域。我们还介绍了一些已证明特别有用的顶点级系统覆盖。为了防止混叠伪影,我们自动过滤掉网格采样频率不足的波。

深度

  • 我们将水体底部的高度放在顶点z组件,将地下水位的高度作为常数传递,并通过减法获得可用的水深。我们使用水深来控制水的不透明度、反射的强度和几何波的幅度。拥有可用的水深还可以对光传输效果进行更复杂的建模

  • 根据深度衰减水网格与水平面相交的波浪允许水顶点在网格与陡峭河岸相交的地方“固定”。它还使进入浅岸的海浪逐渐消亡。因为我们限制我们的顶点永远不会低于它们的输入高度,所以将波浪衰减到略高于水平面的零允许波浪拍打到岸边,同时使我们能够控制它们可以在岸上走多远。

重写

  • 通常情况下,我们对每个顶点的处理都是一样的,但是我们可以通过重写顶点的信息(即RGB顶点颜色)改变处理方式
  • 默认为白色(1,1,1).红色分量控制整体透明度,当红色通带变为零时,使水面完全透明。绿色通道调制表面反射的强度,当绿色通道为零时使水面无光泽。蓝色通道限制了基于视角的不透明度衰减,这会影响菲涅耳项。

滤波
在这里插入图片描述

  • 高度函数的最短波长取决于网格的细分程度,只要网格中三角形的边与我们的高度函数中的波长相比短,表面就会看起来不错。当边缘长度与我们函数中最短波长的一半一样长或更长时,我们会看的伪影(指原本被扫描物体并不存在而在图像上却出现的各种形态的影像)。
  • 一种方法是提前确定我们的高度函数中的最短波长是多少,然后对网格进行细分,使三角形网格所有边都比该波长短一些。在这项工作中,我们采用了另一种方法:我们查看顶点附近的边长度,然后过滤掉“太短”而无法在该附近很好地表示的波。

四、运行过程

现在已经拥有了几何模型和法线贴图了,我们需要生成适当的凹凸环境映射来把这两个联系到一起。

  • 这些参数是将我们的法线从纹理空间转换到世界空间,以及将我们的表面反射到我们的立方体环境贴图中的眼睛矢量。我们首先推导出这些,然后进行顶点和像素处理。

1、映射参数

切线空间基向量:
我们可以根据水面函数的偏导数计算空间基向量。(参照Gerstner波)
在这里插入图片描述
将我们的纹理空间法线转换为表面空间法线。

  • 这个地方的两个空间,我又去查了,因为没怎么接触过,surface-space normals,texture-space normals
  • 然后扒出来了一个什么学校的pdf
  • 我先暂且这么定义吧,后面如果发现了准确的定义就回来修订

这里是引用

在这里插入图片描述

如果我们想重新调整法线的x和y分量,我们必须采取最后一步。我们可能想要重新缩放组件,因为我们在将它们写入法线贴图时已经缩放它们以最大化精度。

最终的变换矩阵
在这里插入图片描述

2、eye vector 摄像机向量

我们会将环境贴图投影到与我们的水池半径相同并且以水池为中心的球体上。目的是反射更加真实的水体结构(水反射出的东西)

给定从点C生成的环境贴图,相机现在位于点E并注视点P处的顶点。我们希望我们的眼睛矢量从E穿过P ,并在环境图中看到A处的对象。但眼睛矢量实际上是相对于生成环境贴图的点而言的,因此我们将在点B对环境贴图进行采样。
在这里插入图片描述
数学计算:
我们计算一个摄像机向量,从C指向A。我们可以找到A作为我们的原始摄像机矢量与球体相交的点,然后我们的校正后的矢量是A - C。因为A在半径为r的球面上,并且A = E + ( P - E ) t,所以我们有:
在这里插入图片描述
求解出t:
在这里插入图片描述
变量替换:
在这里插入图片描述
带入得到最小的根
在这里插入图片描述
注意看D,它的模为1,得到:
在这里插入图片描述
带入第一个公式
在这里插入图片描述
我们已经有了D,即归一化的摄像机矢量,我们使用它来根据视角衰减水的不透明度。F和G是常数。

总结

好痛苦、、
数学和物理容易让我🐏脑过载
尤其是我已经忘了一些知识了。
还有就是我是用google翻译结合英文原版看的,也许有些地方不太对劲。
埋个坑,空间之间的矩阵变换安排上。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GPU Gems是一本关于图形处理器(GPU)编程的经典书籍,由Nvidia公司出版。这本书的内容涵盖了各种有关GPU编程的主题,包括渲染、光照、物理模拟、图像处理等。通过学习这本书,读者可以了解到如何充分利用GPU的并行计算能力来提高图形渲染的效率和质量。 为了进行GPU Gems的下载,可以通过以下几种途径实现。 首先,可以到Nvidia的官方网站上搜索GPU Gems相关的资源,并尝试下载电子版的PDF文件或者浏览在线的html版本。这需要通过分别访问各个章节的网页或者注册成为Nvidia开发者来获取下载权限。网上也有一些第三方提供GPU Gems资源下载的网站,可以通过搜索引擎查找。 其次,可以尝试在一些科研论文或者技术博客的网站上查找GPU Gems相关的下载链接。这些链接可能是其他开发者或者研究者在自己的网站或者博客上分享的资源。在这些网站上找到链接后,可以直接点击下载相应的资源。 此外,可以尝试通过一些知名的编程书籍网站或者图书馆的在线平台搜索GPU Gems相关的电子书。这些平台通常会有一些付费或者免费的电子书资源,读者可以根据自己的需求选择合适的版本进行下载。 总之,通过以上的途径,读者有很多选择来下载GPU Gems,他们可以根据自己的需求选择相应的方式。无论是通过官方网站、第三方网站,还是其他相关平台,读者都能够找到他们需要的GPU Gems资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值