Proposal: Explicit colors

For beginning developers colors are often thought of as being 4 values that make up any color. But that is of course to limited.
In C we didn’t spend time to annotate what we meant when using colors. Now with
CPP and https://developer.blender.org/diffusion/B/browse/master/source/blender/blenlib/BLI_color.hh
we can make colors more explicit (fe which colorspace/role and alpha association is used).

Internally in Blender due to legacy a lot is bound to the sRGB color space and Rec709.
OpenColorIO uses roles to add more flexibility to storage and handling of colors.

Blender has defined several roles that maps to a color space that is in config.ocio or
can be changed by the user via the color management panel, but many areas in blender still uses the legacy pipeline.

My proposal would that any usage of BLI_color.hh would need to annotate its Colorspace or Role
and its alpha association.

There are be multiple ways how to do this. For example as a template:

Color4b<Space::sRGB, Alpha::Unassociated>, Color4f<Space::SceneReference, Alpha::Associated>.

This could be used to clarify the way how colors are used and we could
start hooking up (OCIO) transformation between them.

Another proposal is to use subclasses. Modern compilers are
able to remove overhead when addressing to final classes only. Benefit is that the compiler
give more understandable errors. Con is readability, With the templating internal parts are
visible and show to developers that it is something to be thinking of.

For the conversion we could use function or constructor overloading to ensure compilers can make
the right decision.

ColorSrgb src_color;
ColorSceneReference dst_color;
convert_color(&src_color, &dst_color);

/* NOTE: only allow final classes as parameter. */
void convert_color(const ColorSrgb &in_color, ColorSceneReference &r_color)
{
}

ColorSceneReference::ColorSceneReference(const ColorSrgb &in_color)
{
}

Example enum items. Space enum contains both concrete spaces limited to what we use internally and role based spaces that can be configured with OCIO.

enum class Alpha {
    /* Color is premultiplied with alpha. */
    Associated,
    /* Color isn't premultiplied with alpha. */
    Unassociated,
};

/* The roles/spaces should be limited to what blender uses internally. */
enum class Space {
    /* Internal used concrete spaces. */
    Srgb,
    Rec709,
    XYZ,
    ...

    /* Roles. */
    Rendering,
    Compositing,
    SceneReference,
    ColorPicking,
    TexturePainting,
    Timing,
    DefaultByte,
    DefaultFloat,
    ...
};
11 Likes

Extending the idea, it would be helpful to have a StoredColor that is explicit when saving color data.

Also, shouldn’t illuminants and white points be factored in or will they be part of Space?

I have been done some experiments on how to utilize compiler optimizations here.

https://developer.blender.org/P2067

I would suggest to use classes for the spaces so we can enrich them later with metadata like whitepoints and XY mappings. The Alpha could be a enum class. Internal color roles could be done using typedefs.

Personally I prefer to use the templates directly as this shows directly to the developer how to interpret the colors. The typedef roles can be convienent in areas where transformations aren’t expected to happen.

I’m in favor of this. This can prevent accidentally mixing color spaces.

2 Likes

This seems good, though it is challenging to use this across Blender, given that we have lots of C / DNA code that is hard to move to this data structure.

The risk here is that we create some complicated infrastructure and then only end up using it in a handful of places, and the color management code complexity as a whole increases.

Do you have some specific ideas on how we would roll this out? Starting in the compositor as a test? Moving imbuf/ and render/ to become C++ code? … ?

1 Like

First step would be to start with the parts that already uses BLI_color.hh.

  • Function + Geometry nodes: Already uses BLI_color.hh
  • Compostor: Is already CPP and some operations use color space conversions.
  • Color picker: There is an effort to move more UI code to CPP Color picker is one that would benefit in readability.
  • Draw manager: Although this is in limited places.
  • Blenkernel: blenkernel (colorband, gpencil, image_gen, studiolight) seems like small tweaks.

It should be checked if the buffers inside the compositor would use this (as part of the planned redesign).

Imbuf + render would need more research/design. From both I would say that render is easier as imbuf has its own color management implementation. I personally would like to work on this eventually.

Other areas would be gpencil, Movie clip, VSE, drawing code in editors, sculpting and painting, … That should be checked with these modules what their ideas and plans are concerning CPP.

I wouldn’t touch DNA or RNA. RNA currently has 2 colors (PROP_COLOR, PROP_COLOR_GAMMA) Adding this mechanism to the CPP api might be useful, but adds dependency to internal blender code.

2 Likes

There is an initial patch https://developer.blender.org/D10978
that adds the basic structure. The patch also covers the migration of function/geometry nodes.

Feedback is welcome.

1 Like