2016-04-14 1 views
0

J'ai rencontré un problème en essayant de calculer le bruit Perlin en utilisant un shader de fragment OpenGL. Le résultat est blocky et pas continu du tout. enter image description herePerlin Noise block grid

Je suis en train d'utiliser ce genre de mise en œuvre: enter image description here

Je ne peux pas comprendre le problème, voici mon code shader fragment:

#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); 

}

Répondre

1

Dans les dernières lignes, vous appelez smoothInter() sur les coordonnées globales x et y, lorsque vous devez l'appeler à l'emplacement toutes les coordonnées.

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)); 

Multiplier par grid_dim ici parce que vos cellules de la grille ne sont pas la largeur de l'unité. smoothInter() doit prendre des valeurs comprises entre 0 et 1 et cette transformation en assure la.

J'ai également dû supprimer les appels normalize(), et à la place "normaliser" le résultat dans la plage [0,1]. C'était difficile, je suppose à cause de votre méthode de générer les vecteurs de gradient aléatoires aux sommets de la grille. En l'état, votre code semble afficher des valeurs entre -2500 et +2500 environ. Une fois que j'ai ajusté cela à la bonne gamme, j'ai eu une régularité indésirable apparaissant. Je l'ai encore une fois mis au choix de prng.