我在过去几年里编写了自己的3D游戏引擎,并希望将其用于游戏。
我偶然发现了以下问题:
我的游戏中有多架飞机,但我们可以谈谈一架飞机。 当然,飞机无法潜入地面并在地形下飞行。 因此,我需要实现能够检测飞机/喷气机与地面之间碰撞的东西。
给出的信息如下:
关于hitboxes: 我想知道使用哪种方法。在性能方面最好的一个似乎是具有不同半径的简单球体。
所以我现在需要的是最佳类型的hitbox(球体,AABB,...)和最有效的计算。
我的尝试是获取每个周围的三角形并计算从那个三角形到我的hitbox球体的每个中心的距离。如果距离小于半径,则表示已成功检测到碰撞。但是当我的飞机上有多达10/20的球体并且要检查100个三角形时,需要花费很多时间。
另一种尝试是从每个hitbox球体获得到地面的垂直距离。这个需要较少的计算,但在接近陡峭的表面时会失败。
如果有人能帮我实现有效版本的飞机/地形碰撞检测,我会很高兴:)
答案 0 :(得分:0)
渲染地形
您可以尝试liner depth buffer来提高准确性。
读深度纹理
您可以将glReadPixels
与GL_DEPTH_COMPONENT
和GL_FLOAT
一起使用。这会将深度缓冲区复制到 CPU 侧内存中。所以现在你也可以在 CPU 方面进行碰撞,或者在视图中进行任何与地面相关的计算......
将深度缓冲区用作纹理
然后将{strong> GPU 复制回glTexImage2D
。我知道这很慢(但很可能比你当前的碰撞计算速度快得多。如果你不使用 Intel HD Graphics 你可以改为#2,#3 FBO深度将深度缓冲直接渲染到纹理。但在英特尔,这不能可靠地(或根本不)。
现在使用GLSL
渲染您的对象(屏幕外)内部片段着色器只是将渲染位置与深度(作为纹理附加)进行比较。如果波纹管在某处输出碰撞。如果在计算着色器中完成,则可以将结果存储在某些纹理中。或者你可以使用一些附件或 FBO 。
如果您无法使用 FBO ,您可以使用特定颜色编码的碰撞渲染到“屏幕”。然后用glReadPixels
读取它并扫描它以处理你在 CPU 方面的碰撞逻辑......
不要在此传递中写入深度缓冲区!并且也不要使用CULL_FACE
因为它可能会错过对象背面的某些碰撞。
现在正常渲染对象
如果你没有在#4 中渲染,或者你将碰撞编码到屏幕缓冲区,你需要覆盖/渲染这些东西。否则,不需要此步骤。但是碰撞检测后的渲染是很好的,因为在碰撞的情况下,你很可能会改变对象的位置/方向/网格,而且已经渲染的对象可能会阻碍被改变的对象。
<强> [注释] 强>
在 CPU 和 GPU 之间复制图像的速度很慢,因此请使用 FBO 并渲染到纹理,如果可以的话。
如果您不熟悉多次传递渲染,请参阅一些QA获取灵感:
这只适用于视图...但你可以做只是碰撞渲染传递(每个对象)。使用相机设置渲染从上到下(鸟眼)查看并仅覆盖对象周围的区域...此外,您不需要太大的分辨率,因此它应该相对较快...所以您可以将屏幕划分为正方形区域(使用glViewport
)在单帧中测试更多对象,以尽可能地减少同步时间减速(使用较少的glReadPixel
次调用)。此外,您不需要任何顶点颜色或纹理。