When attempting to compute the gradient noise derivatives I've seen the use of a function named "hash" and I don't understand its purpose (nor why they have commented that it should be replaced by something better): link


vec2 hash( in vec2 x )  // replace this by something better
    const vec2 k = vec2( 0.3183099, 0.3678794 );
    x = x*k + k.yx;
    return -1.0 + 2.0*fract( 16.0 * k*fract( x.x*x.y*(x.x+x.y)) );

// return gradient noise (in x) and its derivatives (in yz)
vec3 noised( in vec2 p )
    vec2 i = floor( p );
    vec2 f = fract( p );

#if 1
    // quintic interpolation
    vec2 u = f*f*f*(f*(f*6.0-15.0)+10.0);
    vec2 du = 30.0*f*f*(f*(f-2.0)+1.0);
    // cubic interpolation
    vec2 u = f*f*(3.0-2.0*f);
    vec2 du = 6.0*f*(1.0-f);
    vec2 ga = hash( i + vec2(0.0,0.0) );
    vec2 gb = hash( i + vec2(1.0,0.0) );
    vec2 gc = hash( i + vec2(0.0,1.0) );
    vec2 gd = hash( i + vec2(1.0,1.0) );
float va = dot( ga, f - vec2(0.0,0.0) );
float vb = dot( gb, f - vec2(1.0,0.0) );
float vc = dot( gc, f - vec2(0.0,1.0) );
float vd = dot( gd, f - vec2(1.0,1.0) );

return vec3( va + u.x*(vb-va) + u.y*(vc-va) + u.x*u.y*(va-vb-vc+vd),   // value
             ga + u.x*(gb-ga) + u.y*(gc-ga) + u.x*u.y*(ga-gb-gc+gd) +  // derivatives
             du * (u.yx*(va-vb-vc+vd) + vec2(vb,vc) - va));

// -----------------------------------------------

void mainImage( out vec4 fragColor, in vec2 fragCoord )
    vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y;
    vec3 n = noised( 8.0*p + iTime*4.0 );

    vec3 col = 0.5 + 0.5*((p.x>0.0) ? n.yzx : n.xxx);
    fragColor = vec4( col, 1.0 );

The noise is defined using a rectangular regular lattice. This lattice contains cells in which the noise is evaluated using the four corner points of this cell. At every point of the lattice a pseudo-random gradient is defined. The hash function is simply a compact way of defining a pseudo-random function that given coordinates of a point of the lattice $(i,j)$ returns a pseudo-random gradient. In this way the gradient vector is the same for all cells which are adjacent to lattice point $(i, j)$.

The reason it says the hash function should be replaced by something better is because it is a very simple hash function which when evaluated might not be too random at all and periodicities might be observed in the generated noise field.

  • $\begingroup$ Thanks! I was able to figure it yesterday, nice seeing that I had come to the right conclusion. $\endgroup$ Sep 2 '21 at 10:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.