怎么办脸上去除单位立方体世界的一拉我的世界? [英] How to do face removal in a unit-cube world a la Minecraft?

查看:165
本文介绍了怎么办脸上去除单位立方体世界的一拉我的世界?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

重要提示:这个问题是不是几何剔除这个问题是关于几何学的取消的(平截剔除,背面剔除,遮挡剔除或他们的朋友。)在设定时间,很久以前我们开始扑杀和渲染。

Important note: This question is NOT about geometry culling (frustrum culling, back face culling, occlusion culling or any of their friends.) This question is about geometry elimination at set-up time, long before we get to culling and rendering.

在一个单元立方体呈现的世界(一拉的我的世界),我试图找出如何从我的几何面列表不可能从任何角度看到的删除算法,无论身在何处的摄像头。

In a unit-cube rendered world (a la MineCraft), I'm trying to find algorithms for how to remove from my list of geometry faces that can't possibly be seen from any angle, no matter where the camera is.

例如,假设2格:

+----+      +----+
|    |      |    |
|    |      |    |
+----+      +----+

显然有(每平方米4)8可见双方现在我将广场一起的显示的:

+----+----+
|         |
|         |
+----+----+

而不是有8条边,现在我只有6!这都在触摸在中间的两个都看不出来,无论身在何处的摄像头被放置,也没有什么角度它正面临着。 (正方形的纹理不同,所以我们不能把它4个侧面。)

Rather than having 8 sides, now I only have 6! The two that are touching in the middle can't be seen, no matter where the camera is placed, nor what angle it is facing. (The squares are textured differently, so we can't call it 4 sides.)

(同样的事情在工作与3D立方体,但12面(6每立方)成为10为2动人的被淘汰。)

(The same thing works in 3D with cubes, but 12 faces (6 per cube) become 10 as the 2 touching are eliminated.)

我的问题是:什么是一些算法,帮助我认识到这些隐藏的面孔? (我很高兴做我自己的谷歌搜索,但我甚至不知道这是什么所谓的!)尤其是,我正在寻找的东西,处理空心点在中间 - 这点可以看到,如果你是在那里,但是,因为它们是由几何形状包围,你看不到它们。

My question is: what are some algorithms that help me to recognize these hidden faces? (I'm happy to do my own Googling, but I don't even know what this is called!) In particular, I'm looking for something that handles hollow spots in the middle -- spots which COULD be visible if you were in there but, because they're surrounded by geometry, you can't see them.

例如:

+----+----+----+----+
|                   |
|                   |
+    +----+         +
|    |    |         |
|    | A  |         |
+    +----+         +
|                   |
|                   |
+----+----+----+----+

在这种情况下,人们可能会认为有18看得见的两侧,但因为我们知道一个事实,即相机的几何形状外,在广场上的4边A是不可见的。

In this case, one might think there 18 "visible" sides but, because we know for a fact that the camera is outside of the geometry, the 4 sides in square "A" aren't visible.

要进一步复杂化的东西,我希望能找到一个算法,如果一个块被添加或删除,可以使快速更新(同样的一拉的我的世界。)

To further complicate things, I'm hoping to find an algorithm that can make quick updates if a block is added or removed (again, a la MineCraft.)

谢谢!

推荐答案

你的问题的第一部分是很简单的。对于每个立方体,如果是直接相邻的另一个立方体,你删除它与立方体共享的脸。

The first part of your question is really quite simple. For each cube, if it is directly adjacent to another cube, you remove the face it shares with that cube.

这是不是这应该是一个性能问题(修改并上传改变的顶点数据的成本之外),因为你只会重新计算这个当块被放置或删除。放置和取出块的作用是相当地方;它只会影响6相邻的立方体,本身,因此它不应该是一个问题。你也不需要任何专门的数据结构,较明显的人,你需要处理一个立方体为基础的环境等。

This is not something that should be a performance issue (outside of the cost of modifying and uploading the changed vertex data), since you will only recompute this when a block is placed or removed. The effects of placing and removing a block are quite local; it will only affect the 6 neighboring cubes and itself, so it shouldn't be a problem. You also don't need any specialized data structures, other than the obvious ones you need to handle a cube-based environment.

建筑地形的初始成本可能是一些,但是这是一个你能忍受的一次性成本。它的因素到你的加载时间。如果你做了很多安置和清除在框架的空间,这可能是一个问题。

The initial cost of building the terrain may be something, but that's a one-time cost that you can live with. Factor it into your loading time. If you're doing a lot of placements and removals in the space of a frame, it could be an issue.

更棘手的问题是消除密封的室内设计。我的建议:这是不值得的。通过试图除去密封室内,放置或移除块变为非本地操作。你会通过花费时间去优化你的批次数(使用纹理地图/阵列,其中可能的话),你的顶点数据可能得到更高的性能。

The more difficult issue is removing sealed interiors. My suggestion: it's not worth it. By trying to remove sealed interiors, placing or removing a block becomes a non-local operation. You would probably get more performance by spending time optimizing your batch count (use texture atlases/arrays where possible) and your vertex data.

要删除密封的内饰,你需要能够检测室内设计。因此,你需要保持相邻面的双向曲线图。对于每个面,则其四个相邻的面。该被宰杀,因为它是两个相邻的立方体(此前称为死面)不应当是图形的一部分。之间的面

To remove sealed interiors, you need to be able to detect interiors. And therefore, you will need to maintain a bidirectional graph of adjacent faces. For each face, it will have four adjacent faces. Faces that were culled because it was between two adjacent cubes (heretofore referred to as "dead faces") should not be part of the graph.

在一个立方体的放置位置,则必须更新邻接信息为面图。死面需要被去除。放置后邻接现场面需要结合添加由于被放置在新块的新面孔。该算法要做到这一点应该是相当简单的,如果你坐下来,映射出的可能性。例如,如果您有这方:

When a cube is placed, you must update the adjacency information for the face graph. Dead faces need to be removed. The adjacency for live faces after placement needs to incorporate the new faces that were added due to the new block that was placed. The algorithm to do this should be fairly straightforward if you sit down and map out the possibilities. For example, if you have this square:

  A
+++++
+   +
+   + B
+   +
+++++

的面A和B是相邻的。如果将一个新块,你改变邻接:

The faces A and B are adjacent. If you place a new block, you change the adjacency:

     +++++
     +   +
   C +   +
     +   +
  A  +++++
+++++  D
+   +
+   + B
+   +
+++++

A现在毗邻C和B相邻到D。

A is now adjacent to C and B adjacent to D.

在一个多维数据集被删除,则必须再次更新邻接信息为面图。从本质上讲,你要扭转previous操作。

When a cube is removed, you must again update the adjacency information for the face graph. Essentially, you have to reverse the previous operation.

此邻接图的点是这样的:如果所有的非死面的连接图形中,然后准确图形的一个周期将是可见的;所有其他图形的周期将不可见。该图是一个基面,它们都相互连接,无论是直接或间接的循环

The point of this adjacency graph is this: if all of the non-dead faces are connected in the graph, then exactly one cycle of the graph will be visible; all other graph cycles will not be visible. A cycle of the graph being a group of faces that are all connected to one another, either directly or indirectly.

最大的问题是:你是怎么找到可见的周期?以下算法假定块放置/由实体除去。这意味着至少有一个面被放置任何块是可见的。这也意味着,任何死面孔成为现场去除块是可见的。

The big question is this: how do you find the visible cycle? The following algorithm assumes that blocks are placed/removed by an entity. This means that at least one face of any block that is placed is visible. It also means that any dead faces that become live by removing a block are visible.

当你把块,您可以创建面中的一个或多个新的周期。为了检测这一点,你首先发现所有的非亡灵面(那些不直接相邻的东西),您已通过将块中创建的。的至少一个的这些将是可见的;发现的脸。

When you place a block, you may create one or more new cycles of faces. To detect this, you first find all of the non-dead faces (the ones that aren't directly adjacent to something) that you have created by placing the block. At least one of these will be visible; find that face.

然后,对于新的块上的其他非死人脸,使用A *(A星)图形搜索,找到那张脸。 A *是一个优先级队列为基础的图形搜索算法。在这种情况下,该算法的距离是正方形,当前面是上和平方之间的距离,该可见表面是上

Then, for every other non-dead face on the new block, use an A* (A-star) graph search to find that face. A* is a priority-queue-based graph search algorithm. In this case, the "distance" for the algorithm is the distance between the square that the current face is on and the square that the visible face is on.

如果在A *找不到的脸,那么你知道你搜索到(你应该把它们存储在缓冲区中,你对它们进行测试),每个人脸上是一种不可见周期的一部分,因此可以被剔除。您应该标记这些面孔作为不可见,供日后参考。

If the A* cannot find the face, then you know that every face that you searched through (you should probably store them in a buffer as you test them) is part of a non-visible cycle and can therefore be culled. You should mark these faces as being non-visible for later reference.

删除块要容易得多。当你删除块中,至少一个面块必​​须是可见的(见上面的假设)。因此,如果该块将被删除了一些不可见的面,在一个周期包括非可视面每面必须变得可见。所以删除块之前,检查是否有不可见的面孔。如果有任何,使用深度优先搜索查找所有在该周期的脸,并把它们放在一个缓冲区。一旦你删除块,所有这些面孔现在变得可见。

Removing a block is much easier. When you're removing a block, at least one face of the block must be visible (see the assumption above). Therefore, if the block to be removed had some non-visible faces, every face in a cycle including those non-visible faces must become visible. So before removing the block, check it for any non-visible faces. If there are any, use a depth-first search to find all of the faces in that cycle, and put them in a buffer. Once you remove the block, all of those faces now become visible.

现在,如果你能瞬移块,事情变得更加复杂。当你把块,有机会,没有该块的脸是可见的。所以,你需要做的是找到在世界上是可见的面部的地方的。然后做你的A *搜索对那张脸是正常的。这将是一件好事,如果可见面是附近某个地方,所以搜索没有走的太远。

Now, if you're able to teleport blocks, things become more complex. When you place a block, there is the chance that none of that block's faces are visible. So what you need to do is find a face somewhere in the world that is visible. Then do your A* searching towards that face as normal. It would be good if the visible face were somewhere nearby, so the search didn't have to go too far.

通过去除,你所要做的就是找​​到所有相邻块中的不可见的面部循环。然后,你需要找到一个可见的脸前。然后你删除块和搜索这些周期与A *,看看他们是否能找到可见面。这些周期可以是可见的。这些周期无法不可见。

With removal, what you have to do is find all of the non-visible face cycles adjacent to the block. Then you need to find that one visible face as before. Then you remove the block and search those cycles with A* to see if they can find the visible face. Those cycles that can are visible. Those cycles that cannot are not visible.

此外,还需要有一个特殊的情况用于去除块没有活的面(即:完全嵌入在其它块)。这产生了6面周期是不可见的。

Also, you need to have a special case for removing a block that had no live faces (ie: is fully embedded in other blocks). This creates a 6-face cycle that is non-visible.

也许现在你明白为什么它可能不是值得努力?说实话,除非你手上的实际分析数据表明,你需要这个,我的强烈劝你不要去追求的。你很可能会使得更多的工作需要,以及可能对一些无关紧要的花费了大量的时间。

Perhaps now you see why it's probably not worth the effort? Honestly, unless you have actual profiling data in hand that shows that you need this, I strongly advise you not to pursue that. You will likely be making more work than necessary, as well as potentially spending a lot of time on something irrelevant.

现在,我写这个帖子即兴;我想最简单的算法,我可以将工作的。我还没有研究能够改进算法,像preemptively找块展示位置可以创造的内饰,或者找到块,如果删除将成为一个内部可见。因此,我坦率地承认,这种算法是pretty的蛮力。但要找到一个更好的,需要一些努力,如此反复,除非您已在曾说,您分析数据需要要做到这一点,以达到你想要的表现,我建议反对。

Now, I wrote this post off the cuff; I thought of the simplest algorithm I could that would work. I have not researched possible improvements to this algorithm, like preemptively finding block placements that could create interiors, or finding blocks that if removed would make an interior visible. So I freely admit that this algorithm is pretty brute force. But finding a better one will require some effort, so again, unless you have profiling data in had saying that you need to do this to achieve the performance you want, I advise against it.

这篇关于怎么办脸上去除单位立方体世界的一拉我的世界?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆