佩林的模糊世界

图片

什么是Perlin噪音?


佩林的噪音是由肯·佩林(Ken Perlin)于1983年发明的(肯因·佩林(Ken Perlin)因这一成就而获得美国电影艺术与科学学院的奖项)。 您会看到,在那些日子里,每个人都在努力实现照片写实主义,但始终缺乏。 肯·佩林(Ken Perlin)发明了这种噪声算法,以摆脱3D模型的“计算机”悲惨外观。 噪声是计算机图形学中的随机数生成器。 这是随机的,非结构化的模式,在您需要明显结构1缺少的详细零件的来源时很有用。 Perlin噪声是一种多维算法,可用于过程生成,纹理,高程生成,地图生成,表面生成,顶点生成等。 下表2显示了Perlin噪声功能的限制:

尺寸图原始噪声(灰度)申请书
1个

矢量对象看起来手绘
2
程序纹理和火焰之类的对象
3
Perlin噪音用于Minecraft救济

Perlin给出了噪声的以下定义:噪声是白噪声的近似值,限制在一个八度3的范围内。 噪声的正式定义如下:


哪里 -噪音功能。 Perlin的声音是程序噪声。 “形容词程序在计算机科学中用于将程序代码描述的实体与数据结构描述的实体分开。” 4 就是说, 产生了一些东西,并且没有设置硬性。 使用程序噪声而不是例如手动创建噪声有什么好处? 程序噪声紧凑 ,即占用更少的空间。 这是不可分割的 ,即非周期性的 。 它是参数化的 ,可以随机访问; 他还有许多其他优点可以简化艺术家的生活……但这不是我们的最终目标-为艺术家服务吗? 昨天我为After Effects创建了一个插件,可以在我以前的文章中看到。 我没有考虑艺术家对他的兴趣,只考虑我的自我利益,因此没有人下载它。 我明白了这一教训:为艺术家服务,而不是为自己服务。

在Perlin之前,出现了光栅梯度的噪声。 它们是通过在随机值之间进行插值生成的,在Perlin噪声中,每个顶点使用立方晶格 ,然后执行样条插值。 “通过对晶格点进行散列并使用结果选择梯度来获得伪随机梯度。” 5 这些哈希变成12个向量,并使用五次多项式从中心插值到边缘。 很难想象,对吧? 不用担心 我将在图像6和伪代码7中显示它


“ ...使用五次多项式从中心插值到边缘”

这是没有哈希函数的经典Perlin伪代码:

// Function to linearly interpolate between a0 and a1 // Weight w should be in the range [0.0, 1.0] float lerp(float a0, float a1, float w) { return (1.0 - w)*a0 + w*a1; // as an alternative, this slightly faster equivalent formula can be used: // return a0 + w*(a1 - a0); } // Computes the dot product of the distance and gradient vectors. float dotGridGradient(int ix, int iy, float x, float y) { // Precomputed (or otherwise) gradient vectors at each grid node extern float Gradient[IYMAX][IXMAX][2]; // Compute the distance vector float dx = x - (float)ix; float dy = y - (float)iy; // Compute the dot-product return (dx*Gradient[iy][ix][0] + dy*Gradient[iy][ix][1]); } // Compute Perlin noise at coordinates x, y float perlin(float x, float y) { // Determine grid cell coordinates int x0 = int(x); int x1 = x0 + 1; int y0 = int(y); int y1 = y0 + 1; // Determine interpolation weights // Could also use higher order polynomial/s-curve here float sx = x - (float)x0; float sy = y - (float)y0; // Interpolate between grid point gradients float n0, n1, ix0, ix1, value; n0 = dotGridGradient(x0, y0, x, y); n1 = dotGridGradient(x1, y0, x, y); ix0 = lerp(n0, n1, sx); n0 = dotGridGradient(x0, y1, x, y); n1 = dotGridGradient(x1, y1, x, y); ix1 = lerp(n0, n1, sx); value = lerp(ix0, ix1, sy); return value; } 

还值得知道的是,“除了Perlin噪声和稀疏卷积噪声外,所有噪声函数都近似于带状。 Perlin的噪声只是弱带,这可能导致失真和细节丢失的问题。” 8 另外,Perlin噪声没有高斯振幅分布。 也就是说,噪声点不会基于高斯函数而分散,在本文中我们不会考虑。 佩林在很多事情上都很自在,但他却很虚弱。 在下表9中,您可以自己查看。



实践中的Perlin噪声:GLSL实现


因此,让我们谈谈Perlin对GLSL的影响。 珀林噪声可以用作波,用作漫射色,用作漫射材料,用作闪烁光或用作纹理上的斑点。 我个人在此示例中将其用作颜色的闪烁。


在撰写本文时,我正在考虑为After Effects创建一个插件,以添加Perlin杂讯功能。

可以按以下方式创建Perlin最简单的噪声10

 float rand(vec2 c){ return fract(sin(dot(c.xy ,vec2(12.9898,78.233))) * 43758.5453); } float noise(vec2 p, float freq ){ float unit = screenWidth/freq; vec2 ij = floor(p/unit); vec2 xy = mod(p,unit)/unit; //xy = 3.*xy*xy-2.*xy*xy*xy; xy = .5*(1.-cos(PI*xy)); float a = rand((ij+vec2(0.,0.))); float b = rand((ij+vec2(1.,0.))); float c = rand((ij+vec2(0.,1.))); float d = rand((ij+vec2(1.,1.))); float x1 = mix(a, b, xy.x); float x2 = mix(c, d, xy.x); return mix(x1, x2, xy.y); } float pNoise(vec2 p, int res){ float persistance = .5; float n = 0.; float normK = 0.; float f = 4.; float amp = 1.; int iCount = 0; for (int i = 0; i<50; i++){ n+=amp*noise(p, f); f*=2.; normK+=amp; amp*=persistance; if (iCount == res) break; iCount++; } float nf = n/normK; return nf*nf*nf*nf; } 


 #define M_PI 3.14159265358979323846 float rand(vec2 co){return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);} float rand (vec2 co, float l) {return rand(vec2(rand(co), l));} float rand (vec2 co, float l, float t) {return rand(vec2(rand(co, l), t));} float perlin(vec2 p, float dim, float time) { vec2 pos = floor(p * dim); vec2 posx = pos + vec2(1.0, 0.0); vec2 posy = pos + vec2(0.0, 1.0); vec2 posxy = pos + vec2(1.0); float c = rand(pos, dim, time); float cx = rand(posx, dim, time); float cy = rand(posy, dim, time); float cxy = rand(posxy, dim, time); vec2 d = fract(p * dim); d = -0.5 * cos(d * M_PI) + 0.5; float ccx = mix(c, cx, dx); float cycxy = mix(cy, cxy, dx); float center = mix(ccx, cycxy, dy); return center * 2.0 - 1.0; } // p must be normalized! float perlin(vec2 p, float dim) { /*vec2 pos = floor(p * dim); vec2 posx = pos + vec2(1.0, 0.0); vec2 posy = pos + vec2(0.0, 1.0); vec2 posxy = pos + vec2(1.0); // For exclusively black/white noise /*float c = step(rand(pos, dim), 0.5); float cx = step(rand(posx, dim), 0.5); float cy = step(rand(posy, dim), 0.5); float cxy = step(rand(posxy, dim), 0.5);*/ /*float c = rand(pos, dim); float cx = rand(posx, dim); float cy = rand(posy, dim); float cxy = rand(posxy, dim); vec2 d = fract(p * dim); d = -0.5 * cos(d * M_PI) + 0.5; float ccx = mix(c, cx, dx); float cycxy = mix(cy, cxy, dx); float center = mix(ccx, cycxy, dy); return center * 2.0 - 1.0;*/ return perlin(p, dim, 0.0); } 

但是,这是Perlin噪声的重做版本,该噪声创建于2002年。 转到Gist,看看如何实现Perlin的经典噪音。

好,今天就这些了。 我知道一则简短的帖子,它缺少原始内容,但是到目前为止,我已经没有想法了,因为我还没有阅读Real-Time Rendering 。 这本书充满了学习的概念和思想。 我爱她!


同时,我正在阅读另一本书- 计算机图形学基础 。 我对“隐式曲线”这个话题有些困惑,但是我会请我的数学博士学位的亲戚帮我。


参考文献


  • 程序性噪声功能的调查,计算机图形学论坛,第29卷(2010),第8号,第2379-2600页
  • 高效的计算噪声,《图形工具杂志》第16卷,第1期。 2:85-94

  1. 调查等
  2. flafla2.imtqy.com/2014/08/09/perlinnoise.html
  3. A.Lagaue等
  4. A.Lagae等
  5. A.Lagae等
  6. 来自flafla2.imtqy.com/2014/08/09/perlinnoise.html
  7. 来自维基百科
  8. A.Lagae等
  9. 改编自A.Lagae等
  10. gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83

Source: https://habr.com/ru/post/zh-CN441312/


All Articles