GLSL中使用随机数

Published at 2018-11-14

Quick And Easy GPU Random Numbers In D3D11

参考 gl-matrix 的方式生成标准化的随机vec2和vec3。

使用 uint seed = initSeed(); 来初始化种子, 使用 seed = wang_hash(seed); 来更新种子。

uint wang_hash(uint seed) {
    seed = (seed ^ uint(61) ) ^ (seed >> uint(16));
    seed *= uint(9);
    seed = seed ^ (seed >> uint(4));
    seed *= uint(0x27d4eb2d);
    seed = seed ^ (seed >> uint(15));
    return seed;
}

uint initSeed() {
    uint seed = wang_hash(uint(gl_FragCoord.x));
    seed = wang_hash(seed + uint(gl_FragCoord.y));
    seed = wang_hash(seed + uint(iTime*1000.));
    return seed;
}

float randFloat(uint seed) {
    return float(seed) * (1.0 / 4294967296.0);
}

vec2 randVec2U(uint seed) {
    return vec2(randFloat(seed), randFloat(wang_hash(seed)));
}

vec2 randVec2(uint seed) {
    float r = randFloat(seed) * 2.0 * PI;
    return vec2(cos(r), sin(r));
}

vec3 randVec3(uint seed) {
    float r = randFloat(seed) * 2.0 * PI;
    seed = wang_hash(seed);
    float z = randFloat(seed) * 0.57735;
    float zScale = sqrt(1.0-z*z);
    return vec3(cos(r)*zScale, sin(r)*zScale, z);
}