PixarAnimationStudios / OpenUSD

Universal Scene Description
http://www.openusd.org
Other
6.14k stars 1.22k forks source link

"full" material binding not working with USDIMAGINGGL_ENGINE_ENABLE_SCENE_INDEX=1 #3320

Open robpieke opened 1 month ago

robpieke commented 1 month ago

Previously, the following USD would render blue in Storm and red in RenderMan (as-expected). With USDIMAGINGGL_ENGINE_ENABLE_SCENE_INDEX=1 it renders blue in both cases.

I see there's a HdMaterialBindingsSchema::GetMaterialBinding(TfToken const &purpose) function, but it doesn't look like anything actually calls this. HdSceneIndexAdapterSceneDelegate::GetMaterialId() goes through the default (i.e., no explicit purpose).

#usda 1.0
(
    endTimeCode = 1
    framesPerSecond = 24
    metersPerUnit = 1
    startTimeCode = 1
    timeCodesPerSecond = 24
    upAxis = "Y"
)

def Xform "sphere" (
    prepend apiSchemas = ["MaterialBindingAPI"]
)
{
    rel material:binding:full = </materials/red>
    rel material:binding = </materials/blue>

    def Sphere "sphere"
    {
        double radius = 1
    }
}

def Scope "materials"
{
    def Material "red" 
    {
        token outputs:mtlx:surface.connect = </materials/red/mtlxstandard_surface.outputs:out>
        def Shader "mtlxstandard_surface"
        {
            uniform token info:id = "ND_standard_surface_surfaceshader"
            color3f inputs:base_color = (1, 0, 0) 
            token outputs:out
        }
    }
    def Material "blue" 
    {
        token outputs:mtlx:surface.connect = </materials/blue/mtlxstandard_surface.outputs:out>
        def Shader "mtlxstandard_surface"
        {
            uniform token info:id = "ND_standard_surface_surfaceshader"
            color3f inputs:base_color = (0, 0, 1) 
            token outputs:out
        }
    }
}

full

jesschimein commented 1 month ago

Filed as internal issue #USD-10198

robpieke commented 1 month ago

It's easy enough to change HdSceneIndexAdapterSceneDelegate to leverage GetRenderIndex().GetRenderDelegate()->GetMaterialBindingPurpose() and call HdMaterialBindingsSchema::GetMaterialBinding(TfToken const &purpose), which makes the reported test case pass, but I worry this is insufficient as there seem to be other calls to HdMaterialBindingsSchema::GetMaterialBinding() (i.e., the purpose-less version) scattered throughout the codebase. And by "insufficient", that might actually be "best-case" and it is possibly even worse if there is inconsistency where different codepaths are generating different material bindings.