为什么我的GLSL单纯形噪声的质量比在Java上运行的要差得多?

为什么我的GLSL单纯形噪声的质量比在Java上运行的要差得多?,java,opengl,glsl,simplex-noise,Java,Opengl,Glsl,Simplex Noise,我一直在使用单纯形噪声处理程序生成的地形。我决定通过将单纯形噪波的代码传输到我的计算着色器来提高它的性能。问题是,我为GLSL找到的代码的性能比我为Java找到的代码差。两者都能正常工作,但Java simplex噪波生成的地形看起来比GLSL中的地形更好、更有趣。我有没有办法改进我的计算着色器上的Simplex noise算法,或者使用Java noise冒着性能速度的风险获得更好的结果 计算着色器单纯形噪声代码 #version 430 core layout (local_size_x

我一直在使用单纯形噪声处理程序生成的地形。我决定通过将单纯形噪波的代码传输到我的计算着色器来提高它的性能。问题是,我为GLSL找到的代码的性能比我为Java找到的代码差。两者都能正常工作,但Java simplex噪波生成的地形看起来比GLSL中的地形更好、更有趣。我有没有办法改进我的计算着色器上的Simplex noise算法,或者使用Java noise冒着性能速度的风险获得更好的结果

计算着色器单纯形噪声代码

#version 430 core

layout  (local_size_x  =  10, local_size_y  =  10, local_size_z  =  10)  in;

layout(std430, binding=0) buffer Pos3D{
    float Position3D[];
};
layout(std430, binding=1) buffer Pos2D{
    float Position2D[];
};

uniform float size;


vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}
vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}

float snoise(vec3 v){ 
  const vec2  C = vec2(1.0/6.0, 1.0/3.0) ;
  const vec4  D = vec4(0.0, 0.5, 1.0, 2.0);

// First corner
  vec3 i  = floor(v + dot(v, C.yyy) );
  vec3 x0 =   v - i + dot(i, C.xxx) ;

// Other corners
  vec3 g = step(x0.yzx, x0.xyz);
  vec3 l = 1.0 - g;
  vec3 i1 = min( g.xyz, l.zxy );
  vec3 i2 = max( g.xyz, l.zxy );

  //  x0 = x0 - 0. + 0.0 * C 
  vec3 x1 = x0 - i1 + 1.0 * C.xxx;
  vec3 x2 = x0 - i2 + 2.0 * C.xxx;
  vec3 x3 = x0 - 1. + 3.0 * C.xxx;

// Permutations
  i = mod(i, 289.0 ); 
  vec4 p = permute( permute( permute( 
             i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
           + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 
           + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));

// Gradients
// ( N*N points uniformly over a square, mapped onto an octahedron.)
  float n_ = 1.0/7.0; // N=7
  vec3  ns = n_ * D.wyz - D.xzx;

  vec4 j = p - 49.0 * floor(p * ns.z *ns.z);  //  mod(p,N*N)

  vec4 x_ = floor(j * ns.z);
  vec4 y_ = floor(j - 7.0 * x_ );    // mod(j,N)

  vec4 x = x_ *ns.x + ns.yyyy;
  vec4 y = y_ *ns.x + ns.yyyy;
  vec4 h = 1.0 - abs(x) - abs(y);

  vec4 b0 = vec4( x.xy, y.xy );
  vec4 b1 = vec4( x.zw, y.zw );

  vec4 s0 = floor(b0)*2.0 + 1.0;
  vec4 s1 = floor(b1)*2.0 + 1.0;
  vec4 sh = -step(h, vec4(0.0));

  vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
  vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;

  vec3 p0 = vec3(a0.xy,h.x);
  vec3 p1 = vec3(a0.zw,h.y);
  vec3 p2 = vec3(a1.xy,h.z);
  vec3 p3 = vec3(a1.zw,h.w);

//Normalise gradients
  vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
  p0 *= norm.x;
  p1 *= norm.y;
  p2 *= norm.z;
  p3 *= norm.w;

// Mix final noise value
  vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
  m = m * m;
  return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), 
                                dot(p2,x2), dot(p3,x3) ) );
}

vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }

float snoise(vec2 v){
  const vec4 C = vec4(0.211324865405187, 0.366025403784439,
           -0.577350269189626, 0.024390243902439);
  vec2 i  = floor(v + dot(v, C.yy) );
  vec2 x0 = v -   i + dot(i, C.xx);
  vec2 i1;
  i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
  vec4 x12 = x0.xyxy + C.xxzz;
  x12.xy -= i1;
  i = mod(i, 289.0);
  vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
  + i.x + vec3(0.0, i1.x, 1.0 ));
  vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),
    dot(x12.zw,x12.zw)), 0.0);
  m = m*m ;
  m = m*m ;
  vec3 x = 2.0 * fract(p * C.www) - 1.0;
  vec3 h = abs(x) - 0.5;
  vec3 ox = floor(x + 0.5);
  vec3 a0 = x - ox;
  m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
  vec3 g;
  g.x  = a0.x  * x0.x  + h.x  * x0.y;
  g.yz = a0.yz * x12.xz + h.yz * x12.yw;
  return 130.0 * dot(m, g);
}

float sumOctaves(int iterations, vec3 pos, double persistance, double scale, double low, double high){
    double maxamp = 0;
    double amp = 1;
    double frequency = scale;
    double noise = 0;
    
    for(int i = 0; i<iterations; i++){
        noise += snoise(vec3(pos.x*frequency, pos.y*frequency, pos.z*frequency))*amp;
        maxamp += amp;
        amp *= persistance;
        frequency *= 2;
    }
    
    noise /= maxamp;
    
    noise = noise * (high - low) / 2 + (high + low) / 2;
    return float(noise);
}
float sumOctaves(int iterations, vec2 pos, double persistance, double scale, double low, double high){
    double maxamp = 0;
    double amp = 1;
    double frequency = scale;
    double noise = 0;
    
    for(int i = 0; i<iterations; i++){
        noise += snoise(vec2(pos.x*frequency, pos.y*frequency))*amp;
        maxamp += amp;
        amp *= persistance;
        frequency *= 2;
    }
    
    noise /= maxamp;
    
    noise = noise * (high - low) / 2 + (high + low) / 2;
    return float(noise);
}

int getPosition(vec3 v){
    return int(v.x+v.z*size+v.y*size*size);
}
int getPosition(vec2 v){
    return int(v.x+v.y*size);
}
void main(){
    if(gl_GlobalInvocationID.x < size && gl_GlobalInvocationID.y < size && gl_GlobalInvocationID.z < size){
        Position3D[getPosition(gl_GlobalInvocationID)] = sumOctaves(4,gl_GlobalInvocationID,0.5,0.01,0,1);
        Position2D[getPosition(gl_GlobalInvocationID.xz)] = sumOctaves(4,gl_GlobalInvocationID.xz,0.5,0.01,0,1);
    }
}
public class SimplexNoise {  /[![enter image description here][1]][1]/ Simplex noise in 2D, 3D and 4D
  private static Grad grad3[] = {new Grad(1,1,0),new Grad(-1,1,0),new Grad(1,-1,0),new Grad(-1,-1,0),
                                 new Grad(1,0,1),new Grad(-1,0,1),new Grad(1,0,-1),new Grad(-1,0,-1),
                                 new Grad(0,1,1),new Grad(0,-1,1),new Grad(0,1,-1),new Grad(0,-1,-1)};

  private static Grad grad4[]= {new Grad(0,1,1,1),new Grad(0,1,1,-1),new Grad(0,1,-1,1),new Grad(0,1,-1,-1),
                   new Grad(0,-1,1,1),new Grad(0,-1,1,-1),new Grad(0,-1,-1,1),new Grad(0,-1,-1,-1),
                   new Grad(1,0,1,1),new Grad(1,0,1,-1),new Grad(1,0,-1,1),new Grad(1,0,-1,-1),
                   new Grad(-1,0,1,1),new Grad(-1,0,1,-1),new Grad(-1,0,-1,1),new Grad(-1,0,-1,-1),
                   new Grad(1,1,0,1),new Grad(1,1,0,-1),new Grad(1,-1,0,1),new Grad(1,-1,0,-1),
                   new Grad(-1,1,0,1),new Grad(-1,1,0,-1),new Grad(-1,-1,0,1),new Grad(-1,-1,0,-1),
                   new Grad(1,1,1,0),new Grad(1,1,-1,0),new Grad(1,-1,1,0),new Grad(1,-1,-1,0),
                   new Grad(-1,1,1,0),new Grad(-1,1,-1,0),new Grad(-1,-1,1,0),new Grad(-1,-1,-1,0)};

  private static short p[] = {151,160,137,91,90,15,
  131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
  190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
  88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
  77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
  102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
  135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
  5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
  223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
  129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
  251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
  49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
  138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};
  // To remove the need for index wrapping, double the permutation table length
  private static short perm[] = new short[512];
  private static short permMod12[] = new short[512];
  static {
    for(int i=0; i<512; i++)
    {
      perm[i]=p[i & 255];
      permMod12[i] = (short)(perm[i] % 12);
    }
  }

  // Skewing and unskewing factors for 2, 3, and 4 dimensions
  private static final double F2 = 0.5*(Math.sqrt(3.0)-1.0);
  private static final double G2 = (3.0-Math.sqrt(3.0))/6.0;
  private static final double F3 = 1.0/3.0;
  private static final double G3 = 1.0/6.0;
  private static final double F4 = (Math.sqrt(5.0)-1.0)/4.0;
  private static final double G4 = (5.0-Math.sqrt(5.0))/20.0;

  // This method is a *lot* faster than using (int)Math.floor(x)
  private static int fastfloor(double x) {
    int xi = (int)x;
    return x<xi ? xi-1 : xi;
  }

  private static double dot(Grad g, double x, double y) {
    return g.x*x + g.y*y; }

  private static double dot(Grad g, double x, double y, double z) {
    return g.x*x + g.y*y + g.z*z; }

  private static double dot(Grad g, double x, double y, double z, double w) {
    return g.x*x + g.y*y + g.z*z + g.w*w; }


  // 2D simplex noise
  public static double noise(double xin, double yin) {
    double n0, n1, n2; // Noise contributions from the three corners
    // Skew the input space to determine which simplex cell we're in
    double s = (xin+yin)*F2; // Hairy factor for 2D
    int i = fastfloor(xin+s);
    int j = fastfloor(yin+s);
    double t = (i+j)*G2;
    double X0 = i-t; // Unskew the cell origin back to (x,y) space
    double Y0 = j-t;
    double x0 = xin-X0; // The x,y distances from the cell origin
    double y0 = yin-Y0;
    // For the 2D case, the simplex shape is an equilateral triangle.
    // Determine which simplex we are in.
    int i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
    if(x0>y0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
    else {i1=0; j1=1;}      // upper triangle, YX order: (0,0)->(0,1)->(1,1)
    // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
    // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
    // c = (3-sqrt(3))/6
    double x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
    double y1 = y0 - j1 + G2;
    double x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords
    double y2 = y0 - 1.0 + 2.0 * G2;
    // Work out the hashed gradient indices of the three simplex corners
    int ii = i & 255;
    int jj = j & 255;
    int gi0 = permMod12[ii+perm[jj]];
    int gi1 = permMod12[ii+i1+perm[jj+j1]];
    int gi2 = permMod12[ii+1+perm[jj+1]];
    // Calculate the contribution from the three corners
    double t0 = 0.5 - x0*x0-y0*y0;
    if(t0<0) n0 = 0.0;
    else {
      t0 *= t0;
      n0 = t0 * t0 * dot(grad3[gi0], x0, y0);  // (x,y) of grad3 used for 2D gradient
    }
    double t1 = 0.5 - x1*x1-y1*y1;
    if(t1<0) n1 = 0.0;
    else {
      t1 *= t1;
      n1 = t1 * t1 * dot(grad3[gi1], x1, y1);
    }
    double t2 = 0.5 - x2*x2-y2*y2;
    if(t2<0) n2 = 0.0;
    else {
      t2 *= t2;
      n2 = t2 * t2 * dot(grad3[gi2], x2, y2);
    }
    // Add contributions from each corner to get the final noise value.
    // The result is scaled to return values in the interval [-1,1].
    return 70.0 * (n0 + n1 + n2);
  }


  // 3D simplex noise
  public static double noise(double xin, double yin, double zin) {
    double n0, n1, n2, n3; // Noise contributions from the four corners
    // Skew the input space to determine which simplex cell we're in
    double s = (xin+yin+zin)*F3; // Very nice and simple skew factor for 3D
    int i = fastfloor(xin+s);
    int j = fastfloor(yin+s);
    int k = fastfloor(zin+s);
    double t = (i+j+k)*G3;
    double X0 = i-t; // Unskew the cell origin back to (x,y,z) space
    double Y0 = j-t;
    double Z0 = k-t;
    double x0 = xin-X0; // The x,y,z distances from the cell origin
    double y0 = yin-Y0;
    double z0 = zin-Z0;
    // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
    // Determine which simplex we are in.
    int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
    int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
    if(x0>=y0) {
      if(y0>=z0)
        { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order
        else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order
        else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order
      }
    else { // x0<y0
      if(y0<z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; } // Z Y X order
      else if(x0<z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; } // Y Z X order
      else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; } // Y X Z order
    }
    // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
    // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
    // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
    // c = 1/6.
    double x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
    double y1 = y0 - j1 + G3;
    double z1 = z0 - k1 + G3;
    double x2 = x0 - i2 + 2.0*G3; // Offsets for third corner in (x,y,z) coords
    double y2 = y0 - j2 + 2.0*G3;
    double z2 = z0 - k2 + 2.0*G3;
    double x3 = x0 - 1.0 + 3.0*G3; // Offsets for last corner in (x,y,z) coords
    double y3 = y0 - 1.0 + 3.0*G3;
    double z3 = z0 - 1.0 + 3.0*G3;
    // Work out the hashed gradient indices of the four simplex corners
    int ii = i & 255;
    int jj = j & 255;
    int kk = k & 255;
    int gi0 = permMod12[ii+perm[jj+perm[kk]]];
    int gi1 = permMod12[ii+i1+perm[jj+j1+perm[kk+k1]]];
    int gi2 = permMod12[ii+i2+perm[jj+j2+perm[kk+k2]]];
    int gi3 = permMod12[ii+1+perm[jj+1+perm[kk+1]]];
    // Calculate the contribution from the four corners
    double t0 = 0.6 - x0*x0 - y0*y0 - z0*z0;
    if(t0<0) n0 = 0.0;
    else {
      t0 *= t0;
      n0 = t0 * t0 * dot(grad3[gi0], x0, y0, z0);
    }
    double t1 = 0.6 - x1*x1 - y1*y1 - z1*z1;
    if(t1<0) n1 = 0.0;
    else {
      t1 *= t1;
      n1 = t1 * t1 * dot(grad3[gi1], x1, y1, z1);
    }
    double t2 = 0.6 - x2*x2 - y2*y2 - z2*z2;
    if(t2<0) n2 = 0.0;
    else {
      t2 *= t2;
      n2 = t2 * t2 * dot(grad3[gi2], x2, y2, z2);
    }
    double t3 = 0.6 - x3*x3 - y3*y3 - z3*z3;
    if(t3<0) n3 = 0.0;
    else {
      t3 *= t3;
      n3 = t3 * t3 * dot(grad3[gi3], x3, y3, z3);
    }
    // Add contributions from each corner to get the final noise value.
    return 32.0*(n0 + n1 + n2 + n3);
  }


  // 4D simplex noise, better simplex rank ordering method 2012-03-09
  public static double noise(double x, double y, double z, double w) {

    double n0, n1, n2, n3, n4; // Noise contributions from the five corners
    // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
    double s = (x + y + z + w) * F4; // Factor for 4D skewing
    int i = fastfloor(x + s);
    int j = fastfloor(y + s);
    int k = fastfloor(z + s);
    int l = fastfloor(w + s);
    double t = (i + j + k + l) * G4; // Factor for 4D unskewing
    double X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
    double Y0 = j - t;
    double Z0 = k - t;
    double W0 = l - t;
    double x0 = x - X0;  // The x,y,z,w distances from the cell origin
    double y0 = y - Y0;
    double z0 = z - Z0;
    double w0 = w - W0;
    // For the 4D case, the simplex is a 4D shape I won't even try to describe.
    // To find out which of the 24 possible simplices we're in, we need to
    // determine the magnitude ordering of x0, y0, z0 and w0.
    // Six pair-wise comparisons are performed between each possible pair
    // of the four coordinates, and the results are used to rank the numbers.
    int rankx = 0;
    int ranky = 0;
    int rankz = 0;
    int rankw = 0;
    if(x0 > y0) rankx++; else ranky++;
    if(x0 > z0) rankx++; else rankz++;
    if(x0 > w0) rankx++; else rankw++;
    if(y0 > z0) ranky++; else rankz++;
    if(y0 > w0) ranky++; else rankw++;
    if(z0 > w0) rankz++; else rankw++;
    int i1, j1, k1, l1; // The integer offsets for the second simplex corner
    int i2, j2, k2, l2; // The integer offsets for the third simplex corner
    int i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
    // [rankx, ranky, rankz, rankw] is a 4-vector with the numbers 0, 1, 2 and 3
    // in some order. We use a thresholding to set the coordinates in turn.
    // Rank 3 denotes the largest coordinate.
    i1 = rankx >= 3 ? 1 : 0;
    j1 = ranky >= 3 ? 1 : 0;
    k1 = rankz >= 3 ? 1 : 0;
    l1 = rankw >= 3 ? 1 : 0;
    // Rank 2 denotes the second largest coordinate.
    i2 = rankx >= 2 ? 1 : 0;
    j2 = ranky >= 2 ? 1 : 0;
    k2 = rankz >= 2 ? 1 : 0;
    l2 = rankw >= 2 ? 1 : 0;
    // Rank 1 denotes the second smallest coordinate.
    i3 = rankx >= 1 ? 1 : 0;
    j3 = ranky >= 1 ? 1 : 0;
    k3 = rankz >= 1 ? 1 : 0;
    l3 = rankw >= 1 ? 1 : 0;
    // The fifth corner has all coordinate offsets = 1, so no need to compute that.
    double x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords
    double y1 = y0 - j1 + G4;
    double z1 = z0 - k1 + G4;
    double w1 = w0 - l1 + G4;
    double x2 = x0 - i2 + 2.0*G4; // Offsets for third corner in (x,y,z,w) coords
    double y2 = y0 - j2 + 2.0*G4;
    double z2 = z0 - k2 + 2.0*G4;
    double w2 = w0 - l2 + 2.0*G4;
    double x3 = x0 - i3 + 3.0*G4; // Offsets for fourth corner in (x,y,z,w) coords
    double y3 = y0 - j3 + 3.0*G4;
    double z3 = z0 - k3 + 3.0*G4;
    double w3 = w0 - l3 + 3.0*G4;
    double x4 = x0 - 1.0 + 4.0*G4; // Offsets for last corner in (x,y,z,w) coords
    double y4 = y0 - 1.0 + 4.0*G4;
    double z4 = z0 - 1.0 + 4.0*G4;
    double w4 = w0 - 1.0 + 4.0*G4;
    // Work out the hashed gradient indices of the five simplex corners
    int ii = i & 255;
    int jj = j & 255;
    int kk = k & 255;
    int ll = l & 255;
    int gi0 = perm[ii+perm[jj+perm[kk+perm[ll]]]] % 32;
    int gi1 = perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]] % 32;
    int gi2 = perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]] % 32;
    int gi3 = perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]] % 32;
    int gi4 = perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]] % 32;
    // Calculate the contribution from the five corners
    double t0 = 0.6 - x0*x0 - y0*y0 - z0*z0 - w0*w0;
    if(t0<0) n0 = 0.0;
    else {
      t0 *= t0;
      n0 = t0 * t0 * dot(grad4[gi0], x0, y0, z0, w0);
    }
   double t1 = 0.6 - x1*x1 - y1*y1 - z1*z1 - w1*w1;
    if(t1<0) n1 = 0.0;
    else {
      t1 *= t1;
      n1 = t1 * t1 * dot(grad4[gi1], x1, y1, z1, w1);
    }
   double t2 = 0.6 - x2*x2 - y2*y2 - z2*z2 - w2*w2;
    if(t2<0) n2 = 0.0;
    else {
      t2 *= t2;
      n2 = t2 * t2 * dot(grad4[gi2], x2, y2, z2, w2);
    }
   double t3 = 0.6 - x3*x3 - y3*y3 - z3*z3 - w3*w3;
    if(t3<0) n3 = 0.0;
    else {
      t3 *= t3;
      n3 = t3 * t3 * dot(grad4[gi3], x3, y3, z3, w3);
    }
   double t4 = 0.6 - x4*x4 - y4*y4 - z4*z4 - w4*w4;
    if(t4<0) n4 = 0.0;
    else {
      t4 *= t4;
      n4 = t4 * t4 * dot(grad4[gi4], x4, y4, z4, w4);
    }
    // Sum up and scale the result to cover the range [-1,1]
    return 27.0 * (n0 + n1 + n2 + n3 + n4);
  }

  // Inner class to speed upp gradient computations
  // (In Java, array access is a lot slower than member access)
  private static class Grad
  {
    double x, y, z, w;

    Grad(double x, double y, double z)
    {
      this.x = x;
      this.y = y;
      this.z = z;
    }

    Grad(double x, double y, double z, double w)
    {
      this.x = x;
      this.y = y;
      this.z = z;
      this.w = w;
    }
  }
}
#版本430核心
布局(局部尺寸x=10,局部尺寸y=10,局部尺寸z=10)in;
布局(std430,绑定=0)缓冲区Pos3D{
浮动位置3D[];
};
布局(std430,绑定=1)缓冲区Pos2D{
浮动位置2d[];
};
均匀浮动尺寸;
vec4置换(vec4x){returnmod((x*34.0)+1.0)*x289.0);}
vec4 taylorInvSqrt(vec4 r){return 1.79284291400159-0.85373472095314*r;}
浮点数(vec3v){
常数vec2 C=vec2(1.0/6.0,1.0/3.0);
常数vec4d=vec4(0.0,0.5,1.0,2.0);
//第一角
vec3 i=地板(v+dot(v,C.yyy));
vec3 x0=v-i+dot(i,C.xxx);
//其他角落
vec3 g=步长(x0.yzx,x0.xyz);
vec3 l=1.0-g;
vec3 i1=最小值(g.xyz,l.zxy);
vec3 i2=最大值(g.xyz,l.zxy);
//x0=x0-0.+0.0*C
vec3-x1=x0-i1+1.0*C.xxx;
vec3 x2=x0-i2+2.0*C.xxx;
vec3 x3=x0-1.+3.0*C.xxx;
//排列
i=mod(i,289.0);
vec4p=permute(permute(
i、 z+vec4(0.0,i1.z,i2.z,1.0))
+i.y+vec4(0.0,i1.y,i2.y,1.0))
+i.x+vec4(0.0,i1.x,i2.x,1.0));
//梯度
//(N*N个点均匀分布在正方形上,映射到八面体上。)
浮点n_u2;=1.0/7.0;//n=7
vec3 ns=n_*D.wyz-D.xzx;
vec4j=p-49.0*floor(p*ns.z*ns.z);//mod(p,N*N)
vec4 x_uz=地板(j*ns.z);
vec4y=地板(j-7.0*x);//模(j,N)
vec4 x=x_*ns.x+ns.yyyy;
vec4 y=y_*ns.x+ns.yyy;
vec4h=1.0-abs(x)-abs(y);
vec4 b0=vec4(x.xy,y.xy);
vec4b1=vec4(x.zw,y.zw);
vec4 s0=地板(b0)*2.0+1.0;
vec4 s1=地板(b1)*2.0+1.0;
vec4-sh=-step(h,vec4(0.0));
vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy;
vec4 a1=b1.xzyw+s1.xzyw*sh.zzww;
vec3 p0=vec3(a0.xy,h.x);
vec3p1=vec3(a0.zw,h.y);
vec3 p2=vec3(a1.xy,h.z);
vec3 p3=vec3(a1.zw,h.w);
//归一化梯度
vec4常模=taylorInvSqrt(vec4(点(p0,p0),点(p1,p1),点(p2,p2),点(p3,p3));
p0*=norm.x;
p1*=范数y;
p2*=范数z;
p3*=标准值w;
//混合最终噪声值
vec4m=max(0.6-vec4(点(x0,x0),点(x1,x1),点(x2,x2),点(x3,x3)),0.0);
m=m*m;
返回42.0*dot(m*m,vec4(dot(p0,x0),dot(p1,x1),
点(p2,x2),点(p3,x3));
}
vec3置换(vec3x){returnmod((x*34.0)+1.0)*x289.0);}
浮子电压(2伏){
常数vec4 C=vec4(0.211324865405187,0.366025403784439,
-0.577350269189626, 0.024390243902439);
vec2 i=地板(v+点(v,C.yy));
vec2 x0=v-i+dot(i,C.xx);
vec2i1;
i1=(x0.x>x0.y)?vec2(1.0,0.0):vec2(0.0,1.0);
vec4 x12=x0.xyxy+C.xxzz;
x12.xy-=i1;
i=mod(i,289.0);
vec3p=permute(permute(i.y+vec3(0.0,i1.y,1.0))
+i.x+vec3(0.0,i1.x,1.0));
vec3 m=最大值(0.5-vec3(点(x0,x0),点(x12.xy,x12.xy),
点(x12.zw,x12.zw)),0.0);
m=m*m;
m=m*m;
vec3x=2.0*fract(p*C.www)-1.0;
vec3h=abs(x)-0.5;
vec3 ox=地板(x+0.5);
vec3 a0=x-ox;
m*=1.79284291400159-0.85373472095314*(a0*a0+h*h);
vec3g;
g、 x=a0.x*x0.x+h.x*x0.y;
g、 yz=a0.yz*x12.xz+h.yz*x12.yw;
返回130.0*点(m,g);
}
浮点八度音阶(整数迭代、向量3位置、双持续、双刻度、双低、双高){
双最大值=0;
双安培=1;
双频=刻度;
双噪声=0;
对于(int i=0;i=y0){
如果(y0>=z0)
{i1=1;j1=0;k1=0;i2=1;j2=1;k2=0;}//X Y Z顺序
如果(x0>=z0){i1=1;j1=0;k1=0;i2=1;j2=0;k2=1;}//X Z-Y顺序
else{i1=0;j1=0;k1=1;i2=1;j2=0;k2=1;}//Z X Y顺序
}

否则{//x0您可以定义“看起来更好”,如果您信任噪波函数,我看到的唯一区别是glsl计算噪波的总和,并在每次迭代时将频率乘以2,这会带来更多细节。@DraykoonD我的意思是glsl噪波生成的地形与java生成的地形相比,具有更少的悬垂和洞穴。您能定义“看起来更好”吗,如果您相信噪波函数,我看到的唯一区别是glsl计算噪波的总和,并在每次迭代时将频率乘以2,这会带来更多细节。@Draykond我的意思是glsl噪波生成的地形与java生成的地形相比,具有更少的悬垂和洞穴。