Function: Hyperbolic Stretch - setiastro/setiastrosuitepro GitHub Wiki
Function: Universal Hyperbolic Stretch
Interactive hyperbolic tone-mapping with α / β / γ shape controls, LP/HP highlight/shadow protection, and a movable pivot. Works on K (luma) or individual R/G/B channels, with live preview, zoom/pan, masking support, and one-click apply.
What it does
- Builds a generalized hyperbolic curve, mirrored around a user-set pivot (u_*\in(0,1)).
- Lets you shape the roll-off with (\alpha,\beta) and apply a power-law γ lift.
- Protects shadows/highlights via LP/HP blends back toward the identity on each side of the pivot.
- Applies per the selected channel (K/R/G/B), honoring the active mask.
The curve (math)
Base hyperbolic form (left half):
H_{\alpha,\beta}(u)=\frac{u^{\alpha}}{u^{\alpha}+\beta\,(1-u)^{\alpha}},\qquad u\in[0,1],\ \alpha>0,\ \beta>0
Mirrored form (right half): replace (\beta) with (\beta^{-1}):
\tilde{H}_{\alpha,\beta}(u)=\frac{u^{\alpha}}{u^{\alpha}+\beta^{-1}\,(1-u)^{\alpha}}
Let the pivot be (u_\in(0,1)). We remap the domain so that the left half ([0,\tfrac12]) spans ([0,u_]) and the right half ([\tfrac12,1]) spans ([u_*,1]):
u_p(u)=
\begin{cases}
2\,u_\*\,u, & u\le \tfrac12,\\[4pt]
u_\*+2(1-u_\*)(u-\tfrac12), & u>\tfrac12.
\end{cases}
We also scale the outputs so the curve passes smoothly through the pivot. Define the mid-values (m_L=H_{\alpha,\beta}(\tfrac12)) and (m_R=\tilde{H}_{\alpha,\beta}(\tfrac12)). The piecewise curve before protection and γ is:
v_p(u)=
\begin{cases}
\dfrac{u_\*}{\max(m_L,\varepsilon)}\,H_{\alpha,\beta}(u), & u\le \tfrac12,\\[10pt]
u_\*+\dfrac{1-u_\*}{\max(1-m_R,\varepsilon)}\Big(\tilde{H}_{\alpha,\beta}(u)-m_R\Big), & u>\tfrac12,
\end{cases}
\quad \varepsilon>0.
LP/HP protection (blend toward identity on each side of the pivot), with (0\le \mathrm{LP},\mathrm{HP}\le 1):
v_{p,\text{prot}}(u)=
\begin{cases}
(1-\mathrm{LP})\,v_p(u)+\mathrm{LP}\,u_p(u), & u_p(u)\le u_\*,\\[4pt]
(1-\mathrm{HP})\,v_p(u)+\mathrm{HP}\,u_p(u), & u_p(u)\ge u_\*.
\end{cases}
γ lift (power-law in output):
f(u)=\big(\,\mathrm{clip}(v_{p,\text{prot}}(u),0,1)\,\big)^{1/\gamma},\qquad \gamma>0.
Finally, the curve is monotonicized (non-decreasing) and LUT-applied to the chosen channel.
Controls
- Channel:
K (Brightness),R,G,B - α, β: shape and balance of the hyperbolic roll-off (both > 0)
- γ: output power-law lift
- LP / HP: protection (blend-back) for Low (left of pivot) / High (right of pivot)
- Pivot: double-click (or Ctrl+Click) the preview to set (u_*)
Preview: Zoom In/Out, Fit to Preview, pan with click-drag, Ctrl+Wheel to zoom. Masking: If a mask is active, the result is blended as (m\cdot\text{out}+(1-m)\cdot\text{src}).
Typical workflow
- Pick channel (
Kto start). - Set pivot at the brightness you want “anchored” (double-click the image).
- Shape with α/β, then fine-tune contrast with γ.
- Add LP/HP if you need extra protection of shadows/highlights.
- Apply. (A history step is recorded; metadata includes α, β, γ, LP, HP, pivot, channel, and mask info.)
Notes & tips
- Lower β favors shadows; higher β favors highlights around the pivot.
- Use LP to keep the left of the pivot closer to identity, HP for the right.
- You can run multiple gentle passes: apply, reset, re-pivot, and refine.