【问题标题】:Terrain Object collision detection地形物体碰撞检测
【发布时间】:2017-09-16 18:10:48
【问题描述】:

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

我偶然发现了以下问题:

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

给出的信息如下:

  1. 地形网格[二维数组;根据 x,z 坐标存储高度]
  2. 我的飞机的 Hitbox(它与我的飞机一起移动,所以边界等都已经计算和给出)

关于命中框: 我虽然关于使用哪种方法。就性能而言,最好的似乎是具有不同半径的简单球体。

关于地面:在图形上,地面被细分为三角形:

所以我现在需要的是最佳类型的碰撞箱(球体、AABB、...)以及相应的最有效的计算。

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

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

如果有人能帮我实现一个高效的平面/地形碰撞检测版本,我会非常高兴:)

【问题讨论】:

  • 对于渲染平面,您可以在着色器中执行此操作。我假设地形是在对象之前渲染的,因此一旦您尝试在表面下方渲染平面片段(测试上一次传递的预存储深度纹理),您就会知道发生了碰撞,因此您可以将平面 ID 输出到某些 1D 纹理输出或其他内容。这种方式是像素完美的,甚至可以提供命中的位置。
  • 为了提高着色器的速度,我预先计算了每个顶点的高度。所以没有“深度纹理”。从我的高度图读取后,我也可能会更改顶点位置。
  • 等等。 Nvm,您在谈论深度纹理。我怎么读那个?
  • @Luecx 我将我的评论改写为答案,以便更清楚

标签: opengl 3d collision-detection


【解决方案1】:
  1. 渲染地形

    也许你可以试试liner depth buffer 来提高准确性。

  2. 读取深度纹理

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

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

    所以用glTexImage2D 将其复制回GPU。我知道这很慢(但很可能比您当前的碰撞计算快得多。如果您不使用 Intel HD Graphics 您可以改为 #2,#3 使用FBO 用于将深度缓冲区直接渲染到纹理的深度。但在 Intel 上,这不能可靠地工作(或根本不工作)。

  4. 现在使用 GLSL 渲染您的对象(屏幕外)

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

    如果您不能使用 FBO,您可以使用特定颜色编码的碰撞渲染到“屏幕”。然后用glReadPixels 阅读它并扫描它以处理您在 CPU 端的任何碰撞逻辑......

    在这个过程中不要写入深度缓冲区!!!并且也不要使用CULL_FACE,因为这可能会错过对象背面的一些碰撞。

  5. 现在正常渲染对象

    如果您没有在 #4 中渲染,或者您将碰撞编码到屏幕缓冲区,您需要覆盖/渲染这些内容。否则不需要这一步。但是在碰撞检测之后渲染是好的,因为在发生碰撞的情况下,您很可能会更改对象的位置/方向/网格,并且已经渲染的对象可能会阻碍更改的对象。

[备注]

CPUGPU 之间复制图像很慢,因此请使用 FBO 并尽可能渲染到纹理。

如果您不熟悉多通道渲染,请参阅一些 QA 以获得灵感:

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

【讨论】:

    猜你喜欢
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2015-02-10
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多