Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: Perlin noise in a fragment shader

  1. #11
    Junior Member Regular Contributor
    Join Date
    Nov 2007
    Location
    London UK
    Posts
    242

    Re: Perlin noise in a fragment shader

    Hi,

    I'm trying to implement 3D simplex noise from the example found in the GLSL fragment shader in this archive:
    http://staffwww.itn.liu.se/~stegu/si...e/MacOSX-port/
    and am not sure that I've got it right.


    The texture I get isn't quite as random as I'd hope. As you can see, it exhibits very obvious diagonal stripes, and looks nothing like the builtin GLSL noise1(x,y,z) function.

    I'm using a 256x256px permutation texture with random values in each of the 4 channels.

    Anyone any idea what might be going wrong?

    a|x
    http://machinesdontcare.wordpress.com

  2. #12
    Junior Member Regular Contributor
    Join Date
    Aug 2007
    Posts
    107

    Re: Perlin noise in a fragment shader

    Hi Toneburst.

    Indeed, it doesn't quite look like regular perlin noise or simplex noise. Instead, have you tried using the permutation texture that is generated in the C code? When I ported "GLSL-noise.zip" to Java, I got the expected results with the "permTexture" (I didn't use the gradTexture because I didn't need 4D Simplex Noise).

    BTW: Interesting. I've never seen the GLSL noise function return anything useful on my implementation - infact, the assembly just seems to replace the value from noise with the constant "0.0". Has it only been implemented recently? What does it look like?
    kind regards,
    Nicolai de Haan

  3. #13
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,655

    Re: Perlin noise in a fragment shader

    Looks like your octaves are not right, it can be the scale of each level, or the amplitude, or both.

  4. #14
    Senior Member OpenGL Guru zed's Avatar
    Join Date
    Jul 2000
    Location
    S41.16.25 E173.16.21
    Posts
    2,609

    Re: Perlin noise in a fragment shader

    Ive seen that two when I impplemented noise (but such a long time ago I forget what the cause was)

    one thing to do is to turn off the filtering on the textures, including the aniostropic filtering

  5. #15
    Junior Member Regular Contributor
    Join Date
    Nov 2007
    Location
    London UK
    Posts
    242

    Re: Perlin noise in a fragment shader

    Wow, so many responses!

    Nicolai, could you possibly post the permTexture image you used? I'm afraid I don't know how to generate the texture from the C code. I'm embarrassed to say I'm really a relative programming newbie- I only posted in the Advanced forum because I came across this thread while doing a search for noise implementations.

    Here's an example of GLSL noise1() running on my MacBook Pro. It's quite possible that it's running in software, rather than on the GPU (though I haven't checked).


    ZbuffeR, there's only the one octave there. Maybe that's the problem...
    Actually, though, I seem to get the same diagonal banding whatever scale I use, so adding octaves isn't going to help, I don't think.

    zed, unfortunately, I don't have the option of changing filtering modes. I'm using an application that allows GLSL shaders to be used, but doesn't let filtering options be changed.


    Thanks for getting back to me guys! Anything else I could try?

    a|x

  6. #16
    Junior Member Regular Contributor
    Join Date
    Aug 2007
    Posts
    107

    Re: Perlin noise in a fragment shader

    ToneBurst:

    Thanks for the screenshot of the GLSL noise() function.

    I wrote out the permTexture with DevIL. The texels are not computed from Stefan Gustavson's reference code in C but from my conversion. I ran it through ImageMagick "identify -verbose" and uploaded the output here. If someone thinks this looks wrong, please post a message. Looking at the histogram it certainly looks noisy and when used with the GLSL shaders from Gustavson, it produces what I expected simplex noise example. Rendered in ortho with normalized texture coordinates with the shaders:

    Code :
     /*
     * Author: Stefan Gustavson ITN-LiTH (stegu at itn.liu.se) 2004-12-05
     * You may use, modify and redistribute this code free of charge,
     * provided that my name and this notice appears intact.
     *
     * Modified: Nicolai de Haan Brøgger (ndhb78 at gmail.com)
     */
     uniform vec2 noiseFrequency;
     uniform vec2 noiseOffset;
     
     void main(void) {
    	gl_TexCoord[0].st = gl_MultiTexCoord0.st;
    	gl_TexCoord[0].st += noiseOffset;
    	gl_TexCoord[0].st *= noiseFrequency;
    	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    } // function

    Code :
    /*
     * Author: Stefan Gustavson ITN-LiTH (stegu at itn.liu.se) 2004-12-05
     * You may use, modify and redistribute this code free of charge,
     * provided that my name and this notice appears intact.
     *
     * Modified: Nicolai de Haan Brøgger (ndhb78 at gmail.com)
     */
    uniform sampler2D noisePermTexture;
     
    /*
     * To create offsets of one texel and one half texel in the
     * texture lookup, we need to know the texture image size.
     */
    #define ONE 0.00390625 // change accordingly if you change the code to use another texture size (1 / 256) 
    #define ONEHALF 0.001953125  // change accordingly if you change the code to use another texture size (0.5 / 256)
     
    /*
     * The interpolation function. This could be a 1D texture lookup
     * to get some more speed, but it's not the main part of the algorithm.
     */
    float fade(float t) {
      return t*t*t*(t*(t*6.0-15.0)+10.0); // Improved fade, yields C2-continuous noise
    } // function
     
    /*
     * 2D simplex noise. Somewhat slower but much better looking than classic noise.
     */
    float snoise(vec2 P) {
    	// Skew and unskew factors are a bit hairy for 2D, so define them as constants
    	#define F2 0.366025403784 // This is (sqrt(3.0) - 1.0) / 2.0
    	#define G2 0.211324865405 // This is (3.0 - sqrt(3.0)) / 6.0
     
    	// Skew the (x,y) space to determine which cell of 2 simplices we're in
     	float s = (P.x + P.y) * F2;   // Hairy factor for 2D skewing
      	vec2 Pi = floor(P + s);
      	float t = (Pi.x + Pi.y) * G2; // Hairy factor for unskewing
      	vec2 P0 = Pi - t; // Unskew the cell origin back to (x,y) space
      	Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup
     
      	vec2 Pf0 = P - P0;  // The x,y distances from the cell origin
     
      	// For the 2D case, the simplex shape is an equilateral triangle.
      	// Find out whether we are above or below the x=y diagonal to
      	// determine which of the two triangles we're in.
      	vec2 o1;
      	if(Pf0.x > Pf0.y)
      		o1 = vec2(1.0, 0.0); // +x, +y traversal order
      	else
      		o1 = vec2(0.0, 1.0); // +y, +x traversal order
     
      	// Noise contribution from simplex origin
      	vec2 grad0 = texture2D(noisePermTexture, Pi).rg * 4.0 - 1.0;
      	float t0 = 0.5 - dot(Pf0, Pf0);
      	float n0;
      	if (t0 < 0.0) {
      		n0 = 0.0;
      	} else {
        	t0 *= t0;
        	n0 = t0 * t0 * dot(grad0, Pf0);
      	} // if else
     
      	// Noise contribution from middle corner
      	vec2 Pf1 = Pf0 - o1 + G2;
      	vec2 grad1 = texture2D(noisePermTexture, Pi + o1*ONE).rg * 4.0 - 1.0;
      	float t1 = 0.5 - dot(Pf1, Pf1);
      	float n1;
      	if (t1 < 0.0) {
      		n1 = 0.0;
      	} else {
    	    t1 *= t1;
    		n1 = t1 * t1 * dot(grad1, Pf1);
      	} // if else
     
    	// Noise contribution from last corner
      	vec2 Pf2 = Pf0 - vec2(1.0-2.0*G2);
      	vec2 grad2 = texture2D(noisePermTexture, Pi + vec2(ONE, ONE)).rg * 4.0 - 1.0;
      	float t2 = 0.5 - dot(Pf2, Pf2);
      	float n2;
      	if(t2 < 0.0) {
      		n2 = 0.0;
    	} else {
    		t2 *= t2;
    		n2 = t2 * t2 * dot(grad2, Pf2);
    	} // if else
     
    	// Sum up and scale the result to cover the range [-1,1]
      	return 70.0 * (n0 + n1 + n2);
    } // function
     
    void main(void) {
    	float n = snoise(gl_TexCoord[0].st);
    	gl_FragColor = vec4(0.5 + 0.5 * vec3(n, n, n), 1.0); // Bias to range [0.0 : 1.0] and set fragment to fully opaque. 
    } // function
    kind regards,
    Nicolai de Haan

  7. #17
    Junior Member Regular Contributor oc2k1's Avatar
    Join Date
    Jan 2007
    Location
    germany
    Posts
    171

    Re: Perlin noise in a fragment shader

    Try my implementation. Unfortunately it slows down at high magnifications, but it supports anisotropic filtering...

    http://lumina.sourceforge.net/Tutorials/Noise.html

  8. #18
    Junior Member Regular Contributor
    Join Date
    Nov 2007
    Location
    London UK
    Posts
    242

    Re: Perlin noise in a fragment shader

    Thanks for the extra info oc2k1 and Nicolai de Haan Brøgger!
    I hadn't checked this thread for a while, but I've come back to this problem now, so I'll check out both your leads.

    Cheers again,

    a|x

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •