diff options
| -rw-r--r-- | pbr.cginc | 1 | ||||
| -rw-r--r-- | tone.cginc | 60 | ||||
| -rw-r--r-- | tooner.shader | 2 |
3 files changed, 36 insertions, 27 deletions
@@ -283,7 +283,6 @@ float4 getLitColor( float2 brightness_proportions = brightnesses / sum_brightness; #if defined(_BRIGHTNESS_CLAMP) sum_brightness = smooth_clamp(sum_brightness, _Min_Brightness, _Max_Brightness); - //sum_brightness = clamp(sum_brightness, _Min_Brightness, _Max_Brightness); #endif direct_light.color[2] = sum_brightness * brightness_proportions[0]; indirect_light.diffuse[2] = sum_brightness * brightness_proportions[1]; @@ -21,33 +21,45 @@ float3 aces_filmic(float3 x) { // Nice properties: // 1. At x=0, the derivative is 1. // 2. No transcendental ops, and branchless. -float3 smooth_min(float3 x, float k) { - // Derivation of `b` from `k`: - // f(x, b) = b * x / (x + b) - // We want f(1, b) = k. - // In other words, we want the max value the function can take on [0, 1] to - // be k. - // k = f(1, b) - // = b / (1 + b) - // b = k * (1 + b) - // = k + kb - // 1 = k/b + k - // 1 - k = k/b - // 1/(1-k) = b/k - // b = k/(1-k) - float e = 1E-4; - k = min(1-e, k); - float b = k/(1-k); - return b * x / (x + b); + +// This original attempt at a smooth minimum function has a problem: +// f(x, k) = k * x / (x + k) +// As k -> inf, f(x, k) -> 1. We want f(x, k) -> k. +// Claude suggests this: +// f(x, a, j) = j * (1 + a) * x / (1 + ax) +// At x=1: +// f(1, a, j) = j * (1 + a) / (1 + a) +// = j +// At infinity, we know that: +// b * x / (x + b) -> 1 +// So: +// f(x, a, j) = j * (1 + a) * x / (1 + ax) +// = (j + ja) * x / (1 + ax) +// = (jx + jax) / (1 + ax) +// = jx / (1 + ax) + jax / (1 + ax) +// = j (x / (1 + ax) + ax / (1 + ax)) +// At infinity, this becomes: +// j (1/a + 1) +// So if we want the limit to be k: +// k = j (1/a + 1) +// k/j = 1/a + 1 +// k/j - 1 = 1/a +// a = 1 / (k/j - 1) + +// Smooth, analytic min function. +// Guarantees that x <= k for all positive x. At x=1, returns j. +// Caller must ensure that j < k. +float smooth_min(float x, float j, float k) { + float a = 1 / (k / j - 1); + return j * (1 + a) * x / (1 + a * x); } -float smooth_min(float x, float k) { - float e = 1E-4; - k = min(1-e, k); - float b = k/(1-k); - return b * x / (x + b); +float3 smooth_min(float3 x, float j, float k) { + float a = 1 / (k / j - 1); + return j * (1 + a) * x / (1 + a * x); } + float smooth_clamp(float x, float lo, float hi) { - return smooth_max(smooth_min(x, hi), lo); + return smooth_max(smooth_min(x, (lo + (hi - lo)/2), hi), lo); } #endif // __TONE_INC diff --git a/tooner.shader b/tooner.shader index e2c757e..a515288 100644 --- a/tooner.shader +++ b/tooner.shader @@ -958,7 +958,6 @@ Shader "yum_food/tooner" #include "tooner_lighting.cginc" ENDCG } - /* Pass { Tags { "RenderType"="Opaque" @@ -1039,7 +1038,6 @@ Shader "yum_food/tooner" #include "mochie_shadow_caster.cginc" ENDCG } - */ } CustomEditor "ToonerGUI" } |
