5

So I am still getting upvotes for my ancient comment on this question: What's the origin of this GLSL rand() one-liner?

And it got me thinking, what would a good GLSL hash function look like? There are obvious use cases for it like Perlin noise. There are some properties that I would look for in a good implementation.

  • Stable under different precisions (mediump,highp). This could be configurable.
  • Should be usable in ES2, so it can not use integer support
  • ALU only, no textures
  • Not looking for cryptographic qualities, but for large periods and "perceptual" randomness
  • Should ideally produce the same results on a bare minimum spec ES2 implementation

Practically I think most people just mix x,y inputs by multiplying them with some prime numbers, adding them, multiplying them again, and looking the result coordinate up in a tiling texture of random numbers with nearest sampling.

So this question is less about looking for "the answer" but curiosity if there is a good way to do this. I would also like to know arguments about why it is not possible.

Community
  • 1
  • 1
starmole
  • 4,974
  • 1
  • 28
  • 48

1 Answers1

1

"Murmur" style of hash functions seem to perform very well for this kind of application, check out https://nullprogram.com/blog/2018/07/31/ and https://www.shadertoy.com/view/WttXWX. Quoting from the later:

//bias: 0.17353355999581582 ( very probably the best of its kind )
uint lowbias32(uint x)
{
    x ^= x >> 16;
    x *= 0x7feb352dU;
    x ^= x >> 15;
    x *= 0x846ca68bU;
    x ^= x >> 16;
    return x;
}


// bias: 0.020888578919738908 = minimal theoretic limit
uint triple32(uint x)
{
    x ^= x >> 17;
    x *= 0xed5ad4bbU;
    x ^= x >> 11;
    x *= 0xac4c1b51U;
    x ^= x >> 15;
    x *= 0x31848babU;
    x ^= x >> 14;
    return x;
}
dividebyzero
  • 2,190
  • 1
  • 21
  • 33