mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-12 21:32:52 +00:00
#3487, #3488, #3489, #3490, #3491: Levels (Individual Controls): GPU saturates the curve before pow can overflow
WGSL leaves the result of an overflowing pow indeterminate, so clamping after it did not guarantee the CPU's 1e30 bound on every backend. A curve past the bound (log2|t| / gamma > 99.7) now saturates to +-1e30 without calling pow; between 1e30 and 2^99.7 the clamp gives the same 1e30, so the GPU matches the CPU everywhere.
This commit is contained in:
1 file changed
+6
-2
@@ -40,8 +40,12 @@ fn fxt_lv(i: u32, v: f32, clip_b: bool, clip_w: bool) -> f32 {
|
||||
if (clip_w) {
|
||||
t = min(t, 1.0);
|
||||
}
|
||||
// color2::LEVELS_IC_CURVE_LIMIT keeps the curve finite.
|
||||
let curve = clamp(fxt_gamma(t, max(data[o + 2u], 0.01)), -1e30, 1e30);
|
||||
// color2::LEVELS_IC_CURVE_LIMIT keeps the curve finite. WGSL leaves an overflowing pow
|
||||
// indeterminate, so a curve past the bound saturates before pow: |t|^(1/g) > 1e30 once
|
||||
// log2|t| / g > 99.66; between 1e30 and 2^99.7 the clamp gives the same 1e30.
|
||||
let g = max(data[o + 2u], 0.01);
|
||||
let saturate = abs(t) > 1.0 && log2(abs(t)) / g > 99.7;
|
||||
let curve = select(clamp(fxt_gamma(t, g), -1e30, 1e30), sign(t) * 1e30, saturate);
|
||||
return data[o + 3u] + (data[o + 4u] - data[o + 3u]) * curve;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user