【问题标题】:Handling blocks in Minecraft-style terrain (d3d/c++)在 Minecraft 风格的地形中处理块 (d3d/c++)
【发布时间】:2012-03-21 04:27:30
【问题描述】:

在由数千个立方体组成的 3d 地形中(即 Minecraft ),在位置和渲染方面处理每个块的方法是什么?更具体地说,我知道在 DirectX 9 中绘制一个立方体的基元并对其进行世界变换可能是一种荒谬的方法,因为存在很多性能问题,所以我想知道更合理的方法是什么。

每个立方体应该是一个多次复制的网格,还是它们是一种从顶点缓冲区中的数据创建适当网格的方法?

我发现this article 介绍了实现我想要实现的东西背后的一些理论,但我以前从未使用过八叉树,所以我无法从源代码中获取太多内容。如果八叉树确实是要走的路,那么学习它们的好起点在哪里?我的大部分谷歌搜索只找到了关于理论的博客文章,很少或没有实现示例。

看起来使用体素在这方面会很有用,但就像使用八叉树一样,我在这里没有经验,所以我真的不知道首先要学习什么。

无论如何,感谢您提供的任何建议\资源\书名。我确信这很明显,但我对 3d 编程还是很陌生,所以非常感谢您的帮助。

【问题讨论】:

    标签: directx minecraft terrain voxel


    【解决方案1】:

    首先,如果您使用 Minecraft 作为参考,请考虑他们对块的使用并将其与 Oct-trees 相关联。 Minecraft 将他们的世界分成更小的块来处理需要存储的大量信息,因此使用 Oct-trees 来组织这些将要存储的数据。 Goz 对 Oct-trees 和 Quad-trees 的工作方式有非常准确的描述,因此请使用他的信息作为参考。

    要考虑的另一件事是,您实际上并不想将每个立方体都绘制到屏幕上,因为这会消耗您的帧速率。使用对象剔除仅将可见立方体绘制到屏幕上。再次,如果您认为 Minecraft;你有没有遇到过可以看穿积木和地下世界的小故障?这是因为 Minecraft 只绘制顶层的方块。屏幕上有这么多对象,使用相机平截头体和遮挡查询来研究对象剔除将是一项值得投资。

    有关使用 DirectX 的信息,我会推荐 Frank Luna 的任何一本书。我自己拥有这本书,在使用 DirectX 编程时它从未离开过我的身边。 http://www.amazon.com/Introduction-Game-Programming-Direct-9-0c/dp/1598220160/ref=sr_1_3?ie=UTF8&qid=1332478780&sr=8-3 我强烈推荐这本书,因为我从中学到了关于 DirectX 的几乎所有知识。

    在 Google 搜索中,我找到了讨论遮挡剔除的链接,因为 Luna 不涉及遮挡剔除,仅涉及截锥剔除。我听说 Programming Gems 系列提到了很多,但我不能亲自证明它的名字。 http://http.developer.nvidia.com/GPUGems/gpugems_ch29.html

    希望这会有所帮助。

    【讨论】:

    • 非常感谢!我听说过弗兰克·卢纳 (Frank Luna) 的书的好消息,所以我想我会花时间通读一遍。顺便说一句,一旦你实现了剔除并且你知道你想要绘制哪些立方体,你是否仍然使用单独的绘制调用一次绘制它们,还是有更好的方法来做到这一点?再次感谢。
    • 对象一次只能绘制一个。如果您有多个对象呈现到屏幕上,请构建一个类来处理它们的信息和一个向量来保存每个对象。将此向量传递到您的渲染循环中,并在调用其渲染函数的 for 循环中遍历每个元素。还有更多方法可以进一步简化这一点,但我会把它留给你来解决。玩弄它并调整代码直到它恰到好处,从来没有任何害处。
    【解决方案2】:

    八叉树相当简单,尤其是像我的工艺中的轴对齐的那些。

    它基本上只是四叉树的 3D 扩展。您可能会发现先了解四叉树会更容易。

    让您快速了解四叉树;基本上你从一个正方形开始。现在想象在那个正方形中放置一个小得多的正方形。如果你想构建一个代表它的四叉树,你首先将原始正方形分成 4 个大小相等的正方形。

    接下来,您检查每个象限,如果较小的正方形在该象限中,则将该象限分成 4 个较小的正方形。然后检查这 4 个象限,选择象限并细分。最终,您的小方块将完全包含在一个或多个象限内象限内的象限内(等)。您现在已经构建了四叉树。

    现在,如果您想像在较大的正方形内搜索特定的正方形,您可以快速看到四叉树的好处。您现在可以检查前 4 个象限以查看它们是否包含它,而不是搜索四叉树中的每个可能的正方形(相当于搜索纹理中的每个像素)。如果有,您可以检查它的 4 个子象限,依此类推,直到找到完全包含您的正方形(或像素)的最小象限。这样一来,您就可以少做很多测试来找到您的对象。

    现在八叉树基本上是相同的东西,但现在不是在正方形中编码正方形,而是在立方体中编码立方体。每个立方体都可以分成 8 个较小的八分圆(因此得名 oct-tree)。

    Oct-trees 的优势在于,通过知道您从哪个 octant 开始,您可以轻松地通过 oct-tree 投射光线以查找碰撞(因为 octant 要么是满的,要么是部分满的,要么是空的)。如果一个八分圆是空的,那么你直接穿过它,然后检查另一边的八分圆。如果它是部分满的,你检查它的子八分圆等等,直到你找到一个完整的八分圆(即你已经击中一个实心立方体并渲染它)或者你完全通过八分圆,因此没有立方体要渲染.这就是我的世界的工作方式(我猜无论如何;))。这也是一种快速渲染体素数据的好方法,如今越来越多的人将其视为未来可能的渲染机制。

    希望对您有所帮助! :)

    【讨论】:

    • 非常感谢,帮了大忙!很清楚的解释。我将首先研究四叉树并从那里开始。
    【解决方案3】:

    八叉树和四叉树对于剔除要渲染的几何体部分很有用。 Minecraft 使用 16x16x16 渲染块将地形分解为可管理的部分。

    另一个需要考虑的技术是实例化。实例化是您告诉 GPU 在不同位置多次渲染对象的地方。它用于人群渲染、树木以及任何几何形状相同但你有很多的东西。

    http://msdn.microsoft.com/en-us/library/windows/desktop/bb173349(v=vs.85).aspx

    http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter03.html

    这是一篇文章,作者在 OpenGL 4 中复制了 minecraft 渲染器。虽然代码不适用于您的案例,但可以将技术(剔除被包围的立方体等)应用于 directx 渲染器。

    http://codeflow.org/entries/2010/dec/09/minecraft-like-rendering-experiments-in-opengl-4/

    不要被块状图形和低质量纹理所迷惑。 Minecraft 是一个极其复杂的渲染器,您需要想出方法来处理所涉及的大量项目。例如,即使是世界的“小”部分,比如 100x100x100 块也是 100 万块。将每个块作为单独的网格推送到 GPU 会杀死你的 GPU。当您深入了解这项技术时,Minecraft 渲染器比大多数第一人称射击游戏要复杂得多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      相关资源
      最近更新 更多