summaryrefslogtreecommitdiffstats
path: root/ssfd.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2026-03-31 21:52:22 -0700
committeryum <yum.food.vr@gmail.com>2026-03-31 21:52:22 -0700
commit072fa8904087ad780ef09132e0e0717d0eecdb68 (patch)
tree9106d1a919f1e54c6895b976053b6d732651ce48 /ssfd.cginc
parent57aa53c6b1b51265839dbd71aac4eeb88e050de0 (diff)
ssfd bugfixes
Diffstat (limited to 'ssfd.cginc')
-rw-r--r--ssfd.cginc20
1 files changed, 12 insertions, 8 deletions
diff --git a/ssfd.cginc b/ssfd.cginc
index c3e1c89..df45d81 100644
--- a/ssfd.cginc
+++ b/ssfd.cginc
@@ -32,19 +32,24 @@ float ssfd(float2 uv, float scale, float max_fwidth, float2 uv_offset, texture3D
// Factor is 16.
// log_2(factor) is 4.
// Divide original by 16.
- float fw_factor = uv_fw / max_fwidth;
- float fractal_level = log2(fw_factor) / log2(bayer_res);
+ float fw_factor = max(uv_fw / max_fwidth, 1e-6);
+ // Fractal transitions need to happen in octaves to match the Bayer
+ // self-similarity used by the reference implementation.
+ float fractal_level = log2(fw_factor);
float fractal_level_floor = floor(fractal_level);
float fractal_remainder = fractal_level - fractal_level_floor;
- uv *= pow(bayer_res, -fractal_level_floor);
- uv += uv_offset * pow(bayer_res, -fractal_level_floor);
+ float uv_scale = exp2(-fractal_level_floor);
+ uv *= uv_scale;
+ uv += uv_offset * uv_scale;
float n_layers = depth;
- float not_used_lo = 1/(n_layers*2);
- float not_used_hi = 1 - not_used_lo;
+ float min_sub_layer = max(1.0, 0.25 * n_layers);
+ float max_sub_layer = n_layers;
- float uvw = (not_used_hi - not_used_lo) * (1 - fractal_remainder) + not_used_lo;
+ // Only the top 3/4 of the layer stack is fractally self-similar.
+ float sub_layer = lerp(min_sub_layer, max_sub_layer, 1 - fractal_remainder);
+ float uvw = (sub_layer - 0.5) / n_layers;
float3 uv_3d = float3(uv, uvw);
@@ -68,4 +73,3 @@ void apply_ssfd(v2f i, float2 uv, LightData l, float3 normal, inout float3 albed
}
#endif // __SSFD_INC
-