无限滚动 3d 地图

Endless scrolling over a 3d map

我对 Metal 有一些经验,对 Unity 也有一些经验,并且熟悉设置网格、缓冲区和绘图的支持数据;但 math/shader 方面没有那么多。我正在苦苦挣扎的是如何获得一个无尽的滚动世界。因此,如果我向右侧平移很远,我可以看到左侧并继续前进。

这将是一个无缝地形的应用,玩家可以永远向任何方向滚动并让它只是环绕。

我不想复制绘图上的所有内容并对其进行偏移,这看起来效率极低。我希望有一种方法可以使用一些神奇的矩阵数学或某种着色器来获得东西 wrapping/drawing 在平移地图时他们应该在哪里。我到处搜索了某种指南或解释如何使它工作但没有想出任何东西。

我知道很多旧的 (dos) 游戏都以某种方式做到了这一点,现在还有可能吗?行业似乎已经从这种类型的滚动中迁移出来(边界到边缘与环绕)有什么原因吗?

我创建了一个 simple example 来展示您正在寻找的内容(我认为)。

它的基本思想是使用 MTLRenderCommandEncoder 上的 drawPrimitives(type:vertexStart:vertexCount:instanceCount:) 方法在重复网格中绘制地图。作为实例计数,您要传入要绘制的相同地图的数量,根据需要将其扩展到看不到结束的位置。在我的示例中,我使用了一个简单的 5x5 网格。

为了不让用户看到地图的边缘,我们将计算他们的位置模 1(或您的地图的任何大小):

func didDrag(dx: CGFloat, dy: CGFloat) {
    // Move user position on drag, adding 1 to not get below 0
    x += Float(dx) * draggingSpeed + 1
    z += Float(dy) * draggingSpeed + 1

    x.formTruncatingRemainder(dividingBy: 1)
    z.formTruncatingRemainder(dividingBy: 1)
}

这是它的样子:

只是对我实际实施的内容进行跟进。首先,我基本上有一个包含高度、地形类型和所有爵士乐的 x、y 点数组。使用一些简单的 % 和 additions/subtractions 让节点围绕一个点生成三角形

是微不足道的

在平局中,我计算第一个显示点和最后一个显示点,并计算这些点之间显示的三角形组。 first/last 点考虑了环绕,那么拥有一个无限环绕的世界就变得非常微不足道了。对于每个组,平移偏移量通过该组的统一矩阵传递,该矩阵将将该部分定位在它应该属于的位置。

我通过renderEncoder.setVertexBytes(&uniform, length:..., offset:...)

设置