J'ai essayé d'implémenter Perlin Noise par moi-même en utilisant uniquement la théorie (en suivant flafla2.github.io/2014/08/09/perlinnoise.html). Malheureusement, je n'ai pas pu obtenir l'apparence du bruit Perlin "original".
Quelle est la raison pour laquelle le code ci-dessous rend une version en blocs de Perlin Noise?
Que dois-je améliorer / changer dans le code pour qu'il rende Perlin Noise sans les artefacts?
Je soupçonne qu'il pourrait y avoir un problème dans la façon dont j'interpole ou dans le grads
vecteur. Le grads
vecteur contient des produits scalaires de (vecteur aléatoire pour le point de réseau) et (le vecteur de taille) - pour les 4 points de réseau à proximité. (Les vecteurs aléatoires et de taille sont décrits dans le tout premier lien.)
GLSL Sandbox: http://glslsandbox.com/e#32663.0
float fade(float t) { return t * t * t * (t * (t * 6. - 15.) + 10.); }
vec2 smooth(vec2 x) { return vec2(fade(x.x), fade(x.y)); }
vec2 hash(vec2 co) {
return fract (vec2(.5654654, -.65465) * dot (vec2(.654, 57.4), co));
}
float perlinNoise(vec2 uv) {
vec2 PT = floor(uv);
vec2 pt = fract(uv);
vec2 mmpt= smooth(pt);
vec4 grads = vec4(
dot(hash(PT + vec2(.0, 1.)), pt-vec2(.0, 1.)), dot(hash(PT + vec2(1., 1.)), pt-vec2(1., 1.)),
dot(hash(PT + vec2(.0, .0)), pt-vec2(.0, .0)), dot(hash(PT + vec2(1., .0)), pt-vec2(1., 0.))
);
return 5.*mix (mix (grads.z, grads.w, mmpt.x), mix (grads.x, grads.y, mmpt.x), mmpt.y);
}
float fbm(vec2 uv) {
float finalNoise = 0.;
finalNoise += .50000*perlinNoise(2.*uv);
finalNoise += .25000*perlinNoise(4.*uv);
finalNoise += .12500*perlinNoise(8.*uv);
finalNoise += .06250*perlinNoise(16.*uv);
finalNoise += .03125*perlinNoise(32.*uv);
return finalNoise;
}
void main() {
vec2 position = gl_FragCoord.xy / resolution.y;
gl_FragColor = vec4( vec3( fbm(3.*position) ), 1.0 );
}