体素面爬行(简化网格,可能使用贪婪)


9

编辑:这只是出于我自己的学习经验,并不是出于性能原因而问这个问题。

这是关于Minecraft类地形引擎的。我以块的形式存储块(以块的形式存储16x256x16块)。生成块时,我使用多种过程技术来设置地形和放置对象。生成时,我为整个块(是否有实体)保留一个1D数组,并为实体块保留一个单独的1D数组。

生成后,我遍历实体块以检查它们的邻居,以便仅生成没有实体邻居的块面。我将要生成的面孔存储在自己的列表中(这是6个列表,每个可能的面孔/正常面孔一个)。渲染块时,我渲染相机当前块中的所有列表,而所有其他块中仅渲染面向相机的列表。通过将所有6个列表存储在一个缓冲区中来完成此操作,然后只需更改绘制的范围即可。

结合使用2D地图集和Andrew Russell提出的这个小技巧,我想将相似的面孔完全融合在一起。也就是说,如果它们在相同的列表中(相同的标准),彼此相邻,具有相同的光照水平等。我知道我仍然会以矩形结尾,但是这样可以轻松地将我的顶点数减少50%如果我的估计正确的话,还是更好。

我的假设是将6个列表中的每个列表按其所在的轴排序,然后再按其他两个轴排序(块顶部的列表按其Y值,X,Z排序)。

仅此一项,我就可以很容易地合并面带,但我希望尽可能地合并多个面带。我已经阅读了这个贪婪的网格划分算法,但是在理解它时遇到了很多麻烦。

所以,我的问题是:要按照描述的那样进行人脸合并(忽略对动态地形/照明是否是个坏主意),也许有一种算法更易于实现吗?我也很乐意接受一个答案,它以一种更简单的方式(链接或解释)引导我完成贪婪算法。

我不介意如果它更容易实现,甚至比仅做剥离要好一点,性能都会略有下降。我担心大多数算法都将注意力集中在三角形而不是正方形上,并以我的方式使用2D地图集,我不知道我可以根据当前的技能来实现某些三角形。

PS:我已经对每个块都进行了截锥体剔除,并且如上所述,我也剔除了实体块之间的面。我还没有遮挡剔除,可能永远不会。

*编辑:我实现了自己的小技巧,可能有一个名字,但是我只是简单地浏览了我的6个列表,这些列表按照它们所靠的轴,其次是块类型,然后是照明级别进行了排序。我遍历它们,同时创建新的矩形并同时进行扩展(偏向某个轴)。绝对不是最佳选择,但确实非常快,并且确实使我的顶点数平均降低了近50%。Byte56的评论是我认为是真正答案的壁橱,但我不能选择它作为答案/赏金。

这是在生成完整的初始地形后无需进行任何优化的情况下处理此问题的快速简便的方法。假定给定的所有正方形都是相同的图像,光照水平,法线等。每种颜色都是我要渲染的不同四边形。根据我的列表的排序方式,这是一种非常简单/快速的方法。


经过所有优化后,您仍然遇到性能问题吗?您是否尝试过分析代码以查看问题所在?
MichaelHouse

@ Byte56哦,目前绝对不是性能问题。当我尝试将要学到的东西用于真实游戏时,可能是将来的事情。就目前而言,我只是想学习。我没有任何陈述,因为如果我只是想学习东西只是为了学习它们,我似乎得到的帮助就会减少。
Mythics 2013年

我想我也应该说,如果我真的尝试使用这种方法尝试一款合适的游戏,我希望可见的世界变得巨大。我不希望角色像Minecraft和其他很多角色一样高2个方块和1个方块宽,而更喜欢3个宽度/长和6-9高的方块。虽然可能是静态地形。
Mythics 2013年

1
好的,蒂姆。感谢您的解释。我在为游戏制作引擎时对此进行了一些研究。由于我的环境是动态的,因此我认为每次更改某些内容都不会花费性能成本。但是,你可能会发现一些使用文章有关的最大矩形问题。本质上,这是您正在讨论的用于合并相似面孔的算法(可能不是贪婪的,而是最优的)。祝好运!
MichaelHouse

@ Byte56谢谢,我非常感谢。如果没有找到,那肯定看起来更接近我要寻找的算法。我将不得不修补一下,看看是否可以一次运行就获得所有最大的矩形。我可能对此也有所悬赏,因为我认为问题和详细答案都可能在将来对许多其他人有所帮助。
Mythics 2013年

Answers:


4

您只想做条纹,或者最好是做矩形。没有其他形状可以解决或对您有用。

我还要指出的是,每个块保留6个列表,那么在任何时候,您都将沿基数方向使用这些块中的5个列表,而在其他每个方向上至少使用3个列表。您在这里浪费时间,不仅视频卡可以为您做这种优化,而且即使您自己进行了优化,也最好将所有面孔都放在一个位置,然后将法线与方向进行比较。相机(向量的研究DOT乘积)。

您已经看到的CaptainRedMuff在Greedy网格上的链接就是您问题的答案。从上图还可以明显看出,您最终将获得“ Stripy”网格,但是它们非常有效,而采用更优化的网格将更加复杂,并且您已经表示贪婪的网格已经太复杂了。

如果您在单个块上遇到性能问题,那会让我觉得其他事情是大错特错。

我的第一个猜测是您经常调用绘图操作。您只能告诉图形卡每秒绘制50到400〜次,具体取决于硬件。您要拨打.setData或.draw ____ Primitives多少次?


矩形是我想要的。Byte56链接的算法比贪婪要简单得多,但是我不能接受评论作为答案。我以为他发表了评论,因为他只链接到算法而不是解释它。我不知道您对我的清单的意思。我通常每个块有1-2个绘图调用。我的列表存储在每个块一个缓冲区中。我更改每帧要绘制的范围。我可能是错的,但是向GPU发送不必要的数据似乎适得其反。每块额外的一两次抽奖似乎比向gpu发送更多数据并将其强制剔除更好。
神话

我没有性能问题。我只是喜欢学习这些东西。我将编辑我的问题来说明这一点,但是就像我也告诉Byte56一样,如果我尝试做的事情实际上并未解决问题,我得到的帮助也会减少。为了回答您的问题,我目前每帧最多渲染200-260个块。这是每帧相当常见的500ish DrawIndexedPrimitives。我通常不使用vsync就能获得100-130 FPS,每秒可以进行65,000个呼叫。我不是要无礼,但是你对我说的很少。我可能听不懂,所以请您详细解释一下。也许与XNA有关?
神话

啊,对不起,我想说的是每帧而不是每秒。您已经接近那里的上限,并且如果您仅在地形上,则几乎用完了。
菲尔,

我+1了您的答案,因为它的确使我想到了我可以做出的一些改进,但与该问题无关。另外,我认为我应该分享内森·里德(Nathan Reed)关于可能的平局限注链接
Mythics 2013年

我必须找到我读过的文章,该文章引用了400-500作为限制。一个快速的谷歌没有帮助我。
菲尔,

0

您链接到的文章实际上并没有提供生成网格的算法。它说明了一种评估可能解决方案的方法。

不过,总的来说,本文提供了一个很好的总结:1)天真的解决方案不好,2)有一个最佳解决方案,但是编写和运行都非常耗时,3)快速剔除会产生更好的结果( (这是Minecraft本身所做的一切),最后是4)可能会有一个更聪明的解决方案(贪婪算法)。

您在问题图像中暗示的“解决方案” 贪婪算法。您的问题似乎是“我是否正确实施了他的解决方案?” 我必须回答“他没有给出解决方案;您只是自己解决了这个问题”。

您的解决方案可以更好吗?嗯 当然。可能不值得。我认为遮挡剔除或LOD会更好。即使在地下,Minecraft也会浪费大量的周期来绘制表面,而当您处于表面上时,Minecraft会绘制大量的洞穴和矿山系统网络。是的,一旦网状结构破裂良好,那么消除被遮挡的表面可能是一件好事-但是(例如)通常,让您的显卡进行背面剔除比在CPU上更快。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.