Worley噪声的概念与实现---Unity3D/C#(笔记)
标量场和距离场
在了解Worley噪声之前需要先对标量场和距离场有个基本概念。
1、标量场
场可以理解为一个关于空间的函数,函数的参数是空间的坐标,函数的输出是一个标量、向量、矩阵或张量。如果输出是标量,则可以称其为标量场。(摘自:游戏开发技术杂谈11: Worley噪声 - 知乎 (zhihu.com))
对于一个2D空间来说,有了坐标,有了坐标对应的值。就可以将其可视化。首先通过一个简单的函数对刚才的距离场建模。
实施可视化:
Unity3D中新建一个新建一个脚本 WorleyView.cs
WorleyView.cs:
新建一个空对象,添加WorleyView组件。
创建一个Image和Button对象。
赋值。

运行游戏,点击刚刚创建的按钮,此时的效果:

2、距离场
距离场是一种特殊的标量场,相对于上面测试的标量场来说,距离场多了一个明确的概念,叫特征点。特征点是散落在空间中的特殊的点。(摘自:游戏开发技术杂谈11: Worley噪声 - 知乎 (zhihu.com))
从实现上来看,标量场的特殊点就是原点。
现在实现四个特征点的可视化图形:
在之前的基础上新增两个函数即可。
修改CreateTex函数:
再次运行并点击,得到:

关于距离场的计算,上述代码的问题主要是其效率过低的问题,如果距离场只有这4个特征点还好,但是特征点的数量一旦过多,计算起来就是一种效率的灾难了。
其实对于空间中的一个像素点,并不需要计算所有特征点到它的距离然后逐一比较,那些离得明显比较远的部分可以跳过了,只计算距离比较近的就可以了。所以是如何找到那些比较近的点呢?
Steven·Worley在其论文中的做法是将整个空间划分为多个同等大小的网格,并规定,在每个网格中,都有且只有一个特征点。如下图所示。

这个限制让每个网格都只有一个特征点。那么可知,对于一个像素点来说,距离它最近的就是周围九宫格里的点,只需要找这9个点里最近的就行了。
继续写代码,在原来的基础上新增三个函数。
修改CreateTex函数。
结果:

还要支持无缝衔接,修改下脚本:
在脚本首行定义两个宏,便于快速切换:
修改 BuildWorleyNoise、DistanceWorley函数:
效果,复制几个进行拼接:

下面是整个脚本:

