MaterialX icon indicating copy to clipboard operation
MaterialX copied to clipboard

Regression: multiple color conversions generated in shader for nested multioutput image nodes

Open rasmusbonnedal opened this issue 1 year ago • 3 comments

Description

@bowald found that <gltf_colorimage> generated very dark images in 1.38.10 (and 1.38.9). We have investigated and found that there seem to be a regression in 1.38.9 (Possibly https://github.com/AcademySoftwareFoundation/MaterialX/commit/d63431144a01eae129cd720222e530aff36b3459).

To reproduce

The requirements for triggering this issue is:

  1. An "inner" node which uses an <image> node and exposes the filename input in its interface
  2. An "outer" node which uses the "inner" node, is multioutput and also exposes the filename input in its interface

In that case shadergen will generate a colorspace transform for both nodes which in our case will apply srgb_texture to linrec_709 twice resulting in a very dark image.

repro.zip

Expected result

(From 1.38.8) result_1 38 8

void NG_image_inner(textureresource  file, output color output1)
{
    vector2 geomprop_UV0_out1 = vector2(u,v);
    color image0_image_test_out = color(0.0);
    mx_image_color3(file, "", color(0, 0, 0), geomprop_UV0_out1, "periodic", "periodic", "linear", "", 0, "constant", image0_image_test_out);
    output1 = image0_image_test_out;
}

void NG_image_outer(textureresource  file, output color output1, output float output2)
{
    color image0_image_test_4_output1 = color(0.0);
    NG_image_inner(file, image0_image_test_4_output1);
    output1 = image0_image_test_4_output1;
    output2 = 0.5;
}

NG_image_outer(image_test4_file, image_test4_output1, image_test4_output2);
color image_test4_output1_cm_out = color(0.0);
NG_srgb_texture_to_lin_rec709_color3(image_test4_output1, image_test4_output1_cm_out);

Actual result

(From 1.38.10) result_1 38 10

void NG_image_inner(textureresource  file, output color output1)
{
    vector2 geomprop_UV0_out1 = vector2(u,v);
    color image0_image_test_out = color(0.0);
    mx_image_color3(file, "", color(0.000000, 0.000000, 0.000000), geomprop_UV0_out1, "periodic", "periodic", "linear", "", 0, "constant", image0_image_test_out);
    color image0_image_test_out_cm_out = color(0.0);
    NG_srgb_texture_to_lin_rec709_color3(image0_image_test_out, image0_image_test_out_cm_out);
    output1 = image0_image_test_out_cm_out;
}

void NG_image_outer(textureresource  file, output color output1, output float output2)
{
    color image0_image_test_4_output1 = color(0.0);
    NG_image_inner(file, image0_image_test_4_output1);
    color image0_image_test_4_output1_cm_out = color(0.0);
    NG_srgb_texture_to_lin_rec709_color3(image0_image_test_4_output1, image0_image_test_4_output1_cm_out);
    output1 = image0_image_test_4_output1_cm_out;
    output2 = 0.500000;
}

NG_image_outer(image_test4_file_, image_test4_output1, image_test4_output2);
surfaceshader standard_surface_out = surfaceshader(null_closure, null_closure, 1.0);

rasmusbonnedal avatar Jan 13 '25 10:01 rasmusbonnedal

Hi @rasmusbonnedal Can you confirm if this occurs if you explicitly set the target colorspace in the baking context using context.getOptions().targetColorSpaceOverride = linrec_709

I'm wondering if this is because the getActiveColorSpace is empty.

ashwinbhat avatar Jan 13 '25 17:01 ashwinbhat

We already have that:

    auto& contextOptionsOSL = _contextOSL.getOptions();
    contextOptionsOSL.targetColorSpaceOverride = "lin_rec709";

rasmusbonnedal avatar Jan 14 '25 07:01 rasmusbonnedal

Update

This issue seemed to be solved in MaterialX 1.39.3 for OSL code generation

Result

(From 1.39.3)

Image

void NG_image_inner(textureresource  file, output color output1)
{
    vector2 geomprop_UV0_out1 = vector2(u,v);
    color image0_image_test_out = color(0.0);
    mx_image_color3(file, "", color(0.000000, 0.000000, 0.000000), geomprop_UV0_out1, "periodic", "periodic", "linear", "", 0, "constant", image0_image_test_out);
    output1 = image0_image_test_out;
}

void NG_image_outer(textureresource  file, output color output1, output float output2)
{
    color image0_image_test_4_output1 = color(0.0);
    NG_image_inner(file, image0_image_test_4_output1);
    output1 = image0_image_test_4_output1;
    output2 = 0.500000;
}

NG_image_outer(image_test4_file_, image_test4_output1, image_test4_output2);
color image_test4_output1_cm_out = color(0.0);
NG_srgb_texture_to_lin_rec709_color3(image_test4_output1, image_test4_output1_cm_out);

bowald avatar Jun 11 '25 12:06 bowald