Java 三维游戏几何

Java 三维游戏几何,java,c++,geometry,computational-geometry,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会急剧下降。凭直觉,我意识到: 网格中被其他块隐藏的块不需要渲染 不在人视野内的块也不需要渲染(即,位于人后面的块)

我有一个使用3D网格表示的简单游戏,类似于:

Blocks grid[10][10][10];
游戏中的人物由一个点和一个视线向量表示:

double x,y,z, dx,dy,dz;
我使用3个嵌套for循环绘制网格:

for(...) for(...) for(...)
   draw(grid[i][j][k]);
明显的问题是当网格的大小增长到几百以内时,fps会急剧下降。凭直觉,我意识到:

  • 网格中被其他块隐藏的块不需要渲染
  • 不在人视野内的块也不需要渲染(即,位于人后面的块)
我的问题是,给定一个网格,一个人的x、y、z和一个视觉矢量,我怎么知道哪些块需要渲染,哪些块不需要渲染?

我不久前研究了3D游戏引擎,并研究了它们使用的一些技术。根据我的记忆,他们使用了一种叫做淘汰的方法。他们将“世界”中存在的一切构建成一个树状结构。这样做的想法是,您可以得到此树的一个子集,它表示任何给定时间的可见对象。换句话说,这些是需要呈现的东西。比如说,我有一个房间,房间里有物体。房间在树上,房间中的对象是树的子对象。如果我在房间外面,我会修剪(移除)这根树枝,这意味着我不会渲染它。这样做效果很好的原因是,我不必评估世界上的每个对象来查看它是否应该被渲染,而是快速地修剪世界上我知道不应该被渲染的部分

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

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

以下是一些不同剔除算法的有趣示例:

  • 视锥剔除
  • 背面剔除
  • 基于细胞的遮挡剔除
  • 基于PVS的任意几何体遮挡剔除
  • 其他

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

听起来您要做的是minecraft-y类型的事情。 看一看。 需要注意的要点是:

  • 只需绘制与透明块共享的块的面。e、 g:不要费心在两个不透明的方块之间画面——玩家永远看不到它们
  • 您可能希望将可见块几何体批处理为chunklet(并将其粘贴到VBO中),并基于每个chunklet确定可见性。要准确地找出哪些块是可以看到的,可能需要比把VBO扔到gpu上接受透支更长的时间
  • 整体填充可以很好地确定哪些chunklet是可见的-使用视图截锥、视图方向(如果面向+ve x方向,则不要向-ve方向整体填充)和对chunklet数据的简单分析(例如:如果chunklet的整个面不透明,则不要从该面整体填充)

这是一个相当大的主题,在中有详细介绍。如果您使用openGL或任何其他3D库,它会在最终渲染时自动进行剔除。因此,如果我使用openGL,则添加几何优化不会影响整体性能?@tototo2这是一个极为误导/完全错误的说法。剪辑空间之外的对象不会在屏幕上绘制,但它们仍必须通过顶点/几何体处理器。在剪辑空间中但被其他对象遮挡的对象将被视为可见对象进行处理,但最终像素颜色取决于哪个对象的zDepth值最低(即最接近的对象)-但必须对其进行处理才能到达该点。@cbamber85 OK,抱歉。从下面的TreeBranch中看到答案,不是openGL,而是一些更高级别的引擎必须进行筛选。“在这个算法的原始版本中,世界上的每一个对象都是针对六个平面进行测试的。”我如何着手实现这样的东西?我对复杂的八叉树结构不是特别感兴趣,等等。如果你对解决问题的标准方法不感兴趣,那么你可能需要调整你的努力。与其自己尝试做这些,不如使用一个库。C++中有很多,我知道最好的java之一是JMunKEngEngEngy(上面我链接的)。