diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-31 22:21:39 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-31 22:21:46 -0700 |
| commit | b565525c15948dab84b7d21c33f6e5386bb00ad0 (patch) | |
| tree | d88fe0a923944615a3ad0274a77371bd208981dc | |
| parent | 11aa1cd90b748219ee00c3d6924cc40ca2a5f1f4 (diff) | |
Glitter: tweak hash; looks less artifacty in game
| -rw-r--r-- | glitter.cginc | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/glitter.cginc b/glitter.cginc index a9bbf8b..baf6200 100644 --- a/glitter.cginc +++ b/glitter.cginc @@ -13,7 +13,9 @@ * I have made changes to this code. They are: * 1. Syntax changes required to translate GLSL to HLSL. * 2. Stylistic preferences, like using "1" or "1.0" instead of "1.". - * 3. The `GetGlitterLighting` function, which populates data required for + * 3. Replaced the original glitter RNG with a stronger integer-domain + * permuted congruential generator (PCG) hash. + * 4. The `GetGlitterLighting` function, which populates data required for * indirect glitter. The original paper only discusses analytic lighting. * * @article{KPT:2025:Glinty, @@ -96,7 +98,7 @@ float normal(float2x2 cov, float2 x) { / (sqrt(determinant(cov)) * 2.0 * PI); } -uint2 shuffle(uint2 v) { +uint2 pcg2d(uint2 v) { v = v * 1664525u + 1013904223u; v.x += v.y * 1664525u; v.y += v.x * 1664525u; @@ -109,17 +111,33 @@ uint2 shuffle(uint2 v) { return v; } -float2 rand(uint2 v) { - return float2(shuffle(v)) * UINT_TO_UNIT; +uint4 pcg4d(uint4 v) { + v = v * 1664525u + 1013904223u; + v.x += v.y * v.w; + v.y += v.z * v.x; + v.z += v.x * v.y; + v.w += v.y * v.z; + + v = v ^ (v >> 16u); + + v.x += v.y * v.w; + v.y += v.z * v.x; + v.z += v.x * v.y; + v.w += v.y * v.z; + return v; +} + +float2 rand(uint4 v) { + return float2(pcg4d(v).xy) * UINT_TO_UNIT; } float2 Rand2D(float2 x, float2 y, float l, uint i) { - uint2 ux = asuint(x); - uint2 uy = asuint(y); - uint ul = asuint(l); - // This is broken, but looks cool. - //return hash22_fast(asfloat((ux>>16|ux<<16) ^ uy ^ ul ^ (i*0x124u))); - return rand((ux>>16|ux<<16) ^ uy ^ ul ^ (i*0x124u)); + // `x` and `y` are cell-center coordinates (n + 0.5). Hash the integer cell IDs + // directly so nearby cells do not alias through IEEE-754 bit patterns. + uint4 seed = uint4(uint2(x), uint2(y)); + uint2 salt = pcg2d(uint2(asuint(l), i)); + seed ^= uint4(salt.x, salt.y, salt.y ^ 0x9e3779b9u, salt.x ^ 0x85ebca6bu); + return rand(seed); } float Rand1D(float2 x, float2 y, float l, uint i) { |
