Perlin Noise块网格

时间:2016-04-14 15:50:34

标签: opengl block fragment-shader perlin-noise

我在尝试使用OpenGL片段着色器计算Perlin噪声时遇到了问题。 结果是块状的,根本不连续。 enter image description here

我正在尝试使用这种实现: enter image description here

我无法弄清楚问题,这是我的片段着色器代码:

#version 330 core
out vec3 color;
in vec4 p;
in vec2 uv;

// random value for x gradiant coordinate
float randx(vec2 co){
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}


// random value for y gradaint coordiante
float randy(vec2 co){
    return fract(cos(dot(co.xy ,vec2(4.9898,78.233))) * 68758.5453);
}


// smooth interpolation funtion
float smoothInter(float x){
    return 6*x*x*x*x*x -15*x*x*x*x + 10*x*x*x;
}


float grid_dim = 10.0f;


void main() {
    // Get coloumn and row of the bottom left 
    //point of the square in wich the point is in the grid
    int col = int(uv.x * grid_dim);
    int row = int(uv.y * grid_dim);



// Get the 4 corner coordinate of the square, 
//divided by the grid_dim to have value between [0,1]
vec2 bl = vec2(col, row) / 10.0f;
vec2 br = vec2(col+1, row) / 10.0f;
vec2 tl = vec2(col, row+1) / 10.0f;
vec2 tr = vec2(col+1, row+1) / 10.0f;

// Get vectors that goes from the corner to the point
vec2 a = normalize(uv - bl);
vec2 b = normalize(uv - br);
vec2 c = normalize(uv - tl);
vec2 d = normalize(uv - tr);

// Compute the dot products
float q = dot(vec2(randx(tl),randy(tl)), c);
float r = dot(vec2(randx(tr),randy(tr)), d);
float s = dot(vec2(randx(bl),randy(bl)), a);
float t = dot(vec2(randx(br),randy(br)), b);

// interpolate using mix and our smooth interpolation function
float st = mix(s, t, smoothInter(uv.x));
float qr = mix(q, r, smoothInter(uv.x));
float noise = mix(st, qr, smoothInter(uv.y));

// Output the color
color = vec3(noise, noise, noise);

}

1 个答案:

答案 0 :(得分:1)

在最后几行中,当您需要在本地坐标上调用它时,您在全局 x和y坐标上调用smoothInter()。

float st = mix(s, t, smoothInter( (uv.x - col) * grid_dim ));
float qr = mix(q, r, smoothInter( (uv.x - col) * grid_dim ));
float noise = mix(st, qr, smoothInter( (uv.y - row) * grid_dim ));

此处乘以grid_dim,因为网格单元格不是单位宽度。 smoothInter()应该取0到1之间的值,这个转换确保了。

我还必须删除normalize()调用,而是将结果“规范化”到范围[0,1]。这很棘手,我假设是因为你在网格顶点生成随机梯度向量的方法。就目前而言,您的代码似乎输出介于-2500和+2500之间的值。一旦我将其缩小到正确的范围,我就会出现一些不良的规律性。我再次把它归结为prng的选择。