在Minecraft的多维数据集世界中,如何进行面部去除?

| 重要说明:这个问题与几何图形剔除(视锥细胞剔除,背面剔除,遮挡剔除或他们的任何一个朋友)无关。此问题与设置时间(在我们开始进行剔除和渲染之前)的几何消除有关。 在一个单位立方体渲染的世界(la MineCraft)中,我试图找到一种算法,该方法如何从我的几何面列表中删除无论从何处相机都无法从任何角度看到的几何面。 例如,假设2个正方形:
+----+      +----+
|    |      |    |
|    |      |    |
+----+      +----+
显然有8个可见的边(每个正方形4个)。现在我将正方形一起移动,如下所示:
+----+----+
|         |
|         |
+----+----+
现在我只有6个面,而不是8个面!无论将相机放置在什么位置,也不要面对相机所面对的角度,都看不到中间的两个接触点。 (正方形的纹理不同,因此我们不能将其称为4边。) (同样的东西在带有立方体的3D中也起作用,但是由于消除了2个接触,所以12个面(每个立方体6个面)变为10个。) 我的问题是:什么算法可以帮助我识别这些隐藏的面孔? (我很乐意自己进行谷歌搜索,但我什至不知道这叫什么!)特别是,我正在寻找能够处理中间空心点的东西-可以看到的斑点如果您在其中,但是由于它们被几何图形所包围,则看不到它们。 例如:
+----+----+----+----+
|                   |
|                   |
+    +----+         +
|    |    |         |
|    | A  |         |
+    +----+         +
|                   |
|                   |
+----+----+----+----+
在这种情况下,人们可能会认为那里有18个“可见”侧面,但是,因为我们知道摄像头不在几何图形之外,所以正方形“ A”中的4个侧面是不可见的。 为了进一步使事情复杂化,我希望找到一种算法,如果添加或删除了一个块,该算法可以进行快速更新(同样是la MineCraft。) 谢谢!     
已邀请:
您问题的第一部分确实非常简单。对于每个多维数据集,如果它直接与另一个多维数据集相邻,则删除与该多维数据集共享的面。 这不是性能问题(修改和上传更改的顶点数据的成本之外),因为只有在放置或删除块时才会重新计算。放置和删除块的影响是非常局部的。它只会影响6个相邻的多维数据集及其本身,因此这不是问题。除了处理基于多维数据集的环境所需的显而易见的数据结构外,您也不需要任何专门的数据结构。 构建地形的初始成本可能会有些高,但这是您可以忍受的一次性成本。将其计入您的加载时间。如果要在一个框架的空间中进行大量的放置和移除,则可能是一个问题。 更困难的问题是移除密封的内部。我的建议:这不值得。通过尝试移去密封的内部空间,放置或移走砖块成为非本地操作。花时间优化批处理数量(可能时使用纹理图集/阵列)和顶点数据,可能会获得更高的性能。 要移除密封的内部,您需要能够检测内部。因此,您将需要维护相邻面的双向图。对于每个面,它将有四个相邻的面。由于位于两个相邻的立方体之间而被剔除的面(以前称为“死面”)不应成为图形的一部分。 放置多维数据集后,必须更新面部图的邻接信息。需要去除死角。放置后活体的邻接需要合并由于放置了新块而添加的新脸。如果您坐下来并确定可能性,执行此操作的算法应该非常简单。例如,如果您有这个正方形:
  A
+++++
+   +
+   + B
+   +
+++++
面A和B相邻。如果放置新的块,则更改邻接关系:
     +++++
     +   +
   C +   +
     +   +
  A  +++++
+++++  D
+   +
+   + B
+   +
+++++
现在,A与C相邻,B与D相邻。 删除多维数据集后,必须再次更新面部图的邻接信息。本质上,您必须撤消之前的操作。 该邻接图的要点是:如果所有非死面都在图中连接,则该图的一个周期将是可见的。所有其他图形周期将不可见。图的循环是一组直接或间接彼此相连的面。 最大的问题是:如何找到可见的周期?以下算法假定块是由实体放置/删除的。这意味着所放置的任何块的至少一个面是可见的。这也意味着可以看到通过移除块而变得活跃的任何死角。 放置块时,可以创建一个或多个新的面循环。为了检测到这一点,您首先要找到通过放置块而创建的所有非死脸(与某物不直接相邻的人)。至少其中之一是可见的;找到那张脸。 然后,对于新块上的每个其他非死脸,使用A *(A星)图搜索找到该脸。 A *是基于优先级队列的图搜索算法。在这种情况下,算法的“距离”是当前人脸所在的正方形与可见人脸所在的正方形之间的距离。 如果A *无法找到人脸,则说明您搜索过的每个人脸(在测试它们时都应将它们存储在缓冲区中)是不可见循环的一部分,因此可以将其剔除。您应将这些面孔标记为不可见,以备日后参考。 删除块要容易得多。删除块时,该块的至少一个面必须可见(请参见上面的假设)。因此,如果要删除的块具有一些不可见的面,则循环中的每个面(包括那些不可见的面)都必须变为可见。因此,在移除块之前,请检查其是否存在任何不可见的面。如果有的话,请使用深度优先搜索来查找该循环中的所有面孔,并将它们放入缓冲区中。删除块后,所有这些面现在都可见。 现在,如果您能够传送积木,事情将会变得更加复杂。当您放置一个块时,该块的所有面孔都不可见。因此,您需要做的是在世界上某个可见的地方找到一张脸。然后像平常一样朝着那张脸做A *搜索。如果可见的脸部在附近某个地方会很好,因此搜索不必走得太远。 移除后,您要做的是找到与该块相邻的所有不可见面循环。然后,您需要像以前一样找到一张可见的脸。然后,删除该块并使用A *搜索那些循环,以查看它们是否可以找到可见的面孔。那些可见的周期。那些不可见的循环。 另外,您需要有一个特殊情况来删除没有活脸的块(即:完全嵌入其他块中)。这将创建一个不可见的6面循环。 也许现在您知道为什么不值得付出努力了吗?老实说,除非您掌握的实际分析数据表明您需要此数据,否则我强烈建议您不要这样做。您可能会进行不必要的更多工作,并可能在无关紧要的事情上花费大量时间。 现在,我袖手旁观地写了这篇文章;我想到了最可行的算法。我尚未研究此算法的可能改进,例如抢先查找可以创建内部的砌块放置,或查找如果删除就可以使内部可见的砌块。因此,我自由地承认此算法是蛮力的。但是,找到一个更好的解决方案将需要一些努力,因此,再次提醒您,除非您对数据进行概要分析,否则您必须这样做才能达到所需的性能,但我建议您不要这样做。     

要回复问题请先登录注册