不只是噪音

不只是噪音

噪音是程序生成图形中最基础的工具,只要使用过任何一种计算机图形工具就一定使用过噪音,即使只会用PS也知道有“云彩”和“分层云彩”这些滤镜,它们就是最简单的噪音。虽然是非常简单的工具,但如果深入了解噪音算法的构成方式,就会了解到简单的算法可以生成出无穷无尽的变化,就是因为变化无穷才让噪音成为了非常强大的图形工具。

噪音的基本构成

噪音的基础来自于随机数,如果给屏幕上的每个象素点一个0-1之间的随机数来表示象素点的亮度,就能得到这样一幅图,看起来很像老式电视机故障时的黑白雪花。这种随机图像并没有太大的作用,因为每个点的随机数都是离散的,相互完全没有关系,在这幅图像中的世界是完全没有逻辑,没有能量的。

在80年代Ken Perlin发明了一种更加有用的噪音,称为Perlin噪音。Perlin噪音的构造思路非常简单,既然基本随机噪音因为离散性而没有意义,那就人为让噪音连续起来就好了啊。最简单的连续化处理就是插值,在离散数据中间用函数插值的方法把空隙填满空间就自然连续了。说到插值,学过数值分析的立刻就能想到七八种插值方法,只要能保持连续性不管是三角函数,正态分布,还是样条曲线都可以使用。我想当时Ken Perlin在发明Perlin噪音也是非常直觉地选择了一种类正态分布的函数。对简单随机噪音插值之后都得到了一种像霉菌表面的图像。要看清Perlin噪音的形态可以对噪音画出等高线图,这样就能看到噪音呈现出奇异的类似生物的特征。Perlin噪音的广泛使用就是和它类生物性有很大关系,如果只是用周期函数叠加很难达到这种效果。


刚才说到插值函数的种类很多,既然如此我们就不必拘泥于Perlin发明的噪音了,完全可以自己试验不同的插值函数来生成不同的噪音图案。

简单的线性插值得到的是棱角分明的结构。

指数函数插值得到的

三角函数插值得到的

距离函数插值得到的

当然还可以让不同的插值函数相互叠加,这样就没完没了。

越多细节就越真实

上面这些噪音看起来都很像某种抽象图腾,因为单纯的插值噪音缺少细节。越抽象的东西越缺少细节,越真实的东西细节越丰富,想要利用噪音创造更加真实的东西显然需要更多细节。这里就需要分形结构帮忙了。学计算机专业都知道Koch雪花和复数折叠之类的分形图案,分形就是在不同大小的空间里呈现出相似的结构。分形结构用在噪音里就是将不同缩放比例的简单噪音相互叠加起来,这样可以得到更加丰富的细节。和插值类似,不同的叠加方法会制造不同的结果,Ken Perlin就给出了三种不同的叠加方式。

第一种是简单的缩放叠加,得到的图形就是PS里的“云彩”渲染效果。

第二种是对每层叠加的噪音取绝对值,等同于PS的“分层云彩”

接着对“分层云彩”使用三角函数就得到了第三种分层噪音

shadertoy上的nimitz还发明了一种对每层噪音添加旋转的方法,得到的图形看起来像翻滚的岩浆


我个人也发现了一种很好用的叠加方法,在每层噪音叠加时使用abs(a-b)操作(就是PS里差值叠加),会得到细节丰富,类似流体云的效果

进入不同的空间

个人觉得数学最有趣之处就在于同一个对象在不同角度来看就会变成完全不同的东西,只要换一个角度看问题,就可能进入一个完全不同的世界。对于噪音我们同样可以换个角度来看,噪音也可能看作是在空间(坐标系)上的一种标量场,这样我们除了操作噪音本身之外,还可以操作噪音所在的空间(坐标系)。

空间变换在数学里是非常古老的话题了,你完全不用自己发明,教科书上早就写N种空间变换了。

这里就简单举例几个常见的变换。

1/z变换,最简单的一种共形变换,看起来很像磁场是不是。

1/z再进展到把模长也除掉就会得到星光状的图像。

可以用模长和旋转建立关系,制造扭曲变换

用极坐标变换的变体也可以制造出洞穴的效果

这个时候我们再换一个角度来看问题,既然可以扭曲噪音所在的空间,同样可以用噪音来扭曲别的图形的空间。原本普通的图形在噪音扭曲下就能制造出完全不同的效果。

简单的图形如sin条纹和圆圈条纹经过扭曲就能得到类似树木纹路的图像

另一种噪音voronoi噪音经过扭曲能得到大理石表面的效果

条纹图形经过扭曲会得到绸缎一样的效果

扭曲如果使用在极坐标上,得到的图形

噪音同样可以作为速度场驱动粒子移动。但噪音场是标量,缺少方向,很多人直觉的会想到取梯度场就有方向了啊。虽然梯度场有方向,但梯度场明显是有源的,也就是说粒子顺着梯度场移动最终都回流到一些点失去离开的速度。这里有两种解决方法,第一种是将标量场的标量大小转换为向量角度,也就是一个处处速度相等但方向不同的向量场。

另一种方法就是取旋度场,旋度向量在梯度源的部分会产生旋转,这样粒子就会绕过源而不会流进去出不来。

从复杂空间中得到特殊的颜色

光照就是从物体的几何结构中发现颜色,噪音相关的几何结构非常复杂,我们可以使用各种方法来获得各种特殊的颜色,有时候从这些结构中获得的颜色反而超出自己的想象。

因为方法太多,没办法一一详解。就简单举例几种。

记录空间扭曲程度作为亮度

从标量函数提取出法线,加上简单的伪光照

Gradient Color—在线播放—优酷网,视频高清在线观看 http://v.youku.com/v_show/id_XMTcxMjU3ODYxNg==

从梯度方向进行ray trace,层叠每层的梯度信息得到的颜色

写在最后,这片短文只是简单介绍了一些噪音算法的变化,其中有很多都是被PS AE等软件或者插件实现过的,重复实现这些算法没什么意义,所以就没列出代码。这里只是想提供一些思路,数学和算法的变换无穷无尽,不用拘泥于某些软件的某些功能,只要了解到算法的本质就能自己发展出不同的变化。

文章被以下专栏收录