summaryrefslogtreecommitdiffstats
path: root/glitter.cginc
diff options
context:
space:
mode:
Diffstat (limited to 'glitter.cginc')
-rw-r--r--glitter.cginc38
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) {