虚幻引擎 Gerstner Waves -GPU Gems 从物理模型中实现有效的水体模拟

news2024/12/25 23:45:50

这篇文章重点在于结合GPU Gems一书中有关Gerstner Waves 的数学公式,在虚幻引擎中复现正确的Gerstner Waves和正确的法线

文中内容整理自书中,并附带我的理解,与在虚幻引擎中的实现,可以参考原文看这篇文章,原文网上很多,我这里就不转载了


1.2.1选择波形

我们需要一组参数来定义每个波形。如图1-2所示,这些参数包括:

  • Wavelength 波长 L L L
    • 世界空间中波峰到波峰之间的距离。
    • 波长 L L L 与角频率 w w w 之间的关系为 $w = \frac{2\pi}

这里将会出现第一个坑,包括英伟达官方的

{L}$。

  • Amplitude 振幅 A A A

    • 从水平面到波峰的高度。
  • Speed 速度 S S S

    • 波峰每秒前进的距离。 将速度表示为相位常数 φ \varphi φ 更为方便。
    • φ = S × 2 π L \varphi = S \times\frac{2\pi}{L} φ=S×L2π

这里将会出现第一个坑,包括英伟达官方的文档,这里都丢失了一个π,原书中为 w=2pi/L,下同

  • Direction 方向 D D D
    • 垂直于波阵面的水平向量,波峰沿着波阵面运动。

为了在场景的动态中提供变化,我们将在一定的约束条件下随机生成这些波浪参数。随着时间的推移,我们将持续地将一个波浪渐隐,然后再以一组不同的参数将其渐显。
事实证明,这些参数是相互依赖的。必须仔细的为每个波浪生成一整套参数,这些参数需要以一种令人信服的方式组合在一起。

新建一个函数,我们先把上方出现的变量input写入:
在这里插入图片描述

1.2.2 法线和切线

因为表面是显式函数,所以我们可以直接计算任何点的表面方向,而不需要依赖有限差分技术。
副法线向量 B B B 和切线向量 T T T 是分别 x x x y y y 方向的偏导数。对于2D水平面中的任何点 ( x x x , y y y ),表面上的三维位置 P P P 是:

Equation 6a 公式6a

N ( x , y ) = B ( x , y ) × T ( x , y ) \mathbf{N}(x,y)=\mathbf{B}(x,y)\times\mathbf{T}(x,y) N(x,y)=B(x,y)×T(x,y)

我们先跳过这个,最后再来处理法线

格斯特纳波GerstnerWaves

为了有效的模拟,我们需要控制波浪的陡峭程度。如前所述,正弦波呈现出圆润的外观——这可能正是我们想要的平静、田园诗般的池塘效果。但对于粗犷的海面,我们需要形成更尖锐的波峰和更宽阔的波谷。我们可以使用公式8a和8b来实现所需的形状,但我们选择了相关的格斯特纳波。
GerstnerWaves早在有计算机图形学之前就被开发出来,用于在物理基础上模拟海水。因此GerstnerWaves提供了一些表面的微妙运动,这些变化不明显但是非常可信。(详细描述参见Tessendorf 2001)。
我们选择GerstnerWaves,因为它们有一个常被忽视的特性:将,这正是我们希望顶点集中的地方,如图1-5所示。

GerstnerWaves

图1-5 GerstnerWaves

这是GerstnerWaves函数:

Equation 9 公式9

P ( x , y , t ) = ( x + ∑ ( Q i A i × D i . x × cos ⁡ ( w i D i ⋅ ( x , y ) + φ i t ) ) , y + ∑ ( Q i A i × D i . y × cos ⁡ ( w i D i ⋅ ( x , y ) + φ i t ) ) , ∑ ( A i sin ⁡ ( w i D i ⋅ ( x , y ) + φ i t ) ) ) \mathbf{P}\left(x, y, t\right) = \left(\begin{array}{l} \begin{alignedat}{3} &x&+&\sum \left(Q_{i}A_{i} \times \mathbf{D}_{i}.x \times \cos\left(w_{i}\mathbf{D}_{i} \cdot (x, y) + \varphi_{i}t\right)\right),\\ &y&+& \sum \left(Q_{i}A_{i} \times \mathbf{D}_{i}.y \times \cos\left(w_{i}\mathbf{D}_{i} \cdot (x, y) + \varphi_{i}t\right)\right),\\ & & &\sum \left(A_{i} \sin\left(w_{i}\mathbf{D}_{i} \cdot (x, y) + \varphi_{i}t\right)\right) \end{alignedat} \end{array}\right) P(x,y,t)= xy++(QiAi×Di.x×cos(wiDi(x,y)+φit)),(QiAi×Di.y×cos(wiDi(x,y)+φit)),(Aisin(wiDi(x,y)+φit))

∑为求和,∑()也就是所有波加在一起的,,我们想要先实现一个波,那么公式可以写为:

Px = Q×A×Dx×cos(w×D·(x,y) + φ×t);
Py = Q×A×Dy×cos(w×D·(x,y) + φ×t);
Pz =      A       ×sin(w×D·(x,y) + φ×t);

能看到我们想实现做这个公式还需要两个变量,xy和t,他们分别是:
在这里插入图片描述

这里 Q i Q_i Qi 是一个控制波浪陡峭程度的参数。
对于单个波浪 i i i Q i = 0 Q_i=0 Qi=0 产生常见的滚动正弦波,而 Q i = 1 w i A i Q_i = \frac{1}{w_i A_i} Qi=wiAi1 产生尖锐的波峰。应避免使用较大的 Q i Q_i Qi 值,因为它们会在波峰上方形成环。
实际上,我们可以将 Q Q Q 作为“陡峭程度”参数留给制作艺术家来指定,允许范围是 0 0 0 1 1 1,并使用 Q i = Q w i A i × numWaves Q_i = \frac{Q}{w_i A_i \times \text{numWaves}} Qi=wiAi×numWavesQ 来变化,从完全平滑的波浪到我们能产生的最尖锐的波浪。

值得注意的是,公式3和公式9之间唯一的区别是顶点的横向移动。他们的高度是相同的。这意味着我们不再有一个严格的高度函数。即, P ( x , y , t ) . x ≠ x \mathbf{P}(x,y,t).x \neq x P(x,y,t).x=x 。然而,该函数仍然容易求导,并且有一些项可以方便的消去。求导后得到切线空间的基础向量是:

Equation 10 公式10

B = ( 1 − ∑ ( Q i × D i . x 2 × W A × S ( ) ) , − ∑ ( Q i × D i . x × D i . y × W A × S ( ) ) , ∑ ( D i . x × W A × C ( ) ) ) \mathbf{B} = \begin{pmatrix} \begin{alignedat}{3} &1&-&\sum\left(Q_i \times \mathbf{D}_i.x^2 \times WA \times S()\right),\\ & &-&\sum\left(Q_i \times \mathbf{D}_i.x \times \mathbf{D}_i.y \times WA \times S()\right),\\ & & &\sum\left(\mathbf{D}_i.x \times WA \times C()\right) \end{alignedat} \end{pmatrix} B= 1(Qi×Di.x2×WA×S()),(Qi×Di.x×Di.y×WA×S()),(Di.x×WA×C())

Equation 11 公式11

T = ( − ∑ ( Q i × D i . x × D i . y × W A × S ( ) ) , 1 − ∑ ( Q i × D i . y 2 × W A × S ( ) ) , ∑ ( D i . y × W A × C ( ) ) ) \mathbf{T}= \begin{pmatrix} \begin{alignedat}{3} & &-&\sum\bigl(Q_{i}\times\mathbf{D}_{i}.x\times\mathbf{D}_{i}.y\times WA\times S()\bigr),\\ &1&-&\sum\bigl(Q_{i}\times\mathbf{D}_{i}.y^{2}\times WA\times S()\bigr),\\ & & &\sum\bigl(\mathbf{D}_{i}.y\times WA\times C()\bigr) \end{alignedat} \end{pmatrix} T= 1(Qi×Di.x×Di.y×WA×S()),(Qi×Di.y2×WA×S()),(Di.y×WA×C())

Equation 12 公式12

N = ( − ∑ ( D i . x × W A × C ( ) ) , − ∑ ( D i . y × W A × C ( ) ) , 1 − ∑ ( Q i × W A × S ( ) ) ) \mathbf{N}=\begin{pmatrix} \begin{aligned} &{}- \sum\bigl(\mathbf{D}_i.x\times WA\times C()\bigr),\\ &{}- \sum\bigl(\mathbf{D}_i.y\times WA\times C()\bigr),\\ 1 &{}- \sum\bigl(Q_i\times WA\times S()\bigr) \end{aligned} \end{pmatrix} N= 1(Di.x×WA×C()),(Di.y×WA×C()),(Qi×WA×S())

其中:
W A = w i × A i , WA=w_{i}\times A_{i}, WA=wi×Ai,
S ( ) = sin ⁡ ( w i × D i ⋅ P + φ i t ) S()=\sin\left(w_{i}\times\mathbf{D}_{i}\cdot\mathbf{P}+\varphi_{i}t\right) S()=sin(wi×DiP+φit)
C ( ) = cos ⁡ ( w i × D i ⋅ P + φ i t ) C()=\cos\bigl(w_{i}\times\mathbf{D}_{i}\cdot\mathbf{P}+\varphi_{i}t\bigr) C()=cos(wi×DiP+φit)
这里的 P P P 指的是 ( x x x y y y )
这些公式不像4b、5b和6b方程那样简洁明了,但它们计算起来非常高效。

在形成波峰环的背景下,仔细观察法线的 z z z 分量证明了这一点非常有趣。虽然 Tessendorf (2001) 从流体动力学的纳维-斯托克斯1描述和“李变换技术2”中推导出他的“切碎效应3”,最终结果是在频率域中表达的格斯特纳波的一个变体。
在频率域中,可以避免并检测到波顶的环形,但在空间域中,我们可以清楚地看到正在发生的事情。
Q i × w i × A i Q_i \times w_i \times A_i Qi×wi×Ai 的和大于 1 1 1 时,我们法线的 z z z 分量在峰值处可能变为负值,因为我们的波浪会在自身上方形成环。
只要我们选择的 Q i Q_i Qi 使得这个和始终小于或等于 1 1 1,我们将形成尖锐的峰值但永远不会形成环。

1.2.4参数解释

波长和速度 Wavelength Speed

我们首先选择合适的波长。与其追求现实世界的分布,不如最大化我们能承担的少数波浪的效果。
相似长度的波浪的叠加突出了水面的动态性。
因此,我们选择一个中值波长,并在该长度的一半到两倍之间生成随机波长。中值波长在创作过程中被编写,它可以随时间变化。
例如,在暴风雨期间,波浪可能比晴朗平静时显著更大。
注意,我们不能改变正在活动的波的波长。即便是逐渐改变,波浪的波峰也会向原点扩展或收缩,这看起来非常不自然。
因此,我们改变当前的平均波长,随着时间的推移,当波浪淡出以后,它们将基于新的长度重新生成。方向也是如此。

根据波长,我们可以轻松计算它在表面上的传播速度。Tessendorf 2001中给出忽略高次项的传播关系:

Equation 13 公式13

w = g × 2 π L w=\sqrt{g\times{\frac{2\pi}{L}}} w=g×L2π
其中 w w w 是角频率, g g g 是标准下的(例如980cm/s)重力常数, L L L 是波峰到波峰的长度。

振幅 Amplitude

如何处理振幅是一个见仁见智的问题。
虽然振幅可以看做波长和当前天气条件的函数来求得振幅导数,但我们还是要使用在编写时指定的常数(或脚本化的)比率。
更准确地说,与中值波长一起,艺术家指定了一个中值振幅。
对于任何大小的波浪,其振幅与波长的比率将匹配中值振幅与中值波长的比率。

方向 Direction

波浪行进的方向与其他参数完全独立,因此我们可以根据自己选择的任何标准为每个波浪选择一个方向。
如前所述,我们从大致是风向的恒定向量开始。然后我们从风向的恒定角度内随机选择方向。
这个恒定角度在内容创建时被指定,或者可能被脚本化。


施工中待续

  • 参考来自Gerstner Waves圣经—— Mark Finch - Cyan Worlds GPU Gems

  1. Navier-Stokes ↩︎

  2. Lie Transform Technique ↩︎

  3. choppiness ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1857294.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大模型时代,普通人的科研何去何从

前言 随着大模型技术的飞速发展和普及,我们已经步入了一个全新的科研时代。在这个时代,大数据、深度学习和人工智能等前沿技术成为了推动科研创新的重要引擎。 那么,面对如此迅猛的发展势头,普通人科研该何去何从呢?…

【离散数学】图的随机生成和欧拉(回)路的确定(c语言实现)

实验要求 变量定义 因为如果我们使用局部变量,每一个函数都会使用这些变量,会让函数的参数越变越多。所以我们定义全局变量,这样就不用在参数中调用了。 #define MAX 100 int arrMap[MAX][MAX] { 0 };//图的矩阵 int degree[MAX] { 0 };…

vue2+webpack 和 vite+vue3 配置获取环境变量(补充)

相关涉及知识点可看小编该文章: nginx: 部署前端项目的详细步骤(vue项目build打包nginx部署)_前端工程打包部署到nginx-CSDN博客 1.vue2webpack 我们通常会在项目中看到这么两个文件(没有则自己创建,文件名:.env.***) …

热腾腾的,仓颉cangjie和C#的初战

花了一个下午快速浏览了一下仓颉(Cangjie)的文档。总体感觉,仓颉把现代编程语言的各种特征都融合在一起,称它为“缝合怪”一点都不夸张。没有历史包袱的确让它看起来很爽。由于目前还无法实际试用它,所以编译和运行性能…

Apache Doris 基础 -- 视图和物化视图

1、视图 视图(逻辑视图,logical views)是封装了一个或多个SELECT语句的存储查询(stored queries)。视图在执行时动态访问和计算数据库数据。视图是只读的,可以引用任何表和其他视图的组合。 视图可用于以下目的: 通过对用户隐藏…

全行业通用商城小程序源码

一站式购物新体验 一、引言:开启数字化购物新时代 在数字化快速发展的今天,小程序成为了商家们连接消费者的重要桥梁。特别是“全行业通用商城小程序”,以其便捷的购物体验和多样化的功能,成为了越来越多商家和消费者的首选。本…

mabl:AI原生测试自动化平台的基础使用

mabl:AI原生测试自动化平台的基础使用 简介注册登录安装基本使用创建第一个浏览器测试 Mabl的AI驱动测试能力自动化测试开发与维护异常监测与根源分析高级分析与报告自适应测试执行跨平台兼容性测试 简介 mabl 是一个基于人工智能和机器学习的云原生测试自动化平台…

学习记录之数学表达式(5)

文章目录 十、线性回归10.1 示例10.2 拟合10.3 推导10.4 岭回归10.5 作业 十一、Logistic回归11.1 分割超平面11.2 点到直线的距离11.3 sigmoid函数11.4 优化目标11.5 求解11.6 作业 十、线性回归 线性回归是一个常用的机器学习算法; 10.1 示例 表 1.单变量的股价预…

推荐一款好用的浏览器翻译插件——欧路翻译

近些年,机器翻译的效果越来越好,于是也有更多的开发者,开发了免费使用的浏览器翻译插件。这大大的帮助了我们查看国外的网站,有利于大家获取更多的信息。 在此,给大家推荐一款免费好用的浏览器插件——欧路翻译。支持…

百元左右蓝牙耳机的牌子有哪些?盘点性价比最高的百元机推荐

随着智能手机的普及,蓝牙耳机以其便携性和灵活性逐渐成为人们日常生活不可或缺的配件。尤其是百元左右的蓝牙耳机,因其价格亲民且功能齐全,深受广大消费者的青睐。无论是通勤途中隔绝嘈杂,还是运动时候的动感伴侣,或是…

GPT-5:AI新时代的曙光与我们的准备

一、引言:GPT-5的即将来临 随着科技的飞速发展,人工智能领域正迎来一场前所未有的变革。OpenAI再次引领了这场变革的浪潮,即将发布的GPT-5无疑将成为AI领域的一颗璀璨明星。从GPT-4到GPT-5,每一次的迭代都代表着AI技术的巨大飞跃…

[保姆级教程]在uniapp中使用vant框架

文章目录 导文安装 Vant在uniapp项目中的pages.json中配置easycom,实现组件的自动按需引入:在页面中使用Vant Weapp组件,例如使用按钮组件(Button):其他安装报错官网地址 导文 在 uni-app 中使用 Vant 框架…

使用 GitHub Actions 编译和发布 Android APK

使用 GitHub Actions 编译和发布 Android APK 在现代软件开发中,持续集成和持续部署(CI/CD)已成为不可或缺的一部分。对于 Android 开发者来说,自动化编译和发布 APK 不仅节省时间,还能确保每次发布的一致性。本文将介…

人工智能大模型走向“百花齐放”

前言 去年以来,人工智能大模型浪潮持续涌动。国内外一大批创新企业和高校院所加大研究力度,纷纷推出各自的大模型产品,尤其国产大模型取得了长足进步,大量高质量模型百花齐放,助力中国成为全球人工智能发展的领头羊之…

cmake或vcpkg安装opencv-contrib中遇到raw.githubusercontent.com下载文件失败的错误记录

问题总结:你的网络无法正常在raw.githubusercontent.com网站中下载文件 问题解决:将你的梯子切换为全局的美国节点(香港、日本等均不可行) 问题记录—— cmake: 我在opencv_code中放置了opencv和opencv-contrib的sou…

新建的springboot项目启动报错:找不到或无法加载主类

检查编译问题 在使用Spring Boot时,我们通常使用Maven或Gradle进行项目的构建和编译。如果在编译过程中出现了错误,可能会导致无法加载主类的问题。 在使用Maven时,可以尝试使用 mvn clean install 命令清理并重新构建项目。 如果使用Grad…

Hi3861 OpenHarmony嵌入式应用入门--LiteOS Event

CMSIS 2.0接口使用事件标志是实时操作系统(RTOS)中一种重要的同步机制。事件标志是一种轻量级的同步原语,用于任务间或中断服务程序(ISR)之间的通信。 每个事件标志对象可以包含多个标志位,通常最多为31个&…

LabVIEW高精度电能质量监测系统

LabVIEW和研华采集卡的高精度电能质量监测系统利用虚拟仪器技术,实时监测电能质量的关键指标,如三相电压、频率和谐波。通过提高监测精度和效率,改善电网的电能质量。系 一、系统背景 电能作为现代社会的关键能源,其质量直接影响…

MySQl配置环境变量

配置环境变量 (a)添加一个系统变量,变量名:CATALINA-HOME,变量值:MySql在自己电脑当中的安装路径,注意:5.7版本需要配置的路径是MySQL.Sever5.7的文件夹路径。 (b)在Path变量的结尾添加一个英文分号,之后把上面添加的路径导入进去(%CATALINA-HOME%)在这个结尾处添加\bin. (2)登…

Python爬虫项目集:豆瓣电影排行榜top250

关于整理日常练习的一些爬虫小练习,可用作学习使用。 爬取项目以学习为主,尽可能使用更多的模块进行练习,而不是最优解。 爬虫概要 示例python 库爬取模块request解析模块BeautifulSoup存储类型list(方便存入数据库&#xff09…