3D游戏几何

时间:2012-02-16 03:00:15

标签: java c++ geometry computational-geometry

我有一个使用3D网格表示的简单游戏,例如:

Blocks grid[10][10][10];

游戏中的人用点和视线向量表示:

double x,y,z, dx,dy,dz;

我使用3个嵌套for循环绘制网格:

for(...) for(...) for(...)
   draw(grid[i][j][k]);

显而易见的问题是,当网格的大小增加到数百个时,fps会急剧下降。凭借一些直觉,我意识到:

  • 不需要渲染网格中其他块隐藏的块
  • 不在人的视野范围内的块也不需要渲染(即,人物背后的块)

我的问题是,给定grid[][][],一个人的x,y,z和一个视线向量dx,dy,dz,我怎么能找出需要渲染哪些块而哪些块不需要渲染?

3 个答案:

答案 0 :(得分:7)

我研究过使用JMonkeyEngine,一个3D游戏引擎,不久前看了一下他们采用的一些技术。从我记忆中,他们使用了一种叫做剔除的东西。他们构建了“世界”中存在的一切树形结构。接下来的想法是,您拥有此树的一个子集,可以在任何给定时间表示可见对象。换句话说,这些是需要渲染的东西。所以,比方说,我在房间里有一个房间里有物品。房间在树上,房间里的物品是树的孩子。如果我在房间外面,那么我修剪(删除)树的这个分支,这意味着我不渲染它。这样做的原因很好,我不需要评估世界上的每个对象,看它是否应该渲染,而是我快速修剪我知道不应该渲染的世界的所有部分。

更好的是,当我走进房间时,我从树上修剪整个世界,然后只渲染房间及其所有后代。

我认为JMonkeyEngine团队制作的很多设计决策都是基于David Eberly的书3D Game Engine Design中的内容。我不知道如何实现这样的方法的技术细节,但我敢打赌这本书对你来说是一个很好的起点。

对于一些不同的剔除算法,这是一个有趣的article

  • 查看Frustum Culling
  • 背面剔除
  • 基于细胞的遮挡剔除
  • 基于PVS的任意几何遮挡剔除
  • 其他

答案 1 :(得分:1)

首先你需要一个空间分区结构,如果你使用统一的块大小,最有效的结构可能是octree。然后,您需要编写一个算法,该算法可以计算框是否位于平面的特定一侧(或相交)。一旦你有了,你就可以计算出八角树的哪些叶节点位于视锥体的六个边内 - 那就是视图剔除。同样使用八叉树,您可以确定哪些块遮挡了其他块(有时称为视锥体遮罩),但首先使第一部分工作。

答案 2 :(得分:1)

这听起来像是在寻找类似Minecraft-y的东西。 看看this android minecraft level renderer。 需要注意的要点是:

  • 您只需绘制与透明块共享的块的面。例如:不要在两个不透明的块之间画面 - 玩家永远不会看到它们。
  • 您可能希望将可见块几何体批量化为块(并将其粘贴到VBO中)并确定每个块的可见性。找到确切地看到哪些块可能需要更长的时间,而不仅仅是在gpu上投掷VBO并接受透支。
  • 洪水填充非常适合确定哪些存储块可见 - 使用视锥体,视图方向限制填充(如果您面向+ ve x方向,请勿沿-ve方向泛滥) ,以及对存储块数据的简单分析(例如:如果存储块的整个面是不透明的,不要在该面上泛滥)