欢迎光临散文网 会员登陆 & 注册

Worley噪声的概念与实现---Unity3D/C#(笔记)

2023-08-30 17:48 作者:我看见IB~  | 我要投稿

标量场和距离场

在了解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函数:

效果,复制几个进行拼接:

下面是整个脚本:


Worley噪声的概念与实现---Unity3D/C#(笔记)的评论 (共 条)

分享到微博请遵守国家法律