C# 在XNA 4.0中绘制大量纹理立方体

C# 在XNA 4.0中绘制大量纹理立方体,c#,xna,C#,Xna,我试图在XNA4.0中编写一个定制的Minecraft经典多人客户端,但当涉及到在游戏中实际绘制世界时,我完全被难住了。每个块在三维空间中都是一个立方体,它的每一侧都可能有不同的纹理。我一直在网上阅读,发现立方体的每一面都有不同的纹理,每个面都需要自己的顶点集。这使得每个立方体总共有24个顶点,如果你有一个由64*64*64个立方体(或者更多)组成的世界,那么会产生很多顶点 _ _ _ _ |_|_| == |_ _| 在我的原始代码中,我将纹理贴图拆分为单独的纹理,并在绘制每个立

我试图在XNA4.0中编写一个定制的Minecraft经典多人客户端,但当涉及到在游戏中实际绘制世界时,我完全被难住了。每个块在三维空间中都是一个立方体,它的每一侧都可能有不同的纹理。我一直在网上阅读,发现立方体的每一面都有不同的纹理,每个面都需要自己的顶点集。这使得每个立方体总共有24个顶点,如果你有一个由64*64*64个立方体(或者更多)组成的世界,那么会产生很多顶点

 _ _      _ _
|_|_| == |_ _|
在我的原始代码中,我将纹理贴图拆分为单独的纹理,并在绘制每个立方体的每一侧之前应用这些纹理。我被告知这是一种非常昂贵的方法,我应该将纹理保存在同一个文件中,只需使用UV坐标将某些子纹理映射到立方体上。但这对性能没有多大影响,因为顶点的数量实在太多了。我还被告知在VertexBuffer中收集顶点并一次绘制所有顶点,但这也没有多大帮助,当顶点数量超过缓冲区的最大大小时,偶尔会导致异常。我试图让立方体共享顶点的任何尝试也失败了,导致了巨大的减速和立方体的故障

我不知道该怎么办。一般来说,我很擅长编程,但任何类型的3D编程或游戏开发我都完全不懂

这是我用来画立方体的方法。我有两个全局列表,一个用于顶点,一个用于索引。在绘图时,我迭代世界上所有的立方体,并对那些不是空的立方体(如空气)进行渲染。我拥有的形状类粘贴在下面。AddVertices方法中的注释代码试图使多维数据集共享顶点。将所有立方体的顶点添加到列表中后,数据将粘贴到VertexBuffer和IndexBuffer中,并调用DrawIndexedPrimitives

老实说,我可能做得完全错误,但我真的不知道如何做,也没有教程真正描述如何绘制大量对象,只有非常简单的对象。我必须想出如何重做的基本形状有几个纹理自己

形状:

要加快速度,您可以做很多事情:

您要做的是将一个立方体区域烘焙到顶点缓冲区中。我的意思是把所有的立方体放在一个小区域里,然后把它们放在一个顶点缓冲区中。仅在多维数据集更改时更新此缓冲区

在像minecraft这样的世界里,许多人脸相互遮挡。你能做的最大的事情就是隐藏两个立方体之间共享的面。想象两个立方体紧挨着坐着,你真的不需要在它们之间画一张脸,因为它永远都看不见。在我们的引擎中,这导致顶点减少了20倍

 _ _      _ _
|_|_| == |_ _|
至于你的纹理,就像你说的,使用纹理图谱是个好主意。这将大大减少您的抽签调用


祝你好运!如果你想作弊,看看Infiniminer。Infiniminer是基于minecraft的游戏。它是用XNA编写的,并且是开源的

我认为Minecraft不会一直绘制所有的立方体。它们大部分是内部的,你只需要在表面上画。因此,基本上,您需要一个高效的渲染器。

您需要考虑减小问题的大小。你怎么能用更少的工作来产生相同的图像

如果立方体以固定间隔隔开且大小相同,则可能根本不需要存储顶点-着色器可以在运行时计算顶点位置。如果它们的大小不同,且间隔不固定,则仍可以将它们用于onf实例化(在onf实例化中,您将立方体的位置和大小提供给着色器,并确定在何处渲染顶点以使立方体显示在该位置)


如果你的立方体遮住了它们后面的任何东西,那么你只需要画最前面的立方体——它们后面的任何东西都是看不见的。一种自然的方法是使用八叉树数据结构,将三维空间划分为体素(立方体)。使用八叉树,您可以快速确定哪些立方体是可见的,只需绘制这些立方体-因此,与绘制64x64x64立方体相比,您可能发现每帧只需绘制几百个立方体。您还将发现,随着相机的移动,可见立方体集不会发生太大变化,因此您可以使用这种“时间一致性”来更新数据结构,以最大限度地减少确定哪些立方体可见所需的工作。

您可以获得我与其他几个名为TechCraft的开发人员编写的代码副本:


它是免费和开源的。它应该向您展示如何创建一个类似于Minecrafts的引擎。

我最近在XNA中编写了一个引擎来实现这一点,您要研究的技术称为硬件实例化,它允许您将一个模型传递到着色器中,并将一系列世界位置“实例化”该模型数百次(甚至数千次)遍布你的游戏世界

我在这个示例的基础上构建了我的引擎,用我自己的模型替换实例模型

一旦你把它变成一个可重用的类,它和它附带的着色器就变得非常有用,可以渲染成千上万的你想要的东西(灌木丛、树木、立方体、成群的鸟等等)


一旦你有了一个基础模型(可以是块的一面),它的网格将有一个关联的纹理,你可以用任何你想要的东西来替换它,让你可以动态地改变每一面和不同类型的块的纹理。

我要做的是检查一个立方体是否被其他不透明立方体包围,然后跳过这个立方体,因为它不会