AgX-Step2: Use OCIO's built-in function for sRGB #110712

Merged
Sergey Sharybin merged 6 commits from :AgX-Step2 into main 2023-08-07 17:52:35 +02:00
Contributor

This is the step 2 of AgX implementation as discussed in the original PR

step 2. Use OCIO's built-in functionality for sRGB, includes changing sRGB to be un-clipped

This is the step 2 of AgX implementation as discussed [in the original PR](https://projects.blender.org/blender/blender/pulls/106355#issuecomment-984699) > step 2. Use OCIO's built-in functionality for sRGB, includes changing sRGB to be un-clipped
Zijun Zhou added 3 commits 2023-08-02 06:29:47 +02:00
Zijun Zhou requested review from Sergey Sharybin 2023-08-02 06:30:35 +02:00
Zijun Zhou requested review from Brecht Van Lommel 2023-08-02 06:30:48 +02:00
Nathan Vegdahl approved these changes 2023-08-02 11:40:55 +02:00
Nathan Vegdahl left a comment
Member

Looks good to me!

Some notes for other reviewers:

The expanded version of ExponentWithLinearTransform looks like:

!<ExponentWithLinearTransform> { gamma: [r, g, b, a], offset: [r, g, b, a], style: <linear | mirror>, direction: <inverse | forward> }

Which allows different values to be used for different channels. The style parameter determines how negative values are handled.

Unfortunately, because OCIO is (extremely) poorly documented, it's difficult to look up what happens in the abbreviated form. However, I've verified that the following things are true by sifting through OCIO's source code:

  • The single-value forms of gamma and offset set the r, g, and b values to the provided value, but set alpha to 1.0 and 0.0, respectively. This is what we want, because alpha should be left alone.
  • The default value for style is linear, which continues the linear segment into the negative values without clamping. I think this is probably what we want, since this allows round-tripping when needed, and code that needs >= 0 values (i.e. image file writers) will presumably clamp it themselves if needed. Moreover, proper handling would require gamut clipping prior to the transform anyway.
Looks good to me! Some notes for other reviewers: The expanded version of `ExponentWithLinearTransform` looks like: ``` !<ExponentWithLinearTransform> { gamma: [r, g, b, a], offset: [r, g, b, a], style: <linear | mirror>, direction: <inverse | forward> } ``` Which allows different values to be used for different channels. The `style` parameter determines how negative values are handled. Unfortunately, because OCIO is (extremely) poorly documented, it's difficult to look up what happens in the abbreviated form. However, I've verified that the following things are true by sifting through OCIO's source code: - The single-value forms of `gamma` and `offset` set the r, g, and b values to the provided value, but set alpha to `1.0` and `0.0`, respectively. This is what we want, because alpha should be left alone. - The default value for `style` is `linear`, which continues the linear segment into the negative values without clamping. I think this is probably what we want, since this allows round-tripping when needed, and code that needs >= 0 values (i.e. image file writers) will presumably clamp it themselves if needed. Moreover, proper handling would require gamut clipping prior to the transform anyway.

@blender-bot build

@blender-bot build

@blender-bot build

@blender-bot build

From testing locally the compositor_matte_test fails the keying matte test. It seems that the node is very sensitive to precision. I.e. it seems to give different result when a hard-wired srgb_to_linearrgb_v3_v3 is sued with and without SSE. So this I think will fall under "known side effects".

The clamping of negative values should not happen in the OCIO configuration. This will match the currently used LUT more closely (which allows negative colors between -0.125 and 0). From quick look the "extension" policy seems to also be linear in the current LUT. Since the mapping already allows negative values, I'd expect code which expects clamping is already doing so.

From testing locally the `compositor_matte_test` fails the keying matte test. It seems that the node is very sensitive to precision. I.e. it seems to give different result when a hard-wired `srgb_to_linearrgb_v3_v3` is sued with and without SSE. So this I think will fall under "known side effects". The clamping of negative values should not happen in the OCIO configuration. This will match the currently used LUT more closely (which allows negative colors between -0.125 and 0). From quick look the "extension" policy seems to also be linear in the current LUT. Since the mapping already allows negative values, I'd expect code which expects clamping is already doing so.

Something fishy is going on. All platforms except of Apple Silicon have some real regressions. There is an example screenshot of the result of the image_alpha_blend.blend.

I can confirm the regression on Linux box, but did not have time yet to dig into details.
And to be clear: I can not reproduce the issue on Apple M2.

Something fishy is going on. All platforms except of Apple Silicon have some real regressions. There is an example screenshot of the result of the [image_alpha_blend.blend](https://svn.blender.org/svnroot/bf-blender/trunk/lib/tests/render/image_colorspace/image_alpha_blend.blend). I can confirm the regression on Linux box, but did not have time yet to dig into details. And to be clear: I can not reproduce the issue on Apple M2.
Sergey Sharybin requested changes 2023-08-02 13:01:57 +02:00
Sergey Sharybin left a comment
Owner

Since there are real unexpected changes marking it as Requested Changes as some work needs to be done to solve those.

Since there are real unexpected changes marking it as Requested Changes as some work needs to be done to solve those.

@Eary I am looking into the failure. There is something odd going on even with the current OCIO configuration. Seems like the OCIO is doing different things depending on which direction the transform is defined.

I'll post later once investigation is finished.

@Eary I am looking into the failure. There is something odd going on even with the current OCIO configuration. Seems like the OCIO is doing different things depending on which direction the transform is defined. I'll post later once investigation is finished.

Turns out there are few things here.

Long story short: this PR is actually correct. It just uncovers issue which is already in Blender's codebase.
What's going on is a fiasco of Cycles trying to be too smart, unfortunately.

First aspect is the lovely piece of code around ColorSpaceManager::is_builtin_colorspace() which checks whether a colorspace seems to be sRGB or linear. It does it by comparing 256 points of colors representing in the 0 .. 1 range. For the linear space the code expects a unity conversion, and for sRGB it expects to be close to a function implemented in C color_srgb_to_linear.

One of the issues with this code is that either epsilon needs to be high enough, or it will not detect a sRGB definition as such. For example, removing to_reference: !<FileTransform> {src: srgb.spi1d, interpolation: linear} from the current config.ocio configuration will make the code to NOT detect the sRGB space as such. Similarly, using an analytical piece-wise function in the config.ocio (as this PR proposes) does the same: the color space is no longer considered to be sRGB.

Another issue with this code is that it is not very logically correct. According to the logic in this function a color space like Guard Rail color space will be considered as a built-in, because they do not modify values within the 0 .. 1 range.

The second aspect seems to be a discrepancy of how alpha is handled by the CPU-side slow OCIO code path and the render-time "fast" (also often more memory efficient due to use of uint8 storage) code path. The latter one will only un-associate alpha if the alpha socket is connected to something (and the image is not a data/non-color). The former one will un-associate alpha prior to the color space conversion based on the number of channels in the file.
I might have gotten details here a bit wrong, but the point is: the handling of alpha channel w.r.t color space conversion in "slow" and "fast" code paths is different.

Turns out there are few things here. Long story short: this PR is actually correct. It just uncovers issue which is already in Blender's codebase. What's going on is a fiasco of Cycles trying to be too smart, unfortunately. First aspect is the lovely piece of code around `ColorSpaceManager::is_builtin_colorspace()` which checks whether a colorspace seems to be sRGB or linear. It does it by comparing 256 points of colors representing in the 0 .. 1 range. For the linear space the code expects a unity conversion, and for sRGB it expects to be close to a function implemented in C `color_srgb_to_linear`. One of the issues with this code is that either epsilon needs to be high enough, or it will not detect a sRGB definition as such. For example, removing `to_reference: !<FileTransform> {src: srgb.spi1d, interpolation: linear}` from the current `config.ocio` configuration will make the code to NOT detect the sRGB space as such. Similarly, using an analytical piece-wise function in the `config.ocio` (as this PR proposes) does the same: the color space is no longer considered to be sRGB. Another issue with this code is that it is not very logically correct. According to the logic in this function a color space like Guard Rail color space will be considered as a built-in, because they do not modify values within the 0 .. 1 range. The second aspect seems to be a discrepancy of how alpha is handled by the CPU-side slow OCIO code path and the render-time "fast" (also often more memory efficient due to use of uint8 storage) code path. The latter one will only un-associate alpha if the alpha socket is connected to something (and the image is not a data/non-color). The former one will un-associate alpha prior to the color space conversion based on the number of channels in the file. I might have gotten details here a bit wrong, but the point is: the handling of alpha channel w.r.t color space conversion in "slow" and "fast" code paths is different.
Sergey Sharybin added 1 commit 2023-08-07 14:34:40 +02:00
buildbot/vexp-code-patch-coordinator Build done. Details
daa17bdcc4
Merge branch 'main' into AgX-Step2

@blender-bot build

@blender-bot build

We relaxed the checks a little bit (#110889), so both the from_reference: !<FileTransform> {src: srgb_inv.spi1d, interpolation: linear} (without to_reference) and the from_reference: !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0.055, direction: inverse} are detected as "built-in".

Would still be good to make it so the run-time and pre-processing-time alpha handling are consistent, and improve the naming of the color space check probing (to somehow indicate it is only used for the memory-optimized 8bit access or so), but it is a separate story and is not a blocker from this PR perspective.

I've poked the buildbot to verify this PR with my commit included. Hopefully it passes the check, and we can land this PR soon!

We relaxed the checks a little bit (#110889), so both the `from_reference: !<FileTransform> {src: srgb_inv.spi1d, interpolation: linear} ` (without `to_reference`) and the `from_reference: !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0.055, direction: inverse}` are detected as "built-in". Would still be good to make it so the run-time and pre-processing-time alpha handling are consistent, and improve the naming of the color space check probing (to somehow indicate it is only used for the memory-optimized 8bit access or so), but it is a separate story and is not a blocker from this PR perspective. I've poked the buildbot to verify this PR with my commit included. Hopefully it passes the check, and we can land this PR soon!
Sergey Sharybin added 1 commit 2023-08-07 15:54:42 +02:00
buildbot/vexp-code-patch-coordinator Build done. Details
c64864d45a
Merge branch 'main' into AgX-Step2

@blender-bot build

@blender-bot build
Sergey Sharybin added 1 commit 2023-08-07 16:47:48 +02:00
buildbot/vexp-code-patch-coordinator Build done. Details
3c8ea03d5d
Merge branch 'main' into AgX-Step2

@blender-bot build

@blender-bot build

The struggle continues, but getting closer!

Apparently, it is not that easy to match the matte node across all the platforms we support. It is so sensitive to the exact values.
So increased tolerance there as well (#110897).

The struggle continues, but getting closer! Apparently, it is not that easy to match the matte node across all the platforms we support. It is so sensitive to the exact values. So increased tolerance there as well (#110897).
Sergey Sharybin approved these changes 2023-08-07 17:48:23 +02:00
Sergey Sharybin merged commit f5e567b4a8 into main 2023-08-07 17:52:35 +02:00
Sergey Sharybin deleted branch AgX-Step2 2023-08-07 17:52:37 +02:00
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#110712
No description provided.