Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the origin of this GLSL rand() one-liner?

Tags:

glsl

shader

prng

I've seen this pseudo-random number generator for use in shaders referred to here and there around the web:

float rand(vec2 co){   return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); } 

It's variously called "canonical", or "a one-liner I found on the web somewhere".

What's the origin of this function? Are the constant values as arbitrary as they seem or is there some art to their selection? Is there any discussion of the merits of this function?

EDIT: The oldest reference to this function that I've come across is this archive from Feb '08, the original page now being gone from the web. But there's no more discussion of it there than anywhere else.

like image 393
Grumdrig Avatar asked Oct 18 '12 21:10

Grumdrig


People also ask

What language is GLSL?

The OpenGL Shading Language (GLSL) is the principal shading language for OpenGL. While, thanks to OpenGL Extensions, there are several shading languages available for use in OpenGL, GLSL (and SPIR-V) are supported directly by OpenGL without extensions. GLSL is a C-style language.

What means GLSL?

OpenGL Shading Language (GLSL) is a high-level shading language with a syntax based on the C programming language.

What is GLSL computer graphics?

GLSL is a strictly typed language, and every variable is given a type when it is declared. GLSL has built-in types to represent scalars (that is, single values), vectors, and matrices. The scalar types are float, int, and bool. Version 3.00 adds an unsigned integer type, uint.


1 Answers

Very interesting question!

I am trying to figure this out while typing the answer :) First an easy way to play with it: http://www.wolframalpha.com/input/?i=plot%28+mod%28+sin%28x*12.9898+%2B+y*78.233%29+*+43758.5453%2C1%29x%3D0..2%2C+y%3D0..2%29

Then let's think about what we are trying to do here: For two input coordinates x,y we return a "random number". Now this is not a random number though. It's the same every time we input the same x,y. It's a hash function!

The first thing the function does is to go from 2d to 1d. That is not interesting in itself, but the numbers are chosen so they do not repeat typically. Also we have a floating point addition there. There will be a few more bits from y or x, but the numbers might just be chosen right so it does a mix.

Then we sample a black box sin() function. This will depend a lot on the implementation!

Lastly it amplifies the error in the sin() implementation by multiplying and taking the fraction.

I don't think this is a good hash function in the general case. The sin() is a black box, on the GPU, numerically. It should be possible to construct a much better one by taking almost any hash function and converting it. The hard part is to turn the typical integer operation used in cpu hashing into float (half or 32bit) or fixed point operations, but it should be possible.

Again, the real problem with this as a hash function is that sin() is a black box.

like image 102
starmole Avatar answered Sep 28 '22 08:09

starmole