ampas / aces-vwg-output-transforms

Other
0 stars 2 forks source link

Unnecessary multiply and divide in calculation of `F_L` #27

Open nick-shaw opened 3 months ago

nick-shaw commented 3 months ago

In the calculation of the viewing condition dependent F_L value in the forward and inverse Hellwig conversion there is a multiply by 0.2 followed immediately by a multiply by 5.0. These clearly cancel out to 1.0, but could introduce precision issues in different implementations.

nick-shaw commented 3 months ago

This also happens in the Hellwig_J_to_Y() and Y_to_Hellwig_J() functions.

nick-shaw commented 3 months ago

It's also worth noting that currently this F_L calculation happens four times per pixel, when in fact it could be precomputed once globally.

nick-shaw commented 3 months ago

Taking it further, at single precision float, the whole complexity of incorporating k and k4 in the calculation of F_L has no effect whatsoever. Three lines could be replaced with a simple:

F_L = pow(L_A / 200, 1 / 3)

which in our case, where L_A = 100, is simply 1 / cbrt(2).

KelSolaar commented 3 months ago

I was discussing with Nick and it seems advisable to use an approximation here, especially because $L_A$ is kept constant at a rather high value. The full equation really starts to noticeably deviate at low values:

>>> import colour
>>> f = lambda x : (x / 200) ** (1/3)
>>> f(100)
0.7937005259840998
>>> colour.appearance.hunt.luminance_level_adaptation_factor(100)
0.79370052754616727
>>> f(10)
0.3684031498640387
>>> colour.appearance.hunt.luminance_level_adaptation_factor(10)
0.36840451910550759
>>> f(1)
0.17099759466766973
>>> colour.appearance.hunt.luminance_level_adaptation_factor(1)
0.17150541623653787
>>> f(0.1)
0.07937005259840998
>>> colour.appearance.hunt.luminance_level_adaptation_factor(0.1)
0.070863964674330454

I would just keep a reference/note to the full equation.