2012-02-16 109 views
8

我有一个使用一个三维网格表示一个简单的游戏,是这样的:3D游戏几何

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

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

在游戏中的人是由一个点和视线向量表示我画用3格嵌套的for循环:

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

与此明显的问题是,当网格的大小增长匈奴内dreds,fps显着下降。对于一些直觉,我意识到:

是由在网格中的其他区块隐藏
  • 块不需要被渲染
  • 块所没有的人的视野范围内也不需要是

我的问题是,给定一个grid[][][],呈现(即是后面的人即块)一个人的x,y,z,以及视线矢量dx,dy,dz,我怎么能弄清楚哪些块需要渲染,并且不要” T'

+1

这是一个相当大的话题,在[隐藏表面确定](http ://en.wikipedia.org/wiki/Hidden_​​surface_determination)。 – 2012-02-16 03:04:20

+4

如果您使用openGL或任何其他3D库,它会在最终渲染中自动执行_culling_。 – toto2 2012-02-16 03:04:44

+0

那么如果我使用opengl,那么添加几何优化不会影响整体性能? – 2012-02-16 04:18:42

回答

7

我看了一下使用JMonkeyEngine,一个3D游戏引擎,回头看看他们使用的一些技巧。从我记忆中,他们使用了一种叫做扑杀的东西。他们构建了“世界”中存在的所有东西的树状结构。那么这个想法就是你有一个这个树的子集,它在任何给定的时间代表可见的对象。换句话说,这些是需要渲染的东西。所以,举例说,我在房间里有一个房间里有物品的房间。房间在树上,房间里的物体是树的孩子。如果我在房间外面,那么我修剪(移除)树的这个分支,这意味着我不渲染它。这个作品如此出色的原因是,我不必评估世界上的每个对象是否应该渲染,而是快速修剪我知道不应呈现的整个世界。

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

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

下面是一些不同的剔除算法,一个有趣的article

  • 视域剔除
  • 基于PVS背面剔除
  • 基于Cell的遮挡剔除
  • 任意几何遮挡剔除
  • 其他
+0

“在这个算法的天真版本中,世界上的每个物体都是针对六个平面进行测试的。”我将如何去执行这样的事情?我对复杂的八叉树结构等没有特别的兴趣。 – 2012-02-16 21:10:50

+3

如果您对执行问题的标准方法并不感兴趣,那么您可能需要调整自己的努力。而不是试图自己做这一切,使用图书馆。有C++中的吨,我知道最好的Java之一是JMonkeyEngine(我上面链接)。 – jbranchaud 2012-02-16 21:17:43

1

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

1

这听起来像你要去一个minecraft-y型的东西。 看看this android minecraft level renderer。 需要注意的几点是:

  • 您只需绘制与透明块共享的块的面。例如:不要在两个不透明的块之间绘制面孔 - 玩家将永远看不到它们。
  • 您可能希望将可见块几何体批量化为块(并将其粘贴到VBO中)并确定每个块的可见性。发现确切可以看出哪些块可能需要更长的时间,而不仅仅是在GPU上抛出VBO并接受透支。
  • 填充效果非常好,可以确定哪些小块可见 - 使用视锥体限制填充,查看方向(如果您面向+ ve x方向,请勿在-ve方向溢出) ,并简单地分析数据块数据(例如:如果一个数据块的整个面不透明,不要通过该面泛滥)
+0

谢谢,洪水填充作品非常好! – 2012-02-20 02:14:51