地形对象碰撞检测

时间:2017-09-14 17:45:42

标签: opengl 3d collision-detection

我在过去几年里编写了自己的3D游戏引擎,并希望将其用于游戏。

我偶然发现了以下问题:

我的游戏中有多架飞机,但我们可以谈谈一架飞机。 当然,飞机无法潜入地面并在地形下飞行。 因此,我需要实现能够检测飞机/喷气机与地面之间碰撞的东西。

给出的信息如下:

  1. 地形网格[二维数组;根据x,z坐标存储高度]
  2. 我的飞机的Hitbox(它与我的飞机一起移动,因此界限等都已计算并给出)
  3. 关于hitboxes: 我想知道使用哪种方法。在性能方面最好的一个似乎是具有不同半径的简单球体。

    关于地面:从图形上看,地面被细分为三角形: enter image description here

    所以我现在需要的是最佳类型的hitbox(球体,AABB,...)和最有效的计算。

    我的尝试是获取每个周围的三角形并计算从那个三角形到我的hitbox球体的每个中心的距离。如果距离小于半径,则表示已成功检测到碰撞。但是当我的飞机上有多达10/20的球体并且要检查100个三角形时,需要花费很多时间。

    另一种尝试是从每个hitbox球体获得到地面的垂直距离。这个需要较少的计算,但在接近陡峭的表面时会失败。

    如果有人能帮我实现有效版本的飞机/地形碰撞检测,我会很高兴:)

1 个答案:

答案 0 :(得分:0)

  1. 渲染地形

    您可以尝试liner depth buffer来提高准确性。

  2. 读深度纹理

    您可以将glReadPixelsGL_DEPTH_COMPONENTGL_FLOAT一起使用。这会将深度缓冲区复制到 CPU 侧内存中。所以现在你也可以在 CPU 方面进行碰撞,或者在视图中进行任何与地面相关的计算......

  3. 将深度缓冲区用作纹理

    然后将{strong> GPU 复制回glTexImage2D。我知道这很慢(但很可能比你当前的碰撞计算速度快得多。如果你不使用 Intel HD Graphics 你可以改为#2,#3 FBO深度将深度缓冲直接渲染到纹理。但在英特尔,这不能可靠地(或根本不)。

  4. 现在使用GLSL

    渲染您的对象(屏幕外)

    内部片段着色器只是将渲染位置与深度(作为纹理附加)进行比较。如果波纹管在某处输出碰撞。如果在计算着色器中完成,则可以将结果存储在某些纹理中。或者你可以使用一些附件或 FBO

    如果您无法使用 FBO ,您可以使用特定颜色编码的碰撞渲染到“屏幕”。然后用glReadPixels读取它并扫描它以处理你在 CPU 方面的碰撞逻辑......

    不要在此传递中写入深度缓冲区!并且也不要使用CULL_FACE因为它可能会错过对象背面的某些碰撞。

  5. 现在正常渲染对象

    如果你没有在#4 中渲染,或者你将碰撞编码到屏幕缓冲区,你需要覆盖/渲染这些东西。否则,不需要此步骤。但是碰撞检测后的渲染是很好的,因为在碰撞的情况下,你很可能会改变对象的位置/方向/网格,而且已经渲染的对象可能会阻碍被改变的对象。

  6. <强> [注释]

    CPU GPU 之间复制图像的速度很慢,因此请使用 FBO 并渲染到纹理,如果可以的话。

    如果您不熟悉多次传递渲染,请参阅一些QA获取灵感:

    这只适用于视图...但你可以做只是碰撞渲染传递(每个对象)。使用相机设置渲染从上到下(鸟眼)查看并仅覆盖对象周围的区域...此外,您不需要太大的分辨率,因此它应该相对较快...所以您可以将屏幕划分为正方形区域(使用glViewport)在单帧中测试更多对象,以尽可能地减少同步时间减速(使用较少的glReadPixel次调用)。此外,您不需要任何顶点颜色或纹理。