C++ 有效地为地形物理提供几何图形

C++ 有效地为地形物理提供几何图形,c++,game-physics,terrain,C++,Game Physics,Terrain,我一直在研究游戏引擎中地形系统的不同方法,试图熟悉这项工作。很多细节看起来都很简单,但我对其中一个细节很感兴趣 出于性能原因,许多地形解决方案使用着色器生成部分或全部几何体,例如顶点着色器生成LoD的位置或细分着色器。起初,我认为这些方法只适用于与物理模拟无关的渲染 我这样说的原因是因为我目前对着色器的理解是,着色器计算的结果通常在帧结束时被丢弃。因此,如果您严重依赖着色器,那么几何体信息将在您可以访问它并将其发送到另一个系统(例如在CPU上运行的物理)之前消失 那么,关于着色器,我错了吗?您能

我一直在研究游戏引擎中地形系统的不同方法,试图熟悉这项工作。很多细节看起来都很简单,但我对其中一个细节很感兴趣

出于性能原因,许多地形解决方案使用着色器生成部分或全部几何体,例如顶点着色器生成LoD的位置或细分着色器。起初,我认为这些方法只适用于与物理模拟无关的渲染

我这样说的原因是因为我目前对着色器的理解是,着色器计算的结果通常在帧结束时被丢弃。因此,如果您严重依赖着色器,那么几何体信息将在您可以访问它并将其发送到另一个系统(例如在CPU上运行的物理)之前消失

那么,关于着色器,我错了吗?您能否存储生成几何图形的结果以供其他系统访问?还是我必须将地形几何体保留在CPU上,并将着色器留给其他细节?

着色器 您正确理解了着色器的各个部分,即:在帧之后,数据作为最终合成图像存储在backbuffer中

但是:使用变换反馈可以将变换后的几何体捕获到顶点缓冲区中并重新使用。变换反馈发生在顶点/几何体/细分着色器之后,因此可以使用几何体着色器生成地形(或地形的可见部分)一次,将其推过变换反馈并存储。 这样,您就有可能对地形使用CPU碰撞检测!您甚至可以将其与细分相结合

你会喜欢这个:

对于LOD和细分:LOD不是细分的先决条件。可以使用细分来实现一些更复杂的效果,例如通过对粗糙几何体进行递归细分来添加细节。将其与LOD链接只是一个非常好的优化,避免了基于RAM内存的LOD网格级别,因为您只有“基本网格”并对其进行细分(尽管这将是一个不令人满意的优化imho)

现在有一些关于GPU和CPU独占地形的更深入的信息

GPU生成的地形(程序) 《英伟达篇》中的< P>:

1.2和密度函数从概念上讲,地形表面可完全由一个称为 密度函数。对于三维空间中的任意点(x、y、z),函数 生成单个浮点值。这些值随时间而变化 空间有时是积极的,有时是消极的。如果值为 正,则空间中的该点位于实心地形内

如果该值为负值,则该点位于空白处 (如空气或水)。正反界限 “密度”值为零的值是地形的曲面。 我们希望沿着该曲面构造多边形网格

使用着色器

用于生成地形的密度函数必须可用于碰撞检测着色器,并且必须填充包含碰撞位置(如果有)的输出缓冲区

CUDA

见:

有人使用了CUDA,基于英伟达的文章,但这暗示了同样的含义: 在CUDA中,执行碰撞检测时,必须共享密度函数

然而,这将使转换反馈技术更难实现

着色器和CUDA都意味着至少在一个位置重新采样/重新计算密度,仅用于单个对象的碰撞检测

CPU地形 通常,这意味着一组以顶点/索引缓冲区对的形式存储在RAM内存中的几何体,这些几何体由着色器管道定期处理。由于这里有可用的数据,您也很可能会有一个碰撞网格,它是地形的简化表示,您可以对其执行碰撞

或者,你可以使用一组碰撞器来标记允许的路径,这是早期PS1最终幻想游戏(实际上没有我们今天理解的地形)中执行的

这个简短的回答既不深刻也不完整。我只是想让你们对几十种解决方案中使用的一些概念有一些了解


更多阅读:。

我的理解是,用于物理的碰撞网格通常是地形渲染器可能使用的蒙皮网格的简化形式。您需要存储用于物理计算的碰撞网格。当你运行复杂的物理计算时,你需要尽可能少的点操作。如果您使用的是由着色器计算的几何体,它将极大地阻碍您的计算。此外,渲染引擎生成的着色器将缺少对流体物理模拟至关重要的必要增量时间变量。@Jon-->时间似乎不是问题:您可以使用统一缓冲区,它将保存您的数据,也可以与其他程序共享。非常有见地。我有一点额外的阅读要做。CPU地形更是我的目标,因为计划是为Bullet3D或PhysX之类的东西提供几何图形。当然,除非出于某种原因,这是个糟糕的主意。