mixbox icon indicating copy to clipboard operation
mixbox copied to clipboard

Gamma/non-linearity question

Open virtualritz opened this issue 3 years ago • 2 comments
trafficstars

Could you comment on the linearity of the sRGB values the functions take?

8bit/component sRGB is usually non-linear (baked-in 2.2 gamma) because 8bit is not enough to store colors without visible banding.

Does the code take non-linearity into account? I.e. when mixing colors in RGB this matters as mixing non-linear colors simply leads to (subtly) wrong results.

What about the float variants then?

I.e. can you update the README to clearly state what gamma the sRGB values should have in both cases? I think it would also help to mention this in the paper.

On that note, it is extremely uncommon (can't think of a single case I came across in the wild) to have 32bit/component sRGB values that are not linear.

I.e. float sRGB is commonly sRGB linear. sRGB primaries & white point but with a linear (1.0) gamma. Aka: no baked-in transfer function.

virtualritz avatar Jan 22 '22 10:01 virtualritz

To clarify – the expectation of a user of this lib would commonly be: unsigned char – input/output data is non-linear sRGB with a 2.2 gamma float – input/output data is linear sRGB (no gamma)

virtualritz avatar Jan 22 '22 14:01 virtualritz

Bump. Can you clarify this, pretty please? 😀

virtualritz avatar Mar 18 '22 18:03 virtualritz

All functions in Mixbox 1.x expected non-linear input values and produced non-linear outputs. The internal lookup table is precomputed with this in mind and it takes the non-linearity into account. This means the pigment mixing is carried in the proper linear fashion and the result is non-linearized before output.

We realized the way we named the functions was not ideal and could have lead to some confusion where, e.g., someone would pass linear values as input by mistake. This is why we decided to use new naming for Mixbox 2.0 which hopefully makes the distinction between linear and non-linear more explicit.

There are now 3 versions of each function:

  1. takes 8-bit non-linear rgb (0-255)
  2. takes non-linear 32-bit float rgb (0.0-1.0)
  3. takes linear 32-bit float rgb (0.0-1.0)

For example:

  • mixbox_lerp() takes non-linear 8-bit rgb
  • mixbox_lerp_float() takes non-linear float rgb
  • mixbox_lerp_linear_float() takes linear float rgb

The latent vectors are always in the same linear space and the non-linearity is taken into account when converting to/from the latent space.

scrtwpns avatar Oct 11 '22 09:10 scrtwpns