• Perlin noise


       Perlin noise的目的是为了产生一系列可重复,伪随机的信号,在游戏中我们可以利用产生的perlin noise来混合地形使用,例如沙地和草地的混合,如下图所示,第三张黑白颜色图就是perlin noise产生的(http://devmag.org.za/2009/04/25/perlin-noise/)。

      Perlin noise的产生是从一维扩展到三维的。首先从一维说起,假如我们需要得到一维点x的noise,首先我们取x附近的两个整数点的noise值,然后利用插值函数得到该点的noise。具体计算如下:

    //注释掉的为原始的插值函数,非二次连续,高频突变。
    float fade(float t) {
      // return t*t*(3.0-2.0*t); // Old fade, yields discontinuous second derivative
      return t*t*t*(t*(t*6.0-15.0)+10.0); // Improved fade, yields C2-continuous noise
    }
    
    #define lerp(t, a, b) ( a + t * (b - a) )
    
    float Xdelta = X- (int)X;
    
    //X0,X1为最靠近X两个点的噪声值,G为存放各个整数点的噪声值。
    float X0 =G[int(x)];
    float X1 = G[int(x)+1];   
    
    //返回值
    float noise = lerp(fade(Xdelta),X0,X1);

       

    二维的noise获取如上图所示,首先获取平面周围四个点的noise值,然后计算四个点的贡献度,最后插值计算出改点的noise(http://webstaff.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf),代码注释如下。

    float noise2(vec2 vec)
    {
    //图中的i,j。
     vec2 pf = frac(vec);
    ;
    //相近的四个点随机梯度值(noise 值) vec2 gradient00 = G2[perm[pf.x][perm[pf.y]]; vec2 gradient01 = G2[perm[pf.x]][perm[pf.y+1]]; vec2 gradient10 = G2[perm[pf.x+1]][perm[pf.y]]; vec2 gradient11 = G2[perm[pf.x+1]][perm[pf.y+1]]; //四个点nosie的贡献值。 float n00 = dot(grad00, vec); float n10 = dot(grad10, Pf - vector2(1.0, 0.0)); float n01 = dot(grad01, Pf - vector2(0.0, 1.0)); float n11 = dot(grad11, Pf - vector2(1.0, 1.0)); //x方向的插值计算。 // Blend contributions along y vec2 n_x = lerp2(vector2(n00, n01), vec2(n10, n11), fade(Pf.x)); //y方向的插值计算。 // Blend contributions along y float n_xy = lerp2(n_x.x, n_x.y, fade(Pf.y)); // We're done, return the final noise value. return n_xy; }

    三维perlin noise需要计算空间周围的八个点的nosie值,然后插值获取最终值,计算方式如下。

     // Classic Perlin noise, 3D version
     public static double noise(double x, double y, double z) {
     // Find unit grid cell containing point
     //查找最接近的X,Y,Z
     int X = fastfloor(x);
     int Y = fastfloor(y);
     int Z = fastfloor(z);
     
     //计算插值。
     // Get relative xyz coordinates of point within that cell
     x = x - X;
     y = y - Y;
     z = z - Z;
     
     // Wrap the integer cells at 255 (smaller integer period can be introduced here)
     X = X & 255;
     Y = Y & 255;
     Z = Z & 255;
     //随机索引
    // Calculate a set of eight hashed gradient indices
     int gi000 = perm[X+perm[Y+perm[Z]]] % 12;
     int gi001 = perm[X+perm[Y+perm[Z+1]]] % 12;
     int gi010 = perm[X+perm[Y+1+perm[Z]]] % 12; 
     int gi011 = perm[X+perm[Y+1+perm[Z+1]]] % 12;
     int gi100 = perm[X+1+perm[Y+perm[Z]]] % 12;
     int gi101 = perm[X+1+perm[Y+perm[Z+1]]] % 12;
     int gi110 = perm[X+1+perm[Y+1+perm[Z]]] % 12;
     int gi111 = perm[X+1+perm[Y+1+perm[Z+1]]] % 12;
     
     
     //计算梯度值
     // Calculate noise contributions from each of the eight corners
     double n000= dot(grad3[gi000], x, y, z);
     double n100= dot(grad3[gi100], x-1, y, z);
     double n010= dot(grad3[gi010], x, y-1, z);
     double n110= dot(grad3[gi110], x-1, y-1, z);
     double n001= dot(grad3[gi001], x, y, z-1);
     double n101= dot(grad3[gi101], x-1, y, z-1);
     double n011= dot(grad3[gi011], x, y-1, z-1);
     double n111= dot(grad3[gi111], x-1, y-1, z-1);
     // Compute the fade curve value for each of x, y, z
     double u = fade(x);
     double v = fade(y);
     double w = fade(z);
     // Interpolate along x the contributions from each of the corners
     //计算x方向插值。
     double nx00 = mix(n000, n100, u);
     double nx01 = mix(n001, n101, u);
     double nx10 = mix(n010, n110, u);
     double nx11 = mix(n011, n111, u);
     
     //计算y方向插值。
     // Interpolate the four results along y
     double nxy0 = mix(nx00, nx10, v);
     double nxy1 = mix(nx01, nx11, v);
     //计算z方向插值。
     // Interpolate the two last results along z
     double nxyz = mix(nxy0, nxy1, w);
     
     return nxyz;
     }
  • 相关阅读:
    jquery $.post specification
    鸟语2010.5.5
    不使用ubuntu代理
    how to check network's stablity?
    python float decimal issue
    how to check network's stablity?
    session的作用是什么?
    bottle json issure
    我强烈建议,不要想念komdo的ctrl+r
    how to count files in directory
  • 原文地址:https://www.cnblogs.com/VanHu/p/4941258.html
Copyright © 2020-2023  润新知