2

I am using the following code, together with the noise3D generator from webgl-noise

void main() {
float noise = snoise(vec3(gl_FragCoord.x, gl_FragCoord.y, 0.0));
    vec4(1.0, 1.0, 1.0, noise);
}

I am expecting a completely random output, but what I get is this: non

What am I doing wrong?

Edit: What you see is a single texture, to which I apply the shader in SFML like this:

window.draw(myTexture, myShader);
  • 1
    Don't expect "randomness" from noise. Especially Perlin/simplex (this is simplex noise, by the way, which repeats regularly). If you modulate the noise by some varying input then you will get something resembling "randomness." For instance, if you were to multiply your sampled texture by the output of the noise function at `gl_FragCoord`... – Andon M. Coleman Sep 14 '13 at 03:01

4 Answers4

1

To better express what @Alchemist was getting at:

snoise(vec3(gl_FragCoord.x, gl_FragCoord.y, 0.0));

is using x and y values that vary way too fast (too high "frequency"). Perlin noise such as snoise doesn't look good at that scale. It's designed to have features of roughly unit size. You're using pixels (more or less) as the units, so the random features are pixel-sized, making them unsmooth, and the period is too small as well.

Instead, use

float r = 10.0 / iResolution.y; // pseudocode
snoise(vec3(gl_FragCoord.x * r, gl_FragCoord.y * r, 0.0));

where iResolution.y is the y resolution of the window. Now the noise pattern will be large enough to appear smooth, as it's intended, and the period will be large enough that it won't repeat obviously within your image.

LarsH
  • 27,481
  • 8
  • 94
  • 152
0

As I understand it noise is specifically not random, but rather more natural looking "randomness". http://en.wikipedia.org/wiki/Perlin_noise gives a good overview of Perlin noise, which I think is what you are using.

Your image is a bit too non-random though, and I suspect an error in your coding. Could we see the whole app, please?

OK, @Andon has cracked it.

GKFX
  • 1,386
  • 1
  • 11
  • 30
  • The image should work, here's a direct link: http://i.stack.imgur.com/2ARb8.png Thing is, my image has clear patterns, while perlin noise should look random like this: https://commons.wikimedia.org/wiki/File:PerlinNoise2d.png –  Sep 13 '13 at 15:50
  • I see it now. A minute ago the direct link also failed. – GKFX Sep 13 '13 at 15:59
0

If you include the functionality of the noise3D library, you can do a "split-screen" compare with the "randomness"

// My own random number generator
// See Stack Overflow: http://stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/10625698#10625698
float random( vec2 p )
{
    vec2 r = vec2(23.14069263277926,2.665144142690225 );
    return fract( cos( mod( 12345678., 256. * dot(p,r) ) ) );
}

void main()
{
    vec2  p  = (-iResolution.xy + 2.0*gl_FragCoord.xy) / iResolution.y;
    float th = (-iResolution.x + 2.0*iMouse.x) / iResolution.y;

    if( iMouse.z<0.01) th = 0.5/ iResolution.y;
    float noise = snoise(vec3(gl_FragCoord.x, gl_FragCoord.y, 0.0));

    // Thanks to I.Q. for this interactive split screen!
    // https://www.shadertoy.com/view/MdjGR1
    if( p.x > th )
        noise = random( p );

    vec3 color = vec3(noise, noise, noise );
    color *= smoothstep( 0.006, 0.008, abs(p.x-th) );
    gl_FragColor = vec4( color, 1.0 );
}

ShaderToy version with "split screen" comparison: https://www.shadertoy.com/view/XtX3D4

Michaelangel007
  • 2,798
  • 1
  • 25
  • 23
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – bummi Jan 22 '15 at 09:58
  • How does this answer the question "Why does webgl-noise not give random values?" – LarsH Feb 04 '17 at 01:49
0

First of all, that's not the way that perlin noise is supposed to used.

this no-tiling perlin function generates gradients per 1x1 unit.

    snoise(vec3(gl_FragCoord.x, gl_FragCoord.y, 0.0))

this line is stupid. because it is calling snoise(1, 1, 0), snoise(1, 2, 0).. it equals to a random function here.

you are supposed to get the value of snoise(1.001, 1, 0), snoise(1.002, 1, 0).. then you will see the beautiful natural perlin noise.

The simplfied version of perlin noise shader uses a quick but poor way to generate random gradients. The author assumes you will enlarge the noise and the repetitive pattern will be unnoticeable.

I suggest using a texture-based shader to get a well-randomized effect. The texture should contain a complex permutation information, which helps the shader to generate random effect.

Alchemist
  • 62
  • 5
  • Actually the line you quoted is not (in all environments) calling snoise() with integer values: If you try https://www.shadertoy.com/view/XtX3D4 and change `snoise(q)` to `snoise(floor(q))` (near the bottom), the result changes. Nor is it stupid ... the snoise() implementation the OP referenced doesn't come with documentation describing appropriate inputs. (Nor is it really a random function ... that's exactly the OP's problem.) However your point is valid that Perlin noise is designed to work on much smaller-scale values. – LarsH Feb 03 '17 at 23:09