Metaverse 101 (1/n) 程序化宇宙生成

Overview

如果有可能的话,我会把 Metaverse 相关的技术材料形成一个系列,目前先把这一篇作为第一篇吧。

Metaverse 101 (1/n) 程序化宇宙生成

今天早上读 《This will make you smarter》 的第二章 Living is fatal 时,无意间看到作者 Seth Lloyd 写过一本书叫 《Programming the Universe》,引起了我的兴趣。 Google 了下,这本书大约是在讲 “宇宙是一台超大的量子计算机”。没找到原书,但找到了作者 讲解这个想法的 ppt,翻了下看不懂,去 Youtube 上找到了作者讲解的视频。还没来得及看,被另一个同名视频 Procedural Generation: Programming The Universe 成功引起了兴趣,内容是关于如何程序化地生成一个宇宙,是我看过的宇宙生成的所有例子里最浅显最通俗的,作者讲得很好,我顺手记了下,于是有了这篇帖子。

javidx9 老兄是一个很好的讲解者。整个讲解层层递进,信息密度均匀,非常舒服地一路听完,是教科书级的讲解视频,正好我前段时间也对视频内容创作这块有兴趣,顺便学到不少细节 (所有需要敲代码的地方都复制粘贴快速完成;通过第一人称和第三人称的切换来达到讲述情境切换和旁白的目的)。这里现学现卖,下面的讲述直接切到第一人称。

“自动化生成” 与 “程序化生成” 的区别

在开始讲解细节前,我们先做一个区分:关于 “自动化生成” 与 “程序化生成” 的区别:

Minecraft 和 rogue-like 类游戏并非是 procedural generation 而只是 automated generation。

为什么呢?因为所有生成好的数据被存了下来,在实际运行时,直接读取的生成好的数据。这被认为是自动化生成。

而程序化生成是不同的,总是在资源被看到或被用到时才动态地即时被创造出来 (It’s generating the resources as required on-the-fly and consistently each time.)

这个区别非常重要,因为如果你想要在有限的内存和存储空间内得到一个接近无限的世界,光靠离线存储的自动化生成是不够的。

理想情况下,我们不应存储任何数据,而总是通过代码动态生成需要的细节。

随机性

仅有随机性是不够的,我们需要的是对随机性的充分控制。 (Randomness on its own is not enough to create compelling resources. We need to control the randomnesses in such a way that makes our application sensible.)

从最简单的 rand() / srand() 开始,常规用法,调一次 srand 然后多次 rand 来生成多个恒星位置。这种情况下,想要获取指定恒星的位置,需要把它之前的所有恒星全部生成一遍,实践中性能不可接受。

那么根据每个坐标点的位置来设置种子 srand(y << 16 | x),这样每个坐标都不一样,而且可以快速且确定性地得到某个坐标的随机值。性能上满足要求了,但是,这时候屏幕上产生了规律的条带,完全不随机了,这说明随机值跟 srand 相关性太强,C 语言的 rand/srand 不够用了。

换用 C++ 的 std::19937 吧,这下随机性够了,但设置种子这个动作太费了,200K 像素点花了 400ms,游戏中随时生成的话是不可接受的。

换了 Lehma 的随机数生成,这下性能和随机性都有保障了。

关于随机,正好想起此前记录的关于确定性 GUID 生成的一个实践,顺便记在这里:

稀疏性和层次细节

关注稀疏性。为了让系统展现出区域性的特征,可以让随机数的稀疏性与所在坐标建立相关性。

然后是恒星的尺寸,颜色,行星和卫星数量等细节因素,需要注意两个点:

  1. 对于每一次生成过程而言,所有这些细节要有相同的生成顺序。
  2. 通过立即返回,使得系统总是可以停在恰当的层次细节上,避免无谓的细节生成。

坐标变换与交互

然后,我们讲解了从屏幕坐标到整个宇宙坐标的变换,使得用户可以通过键盘鼠标的交互来向四个方向上观察任意给定的区域,同时可以看到占用的系统资源 (mem/cpu) 是基本恒定的。

最后,我们花了点时间,把上面生成的各种细节以可视化的方式表现出来,当用户选择任意给定的恒星时,都可以显示这个恒星系内的具体情况。

视频中的内容到这里就结束了,可以看出这是一个比较初级的内容。更高级的内容,后续再补充。

附:

(完)


  • 顾露 (Gu Lu) 于免成居
  • 时间: 2021-06-18
  • 编号: Dm-001-2106