Page MenuHome

DRW: Color Management improvement
ClosedPublic

Authored by Clément Foucault (fclem) on Feb 1 2020, 12:33 AM.

Details

Summary

As described in T72420 this patch rewrite a good portion of how the viewport pipeline is define.

The main keypoint is that:

  • Render engines (Workbench/EEVEE/GPencil/Cycles) always output/blend into a scene refered linear colorspace RGBA16F buffer.
  • The overlays are rendered separately in a SRGB8_A8 buffer that allows correct blending in linear space.
  • The overlays and the final render buffer are composited in display linear space, and during the blit to window step to avoid using another extra buffer.

The fact that Render outputs are all in scene refered linear space is very important for viewport compositing (gpencil, future realtime compositor...).

For that to work, we modified OCIO implementation to allow creating a glsl shader from two processor.
This glsl shader does the final blending step in the correct colorspace (display linear).

The current display encoded to display linear transform is only a placeholder exponent transform that does the job (tm) for now.

The OCIO GLSL backend is now faster when adjusting values that are not related to the LUT.

The Overlays code have been cleaned up to centralize all colors inside draw_common.c in order to batch convert the color to the correct display space.

The Gizmos and callbacks are rendered inside the same SRGB8_A8 buffer as the overlays but without GL_FRAMEBUFFER_SRGB enable to ensure

The UV editor renders everything to the SRGB8_A8 buffer without GL_FRAMEBUFFER_SRGB for now to avoid more code refactoring.

The Render API is modified for external engines to draw in scene linear space. So this should not cause any breakage of compatibility.

This patch is also a great step towards HDR display of the viewport.

Diff Detail

Repository
rB Blender
Branch
draw-colormanagement
Build Status
Buildable 6521
Build 6521: arc lint + arc unit

Event Timeline

Just a quick review. Still want to check this in more detail.

intern/opencolorio/fallback_impl.cc
698–699

processor_display

intern/opencolorio/ocio_impl_glsl.cc
574

We should clean up the code and remove this method can be done in a another patch.

694–695

just remove the state parameter name

source/blender/draw/engines/eevee/eevee_renderpasses.c
244

We need to check how we are going to deal with these passes. I can imagine that this design doesn't allow it currently. I added it to reflect how cycles displayed the passes. The draw engine somehow needs to communicate this back to the draw manager. Perhaps with a callback?

source/blender/draw/engines/workbench/workbench_private.h
429–430

remove else-if clause

source/blender/draw/intern/draw_color_management.c
46

Question: isn't a blit enough?
We should find a better name as this is the only CM function that actually doesn't do any CM.

source/blender/draw/intern/draw_common.c
208

We could use a CPU OCIO processor for this. This could be stored in the DRWContextState during initialization.
This can even be reused as the Scene Ref Space can only be changed after restarting blender.

source/blender/draw/intern/draw_manager.c
276

This function should check with what the draw engine actually draws (eg Active renderpass)

source/blender/gpu/intern/gpu_viewport.c
94

The end goal would be that the UV/Image editor would be part of the draw manager, where it needs to be rendered in SRS.

source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl
2

Comment needs to be updated.

source/blender/imbuf/intern/colormanagement.c
916

Should we add this to ocio config

Clément Foucault (fclem) marked 4 inline comments as done.Feb 5 2020, 12:25 AM
Clément Foucault (fclem) added inline comments.
source/blender/draw/engines/eevee/eevee_renderpasses.c
244

The issue is, Grease pencil and maybe other engine can draw on top of it. So maybe it is simpler to build this color management exception inside the drawmanager, just like we do for lookdev and rendered view.

source/blender/draw/intern/draw_color_management.c
46

Yes but blitting requires setting up framebuffers. For simplicity sake I would leave this function as is for now.

We can rename this function to DRW_draw_texture_fullscreen or something like that.

source/blender/draw/intern/draw_common.c
208

We definitely will do that. Although I would prefer to first cache these theme colors first as the transform can be slower with OCIO.

source/blender/gpu/intern/gpu_viewport.c
94

Yes that's what I also meant.

source/blender/imbuf/intern/colormanagement.c
916

The end goal would be to use an ocio role that contains the correct transform for the display. This is what the TODO is about.

Sergey Sharybin (sergey) requested changes to this revision.Feb 6 2020, 9:42 AM

Description sounds all good to me. But i am not sure what is the difference between processor and processor_display. Is it described anywhere?

Also, usual comments on style. Just an initial pass, very quickly.

intern/opencolorio/ocio_impl_glsl.cc
73

TODO: Remove or TODO(fclem): Remove

74

Could become simply: struct OCIO_GLSLCurveMappingParameters { ... };
Same applies to other structures in this file.

208–210

shader_desc, cache_id.

211–283

Always use parenthesis.

312–313

Use OBJECT_GUARDED_NEW/OBJECT_GUARDED_DELETE on the shader itself. It will call appropriate constructor/destructor without you needing to worry about individual fields.

325

const std::string& cacheId

This revision now requires changes to proceed.Feb 6 2020, 9:42 AM
Clément Foucault (fclem) marked an inline comment as done.
  • Cleanup: Update comments & fix some style issues
  • OCIO: Style fixes
  • Merge branch 'master' into draw-colormanagement
Clément Foucault (fclem) marked 5 inline comments as done.Feb 7 2020, 2:19 AM

@Sergey Sharybin (sergey) processor is the OCIO processor containing the Scene Refered Linear > Display Linear transform. The processor_display only contains the Display Linear > Display Encoded transform. For now we do this double transform but this might be avoided in some cases when we don't have any overlays.

This seems good to me (I didn't look at the draw/ module changes, assuming that's fine).

It's breaking compatibility a little bit in the sense that some render engine may not be using our GLSL display shader, but I think that's acceptable if we document it.

It would be nice if we could come up with a better term than "display linear". I think that would typically be interpreted as "color space that has a linear relation to the display space", which isn't the case here. Maybe "UI linear" or something like that.

intern/opencolorio/gpu_shader_display_transform.glsl
154–156

I don't think applying dither at this stage will work well?

I can see the problem that you want to dither the render but not the overlays, but I'm not sure that's possible efficiently. You could transform this color to display space and back just for the dither, but that seems too inefficient.

source/blender/imbuf/intern/colormanagement.c
108–109

It could help to be a bit more verbose here, like using processor_scene_to_ui and processor_ui_to_display.

Clément Foucault (fclem) marked 2 inline comments as done.
  • Address reviewers comments

I think that would typically be interpreted as "color space that has a linear relation to the display space", which isn't the case here.

The Linear term here is meant to contrast with display encoded color space. The color space is linear w.r.t. the display chromaticity and radiometry (amount of light). Not with the display encoded space. I think it is confusing to think about display space only as the display encoded space.

intern/opencolorio/gpu_shader_display_transform.glsl
154–156

Yes this is a concern. Dithering should happen last on the pipeline just before the quantization step. But doing so would mean doing it after overlays have been merged.

Doing it only on the render means having one more transform (just like you pointed out) and would be inefficient.

I wouldn't mind if we dither the overlays to be honest but users could be confused.

I think that would typically be interpreted as "color space that has a linear relation to the display space", which isn't the case here.

The Linear term here is meant to contrast with display encoded color space. The color space is linear w.r.t. the display chromaticity and radiometry (amount of light). Not with the display encoded space. I think it is confusing to think about display space only as the display encoded space.

I understand what you mean, it's just different than existing terminology in Blender and OpenColorIO. They would be considered different color spaces. For me "color space" is about semantics and "encoding" is about compression.

Anyway, not a big deal either way as long as there is a good comment or docs explaining what these color spaces are.

Think same naming suggestion from Brecht can be applied to C-API.
Other than that don't have much to comment about. Seems fine.

This revision is now accepted and ready to land.Feb 11 2020, 2:13 PM
  • Add comment about UI color space
  • Style: Rename processor arguments in C api and glsl impl.
  • Fix crash when selecting in edit mode with eevee
This revision was automatically updated to reflect the committed changes.