AcademySoftwareFoundation / MaterialX

MaterialX is an open standard for the exchange of rich material and look-development content across applications and renderers.
http://www.materialx.org/
Apache License 2.0
1.83k stars 335 forks source link

Custom output doesn't work #623

Closed numega closed 2 years ago

numega commented 3 years ago

I believe the MaterialX file listed below should work. However, I get the following warnings:

Mismatched types in port connection: <input name="diffuseColor" type="color3" nodename="myfunc1" member="color">
Mismatched types in port connection: <input name="roughness" type="float" nodename="myfunc1" member="roughness">

After printing the warnings, MaterialView crashes on this line due to type being a nullptr: throw ExceptionShaderGenError("No syntax is defined for the given type '" + type->getName() + "'.");

<?xml version="1.0"?>
<materialx version="1.38" colorspace="lin_rec709">
    <typedef name="myoutput">
        <member name="color" type="color3"/>
        <member name="roughness" type="float"/>
    </typedef>
    <nodedef name="ND_myfunc_myoutput" node="myfunc">
        <input name="in1" type="color3" value="0.5, 0, 0"/>
        <input name="in2" type="color3" value="0.5, 0, 0"/>
        <output name="out1" type="myoutput"/>
    </nodedef>
    <implementation name="IM_myfunc_myoutput" nodedef="ND_myfunc_myoutput" file="blah2.glsl" function="myfunc"/>
    <myfunc name="myfunc1" type="myoutput">
        <input name="in1" type="color3" value="0, 0.5, 0"/>
        <input name="in2" type="color3" value="0, 0.5, 0"/>
    </myfunc>
    <UsdPreviewSurface name="SR_default" type="surfaceshader">
        <input name="diffuseColor" type="color3" nodename="myfunc1" member="color"/>
        <input name="roughness" type="float" nodename="myfunc1" member="roughness"/>
    </UsdPreviewSurface>
    <surfacematerial name="mymaterial" type="material">
        <input name="surfaceshader" type="surfaceshader" nodename="SR_default"/>
    </surfacematerial>
</materialx>

I'm not sure how blah2.glsl should be written in this case, but this is what I'm trying:

void myfunc(vec3 in1, vec3 in2, out myoutput out1)
{
    out1.color = in1 + in2;
    out1.roughness = 0.5;
}
bernardkwok commented 3 years ago

Unfortunately at this time custom output types like the struct you have is not supported by code generation.

For the case shown here, the "myoutput" struct will need to be split into two separate outputs on your "myfunc" definition. These can then be connected to (as opposed to members of the output).

For the implementation, I think the following should work:

void myfunc(vec3 in1, vec3 in2, out vec3 color, out float roughness)
{
    color = in1 + in2;
    roughness = 0.5;
}

If not then a nodegraph based implementation may be required.

jstone-lucasfilm commented 2 years ago

Thanks for this report, @numega, and @bernardkwok is correct that member elements have never been supported in the MaterialX code generators.

Our current sense is that multi-output nodes are a better solution to the problem that member elements were originally proposed to solve, and we're leaning towards removing member elements from the 1.39 specification.

If you'd like to join the conversation around the 1.39 specification, we'd definitely appreciate your input on the MaterialX channel of the ASWF Slack:

https://www.materialx.org/DiscForum.html

For now, I'll close this original report, and we can continue the discussion on the ASWF Slack as needed.