Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document edge case for image nodes #1776

Conversation

jstone-lucasfilm
Copy link
Member

This changelist documents an edge case in the handling of image node channels, improving the robustness of the MaterialX specification, and aligning it with the current behavior of the MaterialX codebase.

This changelist documents an edge case in the handling of image node channels, improving the robustness of the MaterialX specification, and aligning it with the current behavior of the MaterialX codebase.
@meshula
Copy link

meshula commented Apr 18, 2024

Question about the behavior, as it doesn't match what we do in USD imaging. If the original image was RGBA, and the alt is RGB, I think RGB1 makes more sense than RGB0, especially if one is treating the image as premultiplied. In other words, we fill in channels with zero yes, but alpha is filled with one. Principle of least surprise, and more correct.

@jstone-lucasfilm
Copy link
Member Author

jstone-lucasfilm commented Apr 18, 2024

That's a really interesting proposal, @meshula.

If we were to follow the line of thought you suggest here, then perhaps it would be more consistent to state that referenced image data is processed through a convert node when its type differs from that of the image node?

The rule set for convert nodes handles the RGB1 case that you mention here, but it also contains several additional rules for consistent reinterpretation of data between types.

These rules are stated here in the specification, and I'll copy the relevant details below:

The following input/output data type conversions are supported by convert:

float to colorN/vectorN: copy the input value to all channels of the output
colorN to vectorN / vectorN to colorN, where N is the same for in and out: straight copy of channel values
color3 to color4: copy RGB, set output alpha to 1.0
color4 to color3: drop alpha channel
boolean or integer to float: output is 0.0 or 1.0
vector2 to vector3, or vector3 to vector4: copy incoming channels and append an additional channel with value 1.0 (e.g. convert from non-homogeneous to homogeneous vector)
vector3 to vector2, or vector4 to vector3: drop the last channel

@meshula
Copy link

meshula commented Apr 18, 2024

That sounds preferable indeed.

@jstone-lucasfilm
Copy link
Member Author

@meshula I'd be fine with moving over to that approach in MaterialX, as long as these rules would be acceptable to the USD team as well. Does that sound like a path forward that would work for both teams?

@meshula
Copy link

meshula commented Apr 19, 2024

Here is the algorithm that we have, maybe we can work to reconcile differences. Note that UINT textures have an odd behavior, but I think that specific behavior does not matter to MaterialX?

The fundamental difference we have is that we are propagating missing channels and your rules are appending a 1. I will send you a note as to why this is.

    // if the image has more channels than actually read, and any of the channels 
    // is missing, fill them in by propagating the channel to the left if 
    // possible. If not, fill with zero, unless it is the alpha channel. Alpha is always filled with one.

 if (img->channelCount > readChannelCount) {
        if (img->channelCount == 4 && alphaMissing) {
            // fill the alpha channel with 1.0
                ..... details omitted
            else if (img->pixelType == EXR_PIXEL_UINT) {
                // We're treating uint data as data, not rgba, so fill with zero
                .... details
            }
        }
        if (img->channelCount > 2 && blueMissing) {
            // if G exists, propagate it, else if R exists, propagate it, else fill with zero
            .... details
        }
        if (img->channelCount > 1 && green missing) {
            // if R exists, propagate it, else fill with zero
            .... details
        }
        if (redMissing) {
           // no R, fill with zero
           .... details
        }
  }

@jstone-lucasfilm
Copy link
Member Author

@meshula I'd recommend that we take this update in two steps, first aligning the specification and codebase for MaterialX, and then updating both in tandem to propose a new expected behavior for image nodes. If that sounds fine to you, then I'll merge this existing change, and add a new GitHub Issue for the additional change proposed here.

@jstone-lucasfilm
Copy link
Member Author

I've added a corresponding GitHub Issue for this proposal here:

#1797

@jstone-lucasfilm jstone-lucasfilm changed the title AOUSD: Document edge case for image nodes Document edge case for image nodes Apr 30, 2024
@jstone-lucasfilm jstone-lucasfilm merged commit e2659ba into AcademySoftwareFoundation:dev_1.39 Apr 30, 2024
1 check passed
@jstone-lucasfilm jstone-lucasfilm deleted the dev_aousd_1.39 branch April 30, 2024 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants