material-mdl-source-asset#
Code |
VM.MDL.001 |
|---|---|
Validator |
|
Compatibility |
open-usd |
Tags |
✅ |
Summary#
An MDL shader’s info:mdl:sourceAsset must name an existing .mdl file by an anchored path.
Description#
The subject is a Shader prim inside a Material whose info:implementationSource is
sourceAsset. Such a shader takes its implementation from an MDL module on disk, and
info:mdl:sourceAsset is the path to that module. A shader that does not declare
sourceAsset is outside this requirement.
The path must:
Be authored on the shader
Be non-empty
End in
.mdlStart with
./or../, or be absoluteResolve to a file that exists
A path that is neither anchored nor absolute is resolved through the MDL search path, so which module it names depends on how the runtime is configured. An absolute path resolves deterministically and is not reported here; AA.001 covers it as a portability matter for every asset reference.
Conditions 3 to 5 are read independently, so one path can be reported under more than one of them.
Modules the runtime ships#
Conditions 4 and 5 do not apply to an MDL module the runtime ships and resolves for itself —
OmniPBR.mdl, OmniGlass.mdl, OmniSurface.mdl and the rest of that set, including the
nvidia/core_definitions.mdl prefixed form. A reference to one is authored as the bare module
name deliberately.
Kit ties an MDL module’s identity to its location on disk, so a copy inside the asset is a
different module rather than the same one packaged. The module therefore stays where the
runtime installed it, and the asset names it rather than shipping it. Anchoring such a
reference makes it a layer-relative asset path that USD resolves against the referencing
layer, where nothing is present: ./OmniPBR.mdl in an asset that does not contain
OmniPBR.mdl resolves to nothing at all. The two conditions cannot both be met, which is why
neither is asked.
The set is matched by module name, case-insensitively, so a project-local copy at an explicit path is treated the same way — that copy cannot be relocated into the asset and remain the same module.
Why is it required?#
Broken material references
Non-portable assets
Inconsistent rendering
Examples#
The attribute sits on the Shader prim, alongside info:implementationSource and the
subIdentifier naming the material inside the module. It is not prim metadata on the
Material.
Valid: a relative path to a module that is there#
def Material "opaque__metal__bracket"
{
token outputs:mdl:surface.connect = </opaque__metal__bracket/Shader.outputs:out>
def Shader "Shader"
{
uniform token info:implementationSource = "sourceAsset"
uniform asset info:mdl:sourceAsset = @./materials/OmniPBR/OmniPBR.mdl@
uniform token info:mdl:sourceAsset:subIdentifier = "OmniPBR"
token outputs:out
}
}
Invalid: no .mdl extension#
def Material "opaque__metal__bracket"
{
token outputs:mdl:surface.connect = </opaque__metal__bracket/Shader.outputs:out>
def Shader "Shader"
{
uniform token info:implementationSource = "sourceAsset"
uniform asset info:mdl:sourceAsset = @./materials/OmniPBR/OmniPBR@
uniform token info:mdl:sourceAsset:subIdentifier = "OmniPBR"
token outputs:out
}
}
This path is reported twice: once for the extension, and once because no file resolves at it.
Invalid: a path resolved through the MDL search path#
def Material "opaque__metal__bracket"
{
token outputs:mdl:surface.connect = </opaque__metal__bracket/Shader.outputs:out>
def Shader "Shader"
{
uniform token info:implementationSource = "sourceAsset"
uniform asset info:mdl:sourceAsset = @materials/OmniPBR/OmniPBR.mdl@
uniform token info:mdl:sourceAsset:subIdentifier = "OmniPBR"
token outputs:out
}
}
The module is at the path given, so this is reported for the prefix alone.
Invalid: the module is not there#
def Material "opaque__metal__bracket"
{
token outputs:mdl:surface.connect = </opaque__metal__bracket/Shader.outputs:out>
def Shader "Shader"
{
uniform token info:implementationSource = "sourceAsset"
uniform asset info:mdl:sourceAsset = @./materials/OmniPBR/Unknown.mdl@
uniform token info:mdl:sourceAsset:subIdentifier = "OmniPBR"
token outputs:out
}
}
# Valid: Parent-relative path to existing MDL
def Material "ValidParentRelative" (
info:mdl:sourceAsset = @../source_assets/OmniPBR.mdl@
)
{
}
How to comply#
Author
info:mdl:sourceAsseton every shader that declaresinfo:implementationSource = "sourceAsset"Give it a path ending in
.mdlAnchor the path with
./or../, so it resolves against the referencing layer rather than the MDL search pathLeave a module the runtime ships named as it is, and do not package a copy of it
Ship the module at that path