我现在一直在研究游戏引擎中地形系统的不同方法,试图熟悉这项工作.许多细节看起来很简单,但我对一个细节感到困惑.
出于性能原因,许多地形解决方案利用着色器生成部分或全部几何体,例如顶点着色器以生成LoD的位置或曲面细分着色器.起初我认为这些方法专门用于不关心物理模拟的渲染.
我之所以这么说是因为我理解了着色器,因此着色器计算的结果通常会在帧的末尾被丢弃.因此,如果您严重依赖着色器,那么几何信息将在您访问它并将其发送到另一个系统(例如在CPU上运行的物理)之前消失.
那么,我对着色器有误吗?您可以存储它们的结果,生成要由其他系统访问的几何体吗?或者我是否被迫将地形几何保留在CPU上并将着色器留给其他细节?
最佳答案 着色器
您了解着色器的某些部分是正确的,即:在一帧之后,数据将作为最终合成图像存储在后备缓冲区中.
但是:使用变换反馈,可以将变换后的几何体捕获到顶点缓冲区中并重复使用.变换反馈在顶点/几何/细化着色器之后发生,因此您可以使用几何着色器生成地形(或其一次的可见部分),将其推送到变换反馈并存储它.
这样,您可以在地形上使用CPU碰撞检测!你甚至可以将它与tesselation结合起来.
你会喜欢这个:http://andrew-flower.com/assets/projects/defter-thesis-f9a659feea18ffe347b24e3bbfc054d8.pdf
对于LOD和Tesselation:LOD不是Tesselation的先决条件.您可以使用Tesselation允许一些更复杂的效果,通过递归细分粗糙几何来添加细节.将它与LOD链接只是一个非常好的优化,避免了基于RAM内存的LOD网格级别,因为你只需要你的“基础网格”并细分它(虽然这将是一个不令人满意的优化imho).
现在有关GPU和CPU专有地形的更深入信息.
GPU生成的地形(程序)
正如在NVidia文章中所写 – (https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch01.html):
1.2 Marching Cubes and the Density Function Conceptually, the terrain surface can be completely described by a single function, called the
density function. For any point in 3D space (x, y, z), the function
produces a single floating-point value. These values vary over
space—sometimes positive, sometimes negative. If the value is
positive, then that point in space is inside the solid terrain.If the value is negative, then that point is located in empty space
(such as air or water). The boundary between positive and negative
values—where the density value is zero—is the surface of the terrain.
It is along this surface that we wish to construct a polygonal mesh.
使用着色器
用于生成地形的密度函数必须可用于碰撞检测着色器,并且必须填充包含碰撞位置的输出缓冲区(如果有)…
CUDA
见:https://www.youtube.com/watch?v=kYzxf3ugcg0
在这里有人使用CUDA,基于NVidia文章,但是暗示相同:
在CUDA中,执行碰撞检测时,必须共享密度函数.
然而,这将使变换反馈技术更难实现.
Shaders和CUDA都暗示至少在一个位置重新采样/重新计算密度,仅用于单个物体的碰撞检测.
CPU地形
通常,这意味着以顶点/索引 – 缓冲区对的形式存储RAM存储器的几何体,这些对象由着色器管道定期处理.由于您具有此处可用的数据,因此您很可能还会有一个碰撞网格,它是您的地形的简化表示,您可以根据该网格执行碰撞.
或者,您可以在地形上使用一组碰撞器,标记允许的路径,这是在早期的PS1最终幻想游戏中执行的(实际上我们今天理解地形并不真正具有地形).
这个简短的答案既不深入也不完整.我只是想让你深入了解几十个解决方案中使用的一些概念.
更多阅读:http://prideout.net/blog/?tag=opengl-transform-feedback