Perlin's Improved Noise Working in HLSL but Not Working in GLSL

Started by
4 comments, last by yv 16 years, 10 months ago
I am converting Perlin's Improved Noise from HLSL to GLSL. I am using several look-up textures and appear to be reading values from textures correctly. Maybe someone will see something I am not noticing. To those that have succeeeded in implementing Perlin's Improved Noise in GLSL, please help! My Vertex Shader is as follows: ------------------------------------------------ varying vec2 vTexCoord; varying vec3 vNormal; varying vec3 Nin; uniform float noiseScale; void main(void) { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex * noiseScale; vTexCoord = gl_MultiTexCoord0.st * noiseScale; vNormal = gl_NormalMatrix * gl_Normal; Nin = (gl_Position).xyz * noiseScale; } ------------------------------------------------- My Fragment Shader is below, sorry for the lengthy code: ------------------------------------------------- uniform sampler2D Texture0; uniform sampler1D GenerateGradTexture4D; uniform sampler1D GenerateGradTexture; uniform sampler1D GeneratePermGrad4DTexture; uniform sampler1D GeneratePermGradTexture; uniform sampler2D GeneratePermTexture2D; uniform sampler1D GeneratePermTexture; varying vec2 vTexCoord; varying vec3 vNormal; varying vec3 Nin; const float modulus = 61.0; // modulus in random hash uniform float noiseScale; uniform float anim; uniform float lacunarity; uniform float gain; vec3 fade(vec3 t) { return t * t * t * (t * (t * 6. - 15.) + 10.); // new curve } vec4 fade(vec4 t) { return t * t * t * (t * (t * 6. - 15.) + 10.); // new curve } float perm(float x) { return float(texture1D(GeneratePermTexture, x)); } vec4 perm2d(vec2 p) { return texture2D(GeneratePermTexture2D, p); } float grad(float x, vec3 p) { return dot(texture1D(GenerateGradTexture, x*16.0), vec4(p,1.0)); } float gradperm(float x, vec3 p) { return dot(texture1D(GeneratePermGradTexture, x), vec4(p,1.0)); } // 4d versions float grad(float x, vec4 p) { return dot(texture1D(GenerateGradTexture4D, x), p); } float gradperm(float x, vec4 p) { return dot(texture1D(GeneratePermGrad4DTexture, x), p); } float inoise(vec3 p) { vec3 P = mod(floor(p), 256.0); // FIND UNIT CUBE THAT CONTAINS POINT p -= floor(p); // FIND RELATIVE X,Y,Z OF POINT IN CUBE. vec3 f = fade(p); // COMPUTE FADE CURVES FOR EACH OF X,Y,Z. P = P / 256.0; const float one = 1.0 / 256.0; // HASH COORDINATES OF THE 8 CUBE CORNERS vec4 AA = perm2d(P.xy) + P.z; // AND ADD BLENDED RESULTS FROM 8 CORNERS OF CUBE return mix( mix( mix( gradperm(AA.x, p ), gradperm(AA.z, p + vec3(-1., 0., 0.) ), f.x), mix( gradperm(AA.y, p + vec3(0., -1., 0.) ), gradperm(AA.w, p + vec3(-1., -1., 0.) ), f.x), f.y), mix( mix( gradperm(AA.x+one, p + vec3(0., 0., -1.) ), gradperm(AA.z+one, p + vec3(-1., 0., -1.) ), f.x), mix( gradperm(AA.y+one, p + vec3(0., -1., -1.) ), gradperm(AA.w+one, p + vec3(-1., -1., -1.) ), f.x), f.y), f.z); } // 4D noise float inoise(vec4 p) { vec4 P = mod(floor(p), 256.0); // FIND UNIT HYPERCUBE THAT CONTAINS POINT p -= floor(p); // FIND RELATIVE X,Y,Z OF POINT IN CUBE. vec4 f = fade(p); // COMPUTE FADE CURVES FOR EACH OF X,Y,Z, W P = P / 256.0; const float one = 1.0 / 256.0; // HASH COORDINATES OF THE 16 CORNERS OF THE HYPERCUBE float A = perm(P.x) + P.y; float AA = perm(A) + P.z; float AB = perm(A + one) + P.z; float B = perm(P.x + one) + P.y; float BA = perm(B) + P.z; float BB = perm(B + one) + P.z; float AAA = perm(AA)+P.w, AAB = perm(AA+one)+P.w; float ABA = perm(AB)+P.w, ABB = perm(AB+one)+P.w; float BAA = perm(BA)+P.w, BAB = perm(BA+one)+P.w; float BBA = perm(BB)+P.w, BBB = perm(BB+one)+P.w; // INTERPOLATE DOWN return mix( mix( mix( mix( grad(perm(AAA), p ), grad(perm(BAA), p + vec4(-1, 0, 0, 0) ), f.x), mix( grad(perm(ABA), p + vec4(0, -1, 0, 0) ), grad(perm(BBA), p + vec4(-1, -1, 0, 0) ), f.x), f.y), mix( mix( grad(perm(AAB), p + vec4(0, 0, -1, 0) ), grad(perm(BAB), p + vec4(-1, 0, -1, 0) ), f.x), mix( grad(perm(ABB), p + vec4(0, -1, -1, 0) ), grad(perm(BBB), p + vec4(-1, -1, -1, 0) ), f.x), f.y), f.z), mix( mix( mix( grad(perm(AAA+one), p + vec4(0, 0, 0, -1)), grad(perm(BAA+one), p + vec4(-1, 0, 0, -1) ), f.x), mix( grad(perm(ABA+one), p + vec4(0, -1, 0, -1) ), grad(perm(BBA+one), p + vec4(-1, -1, 0, -1) ), f.x), f.y), mix( mix( grad(perm(AAB+one), p + vec4(0, 0, -1, -1) ), grad(perm(BAB+one), p + vec4(-1, 0, -1, -1) ), f.x), mix( grad(perm(ABB+one), p + vec4(0, -1, -1, -1) ), grad(perm(BBB+one), p + vec4(-1, -1, -1, -1) ), f.x), f.y), f.z), f.w); } float turbulence(vec3 p, int octaves, float lacunarity, float gain) { float sum = 0.0; float freq = 1.0, amp = 1.0; for(int i=0; i<octaves; i++) { sum += abs(inoise(p*freq))*amp; freq *= lacunarity; amp *= gain; } return sum; } float turbulence(vec4 p, int octaves, float lacunarity, float gain) { float sum = 0.0; float freq = 1.0, amp = 1.0; for(int i=0; i<octaves; i++) { sum += abs(inoise(p*freq))*amp; freq *= lacunarity; amp *= gain; } return sum; } float PS_inoise(vec3 p) { return inoise(p); } float PS_turbulence(vec3 p) { return turbulence(p, 4, lacunarity, gain); } float PS_turbulence4(vec3 p) { return turbulence(vec4(p,anim), 1, lacunarity, gain); } void main(void) { float Intensity = normalize( vNormal ).z * 0.5 + 0.5; gl_FragColor = texture2D( Texture0, vTexCoord); float p = PS_inoise(Nin); gl_FragColor = Intensity * p * gl_FragColor; }
Advertisement
http://staffwww.itn.liu.se/~stegu/simplexnoise/
Thank you so much! This is exactly what I was looking for!
I've used the inoise implementation you provided, I am however running into discontinuities about the size of the noise scale.

I am testing in RenderMonkey and this is what I came up with.

http://vanzine.org/download/noisysphere.GIF

I suspect I am NOT doing something very simple with normals.

Please help understand what is going on.

Thanks.

u need to disable aniostropic filtering on the texture
anlso i think u need GL_NEAREST filtering as well
GL_NEAREST in Texture Filtering helped! Anisotropy did not play a role.

Thank you, zedz!

This topic is closed to new replies.

Advertisement