Perlin's Improved Noise Working in HLSL but Not Working in GLSL
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;
}
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.
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
anlso i think u need GL_NEAREST filtering as well
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement