我有一个使用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
,我怎么能找出需要渲染哪些块而哪些块不需要渲染?
答案 0 :(得分:7)
我研究过使用JMonkeyEngine,一个3D游戏引擎,不久前看了一下他们采用的一些技术。从我记忆中,他们使用了一种叫做剔除的东西。他们构建了“世界”中存在的一切树形结构。接下来的想法是,您拥有此树的一个子集,可以在任何给定时间表示可见对象。换句话说,这些是需要渲染的东西。所以,比方说,我在房间里有一个房间里有物品。房间在树上,房间里的物品是树的孩子。如果我在房间外面,那么我修剪(删除)树的这个分支,这意味着我不渲染它。这样做的原因很好,我不需要评估世界上的每个对象,看它是否应该渲染,而是我快速修剪我知道不应该渲染的世界的所有部分。
更好的是,当我走进房间时,我从树上修剪整个世界,然后只渲染房间及其所有后代。
我认为JMonkeyEngine团队制作的很多设计决策都是基于David Eberly的书3D Game Engine Design中的内容。我不知道如何实现这样的方法的技术细节,但我敢打赌这本书对你来说是一个很好的起点。
对于一些不同的剔除算法,这是一个有趣的article:
答案 1 :(得分:1)
首先你需要一个空间分区结构,如果你使用统一的块大小,最有效的结构可能是octree。然后,您需要编写一个算法,该算法可以计算框是否位于平面的特定一侧(或相交)。一旦你有了,你就可以计算出八角树的哪些叶节点位于视锥体的六个边内 - 那就是视图剔除。同样使用八叉树,您可以确定哪些块遮挡了其他块(有时称为视锥体遮罩),但首先使第一部分工作。
答案 2 :(得分:1)
这听起来像是在寻找类似Minecraft-y的东西。 看看this android minecraft level renderer。 需要注意的要点是: