2017-09-14 130 views
-2

我在过去几年中编写了自己的3D游戏引擎,并希望将其用于游戏。地形对象碰撞检测

我迷迷糊糊accros以下问题:

我在游戏的多面,但讲起一个单一的平面。当然,飞机不能潜入地面并在地形下飞行。因此,我需要实施一些能够检测飞机/喷气机与我的地面之间的碰撞的东西。

给出的信息如下:

  1. 网格地形[2-维阵列;在根据X专卖店高度,z坐标]
  2. 击中格我的飞机(它的动作与我的飞机,所以边界等等都已经计算和给予)

所以对hitboxes的: 我虽然约使用哪种方法。表现最好的一个似乎是不同半径的简单球体。

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

所以我现在需要的是最佳的类型击中格的(球体,AABB,...),并且根据最有效的计算。

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

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

我将非常高兴,如果有人愿意帮助我实现平面/地形碰撞检测:)

+0

回答这个问题会非常广泛。您应该阅读[Octree](https://en.wikipedia.org/wiki/Octree) - 另请参阅[用于高效碰撞检测的最佳算法](https:// stackoverflow。com/questions/7107231/best-algorithm-for-efficient-collision-detection-objects-objects)和[八叉树中的边界框](https://gamedev.stackexchange.com/questions/25626/bounding-boxes-in- octrees) – Rabbid76

+0

渲染的飞机,你可以在着色器中做到这一点。我假设在对象之前渲染地形,所以一旦你试图在平面下面渲染平面片段(测试前一次传递的预存深度纹理),就会发生碰撞,因此可以将平面ID输出到某些1D纹理输出或其他任何东西。这种方式是完美的像素,甚至可以提供命中的位置。 – Spektre

+0

为了提高我的着色器速度,我预先计算了每个顶点的高度。所以没有“深度纹理”。我也可能在从我的身高地图上阅读后更改顶点位置。 – Luecx

回答

0
  1. 渲染地形的有效版本

    可能是你可以尝试liner depth buffer以提高精确度。

  2. 读取深度纹理

    可以使用glReadPixelsGL_DEPTH_COMPONENTGL_FLOAT。这将复制深度缓冲区到CPU侧存储器。所以,现在你也可以做CPU侧或鉴于对地有关的任何计算碰撞......

  3. 使用深度缓冲纹理

    所以将它复制回GPUglTexImage2D。我知道这是慢的(但最有可能快得多,那么你当前的计算碰撞。如果你不使用英特尔高清显卡你可以代替#2,#3使用FBO深度将直接渲染深度缓冲区质感。但英特尔并不可靠(或全部)工作。

  4. 现在GLSL

    片段着色器里呈现你的对象(关闭屏幕)只是比较深度渲染位置(附纹理)如果波纹管在某处输出碰撞,如果在计算着色器中完成,则可以将结果存储在某个纹理中。或者你可以使用一些附件或FBO为此。

    如果你不能使用FBO你可以渲染到具有颜色编码冲突的“屏幕”。然后用glReadPixels读取它并扫描它以处理你在CPU端有什么碰撞逻辑...

    不要在此通道中写入深度缓冲区!也不要使用CULL_FACE,因为这可能会遗漏物体背面的某​​些碰撞。

  5. 现在渲染的对象正常

    的情况下,你不#4渲染或你编码碰撞,你需要重写/渲染的东西屏幕缓冲区。否则,这一步是不需要的。但是在碰撞检测之后渲染是很好的,因为在发生碰撞的情况下,最有可能改变对象位置/方向/网格,并且已经渲染的对象可能阻碍了改变的对象。

[注意事项]

复制图像CPU之间GPU慢所以用FBO如果可以的话,而不是渲染到纹理。

如果你不熟悉多通道渲染看到一些质量检查的灵感:

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