Fit Functions and Blackpoint / Whitepoint Adjustment
I thought it could be useful to examine fit/remap functions, how they work and where they can be used. Fitting or remapping is simply the compression/expansion/offset of a range of values from a defined in-point to a newly defined out-point, using multiplication and addition.
An example would be remapping a range of values that span -1 to +1 to fit in the range 0 to 1. This is an example of using a fit function to normalize a range. However you can use the same principles as a method of “grading” or “colour correcting images”, which is what a blackpoint/whitepoint adjustment is.
Examining the Grade node inside Nuke, we see a list of parameters, blackpoint, whitepoint, lift, gain, multiply, offset and gamma. The first four of these are actually a fit function. You define your incoming blacks/whites, then define your new blacks/white using the lift/gain.
You can break fitting down into two steps, normalization and expansion/contraction. To normalize, you set your lowest value back to 0 using (x-minIn), then you set your highest by dividing by the “range”, which is (maxIn-minIn).
In the above example, by subtracting the min value (0.2) from the curve, we arrive at the following:
Subtracting the min val (0.2) from the max val (0.7) yields the range of 0.5. Max val (which is now 0.5, as 0.7-0.2=0.5) divided by 0.5 (range) is 1.
We arrive at a normalized range.
To remap those 0–1 values to the new range, multiply by your new range which is (maxOut-minOut). Then adjust the lift (essentially an inverted multiplication) by adding your minOut.
Fit Function & Blackpoint/Whitepoint Adjustment
(((x-minIn) / (maxIn-minIn) ) * (maxOut-minOut)) +minOut
This is the expression for the final fit function.
As a side-note, this only fits values within the defined source range into a new destination range, which means that anything outside of the defined source range will still exist outside of the new range (modifed in some way depending on the remap). This will need to be clamped if undesirable — Nuke’s Grade defaults to clamping blacks, and Houdini ships with a clamped Fit Range and non-clamped Fit Range.
Houdini: Fit Range
As an example of the fit in other software, Houdini ships with a Fit Range node that is very useful for remapping values in e.g. procedural noise patterns.
Nuke: Grade Node
If you replace the variable names in the above expression with Nuke’s native grading parameters, we’ll have the first four sliders of the Grade node:
(((x-blackpoint) / (whitepoint-blackpoint) ) * (gain-lift)) + lift
Adding the rest of the Grade node parameters will give you:
pow((((x-blackpoint)/(whitepoint-blackpoint)*((gain*multiply)-lift))+lift)+offset,(1/gamma))
The above is now a perfect match of Nuke’s grading tool.