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

前端 未结 4 810
忘了有多久
忘了有多久 2020-12-22 19:17

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.x         


        
4条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-22 19:29

    The origin is probably the paper: "On generating random numbers, with help of y= [(a+x)sin(bx)] mod 1", W.J.J. Rey, 22nd European Meeting of Statisticians and the 7th Vilnius Conference on Probability Theory and Mathematical Statistics, August 1998

    EDIT: Since I can't find a copy of this paper and the "TestU01" reference may not be clear, here's the scheme as described in TestU01 in pseudo-C:

    #define A1 ???
    #define A2 ???
    #define B1 pi*(sqrt(5.0)-1)/2
    #define B2 ???
    
    uint32_t n;   // position in the stream
    
    double next() {
      double t = fract(A1     * sin(B1*n));
      double u = fract((A2+t) * sin(B2*t));
      n++;
      return u;
    } 
    

    where the only recommended constant value is the B1.

    Notice that this is for a stream. Converting to a 1D hash 'n' becomes the integer grid. So my guess is that someone saw this and converted 't' into a simple function f(x,y). Using the original constants above that would yield:

    float hash(vec2 co){
      float t = 12.9898*co.x + 78.233*co.y; 
      return fract((A2+t) * sin(t));  // any B2 is folded into 't' computation
    }
    

提交回复
热议问题