summaryrefslogtreecommitdiffstats
path: root/ssfd.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-02-23 02:24:39 -0800
committeryum <yum.food.vr@gmail.com>2025-02-23 02:24:58 -0800
commitf478606867d42e971c5fa83803f3255e922e6a8a (patch)
treec50ec81b781aaaff9fd74a416c22be8ff1552e5e /ssfd.cginc
parent3ec0f0c2d35f21d2f28d0a116e9e211789b13903 (diff)
add ltcgi, alpha multiplier
Diffstat (limited to 'ssfd.cginc')
-rw-r--r--ssfd.cginc57
1 files changed, 57 insertions, 0 deletions
diff --git a/ssfd.cginc b/ssfd.cginc
new file mode 100644
index 0000000..1eec6d7
--- /dev/null
+++ b/ssfd.cginc
@@ -0,0 +1,57 @@
+#ifndef __SSFD_INC
+#define __SSFD_INC
+
+#include "globals.cginc"
+
+float ssfd(float2 uv, float scale, float max_fwidth, float2 uv_offset, texture3D noise)
+{
+ //float uv_fw = fwidth(uv.x) + fwidth(uv.y);
+ // Original paper uses SVD instead of fwidth.
+ float2x2 M = float2x2(ddx(uv), ddy(uv));
+ float2x2 MtM = mul(transpose(M), M);
+ float trace = MtM[0][0] + MtM[1][1];
+ float det = determinant(MtM);
+ // Calculate eigenvalues using quadratic formula.
+ float tmp = sqrt(trace * trace - 4 * det);
+ float e1 = (trace + tmp) * 0.5;
+ float e2 = (trace - tmp) * 0.5;
+ float2 singular_values = sqrt(float2(e1, e2));
+ // Logic from original paper: the smaller eigenvalue corresponds to the
+ // largest amount of stretching, so we use it to determine when to
+ // subdivide.
+ float uv_fw = singular_values.y;
+ uv_fw *= scale;
+
+ uint width, height, depth;
+ noise.GetDimensions(width, height, depth);
+ float bayer_res = sqrt(depth);
+
+ // Suppose max_fwidth is 1.
+ // uv_fw is 16. That means UV is changing a lot per pixel. That means we want to shrink the scale of the UV.
+ // Factor is 16.
+ // log_2(factor) is 4.
+ // Divide original by 16.
+ float fw_factor = uv_fw / max_fwidth;
+ // log_b(x) = log_a(x) / log_a(b)
+ float fractal_level = log2(fw_factor) / log2(bayer_res);
+ 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 n_layers = depth;
+ float not_used_lo = 1/(n_layers*2);
+ float not_used_hi = 1 - not_used_lo;
+
+ float uvw = (not_used_hi - not_used_lo) * (1 - fractal_remainder) + not_used_lo;
+
+ float3 uv_3d = float3(uv, uvw);
+
+ float dither = noise.SampleLevel(linear_repeat_s, uv_3d, 0);
+
+ return dither;
+}
+
+#endif // __SSFD_INC
+