HDR, color management, krita, luts and other apps
Boudewijn Rempt
boud at valdyas.org
Wed Jun 6 13:31:22 UTC 2012
Here are some notes I prepared today. It's a long read, but please help me
out by pointing out mistakes and options I've forgotten. I've got a
feeling we might have to refactor our display code quite a bit to make
this work correctly, and fast -- especially because in git master there's quite a
bit of brokenness.
Contents:
* color management in Nuke
* color management in Mari
* color management in Krita
** Master
** Lut branch
** With Ocio
The goal is to make Krita function correctly again with all HDR colorspaces and make opengl and
qpainter canvas support the following for HDR colorspaces:
* exposure
* gamma
* lut selection
* painting
* color selection (didn't check how this is done in Nuke and Mari yet,
probably not in the same way as in Krita, where you use the ordinary
colors selectors to select a 8bit int rgba that gets converted using the
exposure settng).
-----------------------------------------
* Color Management in Nuke
"The gain and gamma sliders let you adjust the displayed image, without
affecting your final output. These controls are useful for tasks like
spotting
holes in mattes."
"Press the Zebra Stripe button to apply stripes to all pixels outside the
range
0.0 to 1.0."
"Input Process and Viewer Process operations can be used to modify the
image from the viewed node before it is displayed on your monitor."
Note: the getting started says Input Process is deprecated.
"There are two predefined Viewer Processes, sRGB and rec709,"
" Viewer Process are executed on the GPU. 1D LUT and 3D LUT (Vectorfield)
have GPU implementations, so the built-in Viewer Processes will run on the
GPU (unless gl buffer depth has been set to byte in the Viewer settings,
in which case all processing is done on the CPU). "
"Nuke includes the following predefined Viewer Process gizmos: sRGB and
rec709. By default, sRGB is used because it is a best-guess default for a
typical computer monitor."
*Conclusion*: Nuke is pretty simple-minded. It doesn't care that the
monitor might be calibrated or not, it just allows users to select
"profiles" that change the look, without any care for whether the same
project would look the same with a different monitor.
------------------------------------------------------------------------------
* Color Management in Mari
Mari has both a dialog and a color magement toolbar. The color management
toolbar seems identical with the list of features in the ocio manual, down
to showing only luminance or individual rgb components.
The toolbar has the following items:
Set how colors are displayed using the ColorSpace toolbar:
1. Toggle to enable Enable Color Management in the Color Manager
2. Select a custom OpenColorIO (.ocio) configuration file by clicking
3. Select the colorspace of the current scene using Input ColorSpace
dropdown.
4. Set the display device used to view the scene using the Display Device
dropdown menu.
5. Select the colorspace transform to apply to the scene from the View
Transform dropdown menu.
6. Use the Component dropdown menu to see the individual color
components in the scene.
7. Use the Gain controls to set the amount of exposure adjustment applied
before the display transform by either entering a multiplier (exposure
value), dragging on the slider, or adjusting the F-Stop value.
8. Finally, set the amount of Gamma correction applied after the display
transform by entering a gamma level or by dragging the gamma slider.
There are also some things called "display filters" That sounds like it is
a way to do color correction similar to GIMP -- but I might be confused
about the way they mean "color correction" in the Mari manual.
The mari color management toolbar is included in the ocio distribution, so
it's pretty easy to study.
Conclusion: we can implement, probably, the entire set of Mari
functionality in the Lut docker with some changes to our canvas code.
Enabling OCIO would then _disable_ what I think of as "real" color
management.
------------------------------------------------------------------------------
* Color Management in Krita
Krita currently follows a traditional icc-based colormanagement model. It
uses lcms2 and ctlcs. Krita used to support lcms1 and a kubelka-munk
(spectral) color engine. Krita can convert pixels between all the color
engines it supports. Krita doesn't have an ocio-based color engine yet.
Quick glossary:
Colormodel : pixel arrangement (rgb, bgr, yuv etc, so many bytes per
component)
Profile : icc, ctlcs or other profile that describes what the pixel
values mean and thus allows conversion
Colorspace : combination of model and profile
Engine : a plugin that provides colorspace and profile
implementations.
+ Krita doesn't support spot channels (yet)
+ Every layer has a working colorspace. Layers in an image can all have
different colorspaces.
+ The image has a working colorspace: on composition, all layers are
converted to the working colorspace and combined together
+ The monitor has a profile: this describes the way the monitor deviates
from other monitors and is necessary to make sure the same image looks the
same on two systems.
+ a colorspace can be marked to support HDR
+ we want to be able to have a natural-feeling color selection method for
HDR colorspaces
** In Master
+ ctlcs colorspaces are not marked as HDR: here exposure is applied
during image recomposition by embedding the exposure information in the
profile.
+ the new lcms float colorspaces are marked as HDR, but the exposure
shader is broken.
+ ctlcs colorspaces show exposure even in the qpainter canvas (because
exposure is applied during composition)
+ painting on ctlcs float colorspaces works through converting the
selected fg/bg color to float using exposure embedded in the ctlcs
profile.
** In the lut-docker branch
** Display
+ exposure and gamma are stored in KisCanvasResourceProvider
*** OpenGL
In the lut branch (master is broken for opengl as far as HDR is concerned,
it is not used at all):
if (image colorspace is integer):
1. convert the image to 8 or 16 bit integer rgba textures using the
monitor profile. Currently broken.
2. show the textures
elif (float):
1. convert the image to 16 or 32 bit float rgba textures. This doesn't
use the monitor profile (since that often isn't compatible with float),
but the default profile given by the image colorspace. I.e., no real
conversion.
2. apply the exposure/gamma shader to the textures
3. show the textures
*** QPainter
1. convert the image to 8 bit integer using the monitor profile
2. scale the image
3. display the image
** OCIO
+ Ocio has ocio2icc so, command line tool to generate an ICC “proofing”
profile from a color space transform, which can be used in applications
such as Photoshop. We don't use proofing transforms in Krita, do we?
+ Ocio can be used in the display part of Krita, it can generate
corrected textures or pixels. We could use Ocio in the lut-docker and if
enabled make it replace the final step of conversion from the projection
to the display, or we could make it a step in between.
+ ocio can use the cpu or gpu to perform its transformations.
This situation would make Krita function optionally like Mari for all
practical purposes.
** Possible Refactoring of Krita's display architecture
* create the ocio-based lut docker, which is only active for float images
* the lut docker allows the user to select any of the configured luts;
this transformation will be applied on the projection. Then another
transformation should be applied to correct the result for the monitor
idiosyncracies.
* create a step in both canvases where the image is filtered using ocio.
** OpenGL
This depends a lot on where we'll go with the opengl2 canvas. But ocio
can proably replace our home-grown exposure shader.
We want to:
* make it faster
* support high channel depth monitors and cards
* apply the monitor profile
if (ocio and float):
1. make ocio generate textures from the image with all settings
2. how the deuce do we apply the monitor calibration profile? I don't
know yet... (DisplayTransform?)
elif (not ocio):
1. convert image to the right texture format for the monitor
capabilities using lcms
2. upload the textures
3. show the textures
** QPainter
if (not ocio):
1. convert the image to 8 bit integer using the monitor profile
2. scale the image
3. display the image
elif (ocio):
if (float):
1. convert image pixels using lcms to a known good space for ocio,
if necessary.
2. convert image pixels using ocio (exposure, gamma, other ocio
tricks) to 8 bit rRGB rgba. Use the ocio cpu path.
2a. make sure the ocio configuration is available as icc so we can
create
a correct Krita lmcs2-based colorspace
3. convert converted pixels using lcms2 and the monitor profile to
image
4. pre-scale image
5. show image
NOTES:
* rendering intent and blackpoint are now disregarded when converting to
the monitor colorspace. https://bugs.kde.org/show_bug.cgi?id=301235.
More information about the kimageshop
mailing list