泛化沃利噪声
沃利噪声是一种在计算机图形学中用于程序化纹理的噪声类型。在其最基础的形式下,它看起来是这样的:
虽然效果难看又枯燥,但这种方式却能快速直观地展示出该效果的最终呈现效果。如果我们利用沃利噪声来扭曲一个三维形状,就能得到类似锤纹或坑洞状的纹理:
与许多程序化纹理一样,如果将这一效果重复多次、并采用不同的频率进行渲染,其视觉效果会更加出色:
这些渲染结果中存在一些视觉伪影,因为它们使用的是对沃利噪声的快速近似算法,在某些数值上会产生错误的结果。
虽然这种效果并不十分令人满意,但要弄清这些伪影的来源,我们首先需要了解沃利噪声的工作原理。
它的实现其实非常简单:我们从一个点阵开始。
然后,我们将每个点按照一定的随机偏移量进行移动:
在编写着色器时,我们无法真正生成随机数,因此我们借助哈希函数,根据每个点的逻辑位置(即, 中心点的坐标为 $i = [0 0],右侧的点的坐标为 $i = [1 0] 等)来生成看似随机的偏移量。
最后,当所有点都位于看似随机的位置后,我们就可以计算输入图像中每一个像素到最近点的距离——而这正是沃利噪声的计算过程。
那么,对于任意一个像素,我们该如何计算到最近点的距离呢? 其实很简单:我们知道,我们最初所构建的是一张完全均匀的方格网格。 对于任何一个像素,我们都可以计算出该像素所属的“网格单元”([0 0]、[0 1] 等)。只需将该像素的坐标除以网格的尺寸,再取最接近的整数即可。
此外,我们还知道,最近的点要么位于这个网格内,要么位于紧邻的某个网格中——因为我们只对点进行最多等于网格尺寸一半的偏移,所以每一个随机分布的点依然处于其原始网格单元之内。这意味着,没有任何一个点会位于其他任何网格单元内,而那个点又可能比相邻网格中的任意一点更近。 这样一来,你只需要检查九个点,就能为着色器中的每一个像素提供准确的计算结果。而造成视觉伪影的优化方法在于:与其检查全部八个相邻点,不如只检查距离最近的三个点。你的采样点附近的最近点很可能就位于其中某一个网格单元内,但未必一定如此;因此,一旦运气不佳,你就会不可避免地遇到一些视觉伪影。
在二维场景中,将检查点的数量从 9 个减少到 4 个已经是一个不错的改进;但在三维场景中,这种优化会将检查点数量从 27 个降至 8 个,这甚至可能成为实时渲染与离线渲染之间的关键差异。
不过请注意:事情变得有点复杂了。而我之前展示给你的那段原始代码,其实并没有多么复杂:
这段代码中根本未涉及网格单元的坐标计算,也未进行最近点的判断。 我只是简单地构造出了这个东西,说出了“形状/距离”,然后不知为何,它竟然直接给出了到最近点的距离。
之所以能做到这一点,是因为 Bauble 是一个可以用来制作 3D 图形的实验平台,而这些图形正是通过 有符号距离函数 来实现的。Bauble 的核心理念,就是能够计算到各种对象的距离! 而沃利噪声,恰恰就是由大量随机分布的点所构成的有符号距离函数。 过去,我习惯把有符号距离函数视为定义 3D 形状隐式曲面的工具;然而,沃利噪声则将距离本身作为独立的标量来使用。
于是…… 这确实很有趣。 如果……我们改用其他有符号距离函数,并将其作为程序化噪声的扭曲方式呢?
我们先从简单的开始。既然我们不再使用点,而是随机散布一堆正方形呢?
乍一看,这似乎并不太有趣。不过让我们来看看实际效果:
由于我们只是在二维空间中定义了这个噪声函数,因此我们需要一个二维输入。这样的输入相当单调乏味。不过,这里的情况要有趣得多: 我们可以对它进行多层分解,从而得到……某种效果。
不过,到目前为止,这种效果仍然不够引人注目。如果再进一步改变方向呢?
看起来稍微随机一些吧: 不过,用二维噪声来扭曲三维空间,效果并不算特别理想。
接下来,我们来尝试三维场景。 在三维空间中可视化距离场要困难得多。你现在看到的,其实是穿过原点且朝向摄像机的平面上的距离场——你可以点击并拖动摄像机,以截取不同视角的空间切片。我知道这种可视化效果并不完美,但重点在于:这种技术完全可以推广到三维空间——尽管在三维空间的每一个点上,我们往往很难直观地想象出距离场的形态。
现在,让我们来看看用这种方法来扭曲三维形状时的效果: 是不是有点意思?相比之前的效果,效果要好得多,甚至带有一丝多面体般的宝石质感。
你觉得,如果我们尝试多层分解这种噪声,我们的电脑会不会被烧毁?
很高兴你还在和我一起探索。 让我们把方块换成圆锥: 这种纹理看起来有点像松果吗?我想是这样吧? 我们还可以尝试更多基本几何体。当然,我们不必局限于基本形状。 这是一个经典的 SDF 示例,用来展示构建构造性实体几何体是多么容易: 如果……我们以这个为基础,来构建沃利噪声呢?
我觉得,去掉随机性之后,效果会更有意思。 我们已经构建出了一种有趣的三维噪声函数,并将其用于扭曲三维空间。当然,我们也可以回到最初的定义——将这种噪声视为一种“噪声纹理”:
真是挺有意思。 这一切的意义在于:沃利噪声促使我们重新思考有符号距离函数,将其视为超越隐式曲面的另一种可能性。而 Bauble 让我们轻松构建有符号距离函数,因此它也成为尝试此类纹理的好去处。 即使我们从未发现什么特别吸引人的地方,但和空间玩耍总是充满乐趣。 如果你是第一次看到Bauble,欢迎来到这里!这篇帖子是对一篇曾经在 YouTube 视频中简短提及过的文章的扩展。视频中还展示了更多 Bauble 能够实现的各种创意。如果你对这些内容产生了兴趣,不妨去看看!