Skip to content

Conversation

@jstone-lucasfilm
Copy link
Member

This changelist adds an initial nodedef comparison script to MaterialX, allowing a user to compare node definitions between a data library document (e.g. stdlib_defs.mtlx) and a specification document (e.g. MaterialX.StandardNodes.md), reporting any differences between the two in their supported node sets, typed node signatures, and default values.

The new script builds upon the recent node formatting improvements proposed by the AOUSD Materials Working Group, which greatly increased the accessibility of the MaterialX specification documents to machine parsing and analysis.

GitHub CI additionally calls the nodedef comparison script on each commit to MaterialX, providing a trackable history of the alignment between data libraries and the specification.

This changelist adds an initial nodedef comparison script to MaterialX, allowing a user to compare node definitions between a data library document (e.g. stdlib_defs.mtlx) and a specification document (e.g. MaterialX.StandardNodes.md), reporting any differences between the two in their supported node sets, typed node signatures, and default values.

The new script builds upon the recent node formatting improvements proposed by the AOUSD Materials Working Group, which greatly increased the accessibility of the MaterialX specification documents to machine parsing and analysis.

GitHub CI additionally calls the nodedef comparison script on each commit to MaterialX, providing a trackable history of the alignment between data libraries and the specification.
@jstone-lucasfilm
Copy link
Member Author

Although this is just the first iteration of comparenodedefs.py, it already catches a number of meaningful differences between MaterialX.StandardNodes.md and stdlib_defs.mtlx that we can address in follow-up PRs, and the GitHub CI integration should allow us to track the alignment of our supported nodes over time.

As a starting point, here is the output of comparenodedefs.py when run today:

Comparing:
  Data Library: C:\GitHub\MaterialX\libraries\stdlib\stdlib_defs.mtlx
  Specification: C:\GitHub\MaterialX\documents\Specification\MaterialX.StandardNodes.md

Parsing specification...
  Found 140 nodes with 711 node signatures
Loading data library...
  Found 143 nodes with 689 node signatures

Comparing node signatures...

======================================================================
COMPARISON RESULTS: 122 difference(s) found
======================================================================

Nodes in Specification but not Data Library (1):
--------------------------------------------------
  displacement

Nodes in Data Library but not Specification (4):
--------------------------------------------------
  ramp
  ramp_gradient
  surfacematerial
  volumematerial

Nodes with Different Input Sets (13):
--------------------------------------------------
  dot: (in:boolean) -> out:boolean
    Extra in library: note:string
  dot: (in:color3) -> out:color3
    Extra in library: note:string
  dot: (in:color4) -> out:color4
    Extra in library: note:string
  dot: (in:filename) -> out:filename
    Extra in library: note:string
  dot: (in:float) -> out:float
    Extra in library: note:string
  dot: (in:integer) -> out:integer
    Extra in library: note:string
  dot: (in:matrix33) -> out:matrix33
    Extra in library: note:string
  dot: (in:matrix44) -> out:matrix44
    Extra in library: note:string
  dot: (in:string) -> out:string
    Extra in library: note:string
  dot: (in:vector2) -> out:vector2
    Extra in library: note:string
  dot: (in:vector3) -> out:vector3
    Extra in library: note:string
  dot: (in:vector4) -> out:vector4
    Extra in library: note:string
  time: () -> out:float
    Extra in library: fps:float

Node Signatures in Specification but not Data Library (64):
--------------------------------------------------
  hextiledimage: (file:filename, default:float, texcoord:vector2, tiling:vector2, rotation:float, rotationrange:vector2, scale:float, scalerange:vector2, offset:float, offsetrange:vector2, falloff:float, falloffcontrast:float, lumacoeffs:color3) -> out:float
  hextiledimage: (file:filename, default:vector2, texcoord:vector2, tiling:vector2, rotation:float, rotationrange:vector2, scale:float, scalerange:vector2, offset:float, offsetrange:vector2, falloff:float, falloffcontrast:float, lumacoeffs:color3) -> out:vector2
  hextiledimage: (file:filename, default:vector3, texcoord:vector2, tiling:vector2, rotation:float, rotationrange:vector2, scale:float, scalerange:vector2, offset:float, offsetrange:vector2, falloff:float, falloffcontrast:float, lumacoeffs:color3) -> out:vector3
  hextiledimage: (file:filename, default:vector4, texcoord:vector2, tiling:vector2, rotation:float, rotationrange:vector2, scale:float, scalerange:vector2, offset:float, offsetrange:vector2, falloff:float, falloffcontrast:float, lumacoeffs:color3) -> out:vector4
  ifequal: (value1:float, value2:integer) -> out:boolean
  ifequal: (value1:float, value2:integer, in1:color3, in2:color3) -> out:color3
  ifequal: (value1:float, value2:integer, in1:color4, in2:color4) -> out:color4
  ifequal: (value1:float, value2:integer, in1:float, in2:float) -> out:float
  ifequal: (value1:float, value2:integer, in1:integer, in2:integer) -> out:integer
  ifequal: (value1:float, value2:integer, in1:matrix33, in2:matrix33) -> out:matrix33
  ifequal: (value1:float, value2:integer, in1:matrix44, in2:matrix44) -> out:matrix44
  ifequal: (value1:float, value2:integer, in1:vector2, in2:vector2) -> out:vector2
  ifequal: (value1:float, value2:integer, in1:vector3, in2:vector3) -> out:vector3
  ifequal: (value1:float, value2:integer, in1:vector4, in2:vector4) -> out:vector4
  ifequal: (value1:integer, value2:float) -> out:boolean
  ifequal: (value1:integer, value2:float, in1:color3, in2:color3) -> out:color3
  ifequal: (value1:integer, value2:float, in1:color4, in2:color4) -> out:color4
  ifequal: (value1:integer, value2:float, in1:float, in2:float) -> out:float
  ifequal: (value1:integer, value2:float, in1:integer, in2:integer) -> out:integer
  ifequal: (value1:integer, value2:float, in1:matrix33, in2:matrix33) -> out:matrix33
  ifequal: (value1:integer, value2:float, in1:matrix44, in2:matrix44) -> out:matrix44
  ifequal: (value1:integer, value2:float, in1:vector2, in2:vector2) -> out:vector2
  ifequal: (value1:integer, value2:float, in1:vector3, in2:vector3) -> out:vector3
  ifequal: (value1:integer, value2:float, in1:vector4, in2:vector4) -> out:vector4
  ifgreater: (value1:float, value2:integer) -> out:boolean
  ifgreater: (value1:float, value2:integer, in1:color3, in2:color3) -> out:color3
  ifgreater: (value1:float, value2:integer, in1:color4, in2:color4) -> out:color4
  ifgreater: (value1:float, value2:integer, in1:float, in2:float) -> out:float
  ifgreater: (value1:float, value2:integer, in1:integer, in2:integer) -> out:integer
  ifgreater: (value1:float, value2:integer, in1:matrix33, in2:matrix33) -> out:matrix33
  ifgreater: (value1:float, value2:integer, in1:matrix44, in2:matrix44) -> out:matrix44
  ifgreater: (value1:float, value2:integer, in1:vector2, in2:vector2) -> out:vector2
  ifgreater: (value1:float, value2:integer, in1:vector3, in2:vector3) -> out:vector3
  ifgreater: (value1:float, value2:integer, in1:vector4, in2:vector4) -> out:vector4
  ifgreater: (value1:integer, value2:float) -> out:boolean
  ifgreater: (value1:integer, value2:float, in1:color3, in2:color3) -> out:color3
  ifgreater: (value1:integer, value2:float, in1:color4, in2:color4) -> out:color4
  ifgreater: (value1:integer, value2:float, in1:float, in2:float) -> out:float
  ifgreater: (value1:integer, value2:float, in1:integer, in2:integer) -> out:integer
  ifgreater: (value1:integer, value2:float, in1:matrix33, in2:matrix33) -> out:matrix33
  ifgreater: (value1:integer, value2:float, in1:matrix44, in2:matrix44) -> out:matrix44
  ifgreater: (value1:integer, value2:float, in1:vector2, in2:vector2) -> out:vector2
  ifgreater: (value1:integer, value2:float, in1:vector3, in2:vector3) -> out:vector3
  ifgreater: (value1:integer, value2:float, in1:vector4, in2:vector4) -> out:vector4
  ifgreatereq: (value1:float, value2:integer) -> out:boolean
  ifgreatereq: (value1:float, value2:integer, in1:color3, in2:color3) -> out:color3
  ifgreatereq: (value1:float, value2:integer, in1:color4, in2:color4) -> out:color4
  ifgreatereq: (value1:float, value2:integer, in1:float, in2:float) -> out:float
  ifgreatereq: (value1:float, value2:integer, in1:integer, in2:integer) -> out:integer
  ifgreatereq: (value1:float, value2:integer, in1:matrix33, in2:matrix33) -> out:matrix33
  ifgreatereq: (value1:float, value2:integer, in1:matrix44, in2:matrix44) -> out:matrix44
  ifgreatereq: (value1:float, value2:integer, in1:vector2, in2:vector2) -> out:vector2
  ifgreatereq: (value1:float, value2:integer, in1:vector3, in2:vector3) -> out:vector3
  ifgreatereq: (value1:float, value2:integer, in1:vector4, in2:vector4) -> out:vector4
  ifgreatereq: (value1:integer, value2:float) -> out:boolean
  ifgreatereq: (value1:integer, value2:float, in1:color3, in2:color3) -> out:color3
  ifgreatereq: (value1:integer, value2:float, in1:color4, in2:color4) -> out:color4
  ifgreatereq: (value1:integer, value2:float, in1:float, in2:float) -> out:float
  ifgreatereq: (value1:integer, value2:float, in1:integer, in2:integer) -> out:integer
  ifgreatereq: (value1:integer, value2:float, in1:matrix33, in2:matrix33) -> out:matrix33
  ifgreatereq: (value1:integer, value2:float, in1:matrix44, in2:matrix44) -> out:matrix44
  ifgreatereq: (value1:integer, value2:float, in1:vector2, in2:vector2) -> out:vector2
  ifgreatereq: (value1:integer, value2:float, in1:vector3, in2:vector3) -> out:vector3
  ifgreatereq: (value1:integer, value2:float, in1:vector4, in2:vector4) -> out:vector4

Node Signatures in Data Library but not Specification (40):
--------------------------------------------------
  convert: (in:boolean) -> out:surfaceshader
  convert: (in:color3) -> out:surfaceshader
  convert: (in:color4) -> out:surfaceshader
  convert: (in:float) -> out:surfaceshader
  convert: (in:integer) -> out:surfaceshader
  convert: (in:vector2) -> out:surfaceshader
  convert: (in:vector3) -> out:surfaceshader
  convert: (in:vector4) -> out:surfaceshader
  dot: (in:displacementshader, note:string) -> out:displacementshader
  dot: (in:lightshader, note:string) -> out:lightshader
  dot: (in:surfaceshader, note:string) -> out:surfaceshader
  dot: (in:volumeshader, note:string) -> out:volumeshader
  fractal2d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, texcoord:vector2) -> out:color3
  fractal2d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, texcoord:vector2) -> out:color4
  fractal2d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, texcoord:vector2) -> out:vector2
  fractal2d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, texcoord:vector2) -> out:vector3
  fractal2d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, texcoord:vector2) -> out:vector4
  fractal2d: (amplitude:vector3, octaves:integer, lacunarity:float, diminish:float, texcoord:vector2) -> out:color3
  fractal2d: (amplitude:vector4, octaves:integer, lacunarity:float, diminish:float, texcoord:vector2) -> out:color4
  fractal3d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, position:vector3) -> out:color3
  fractal3d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, position:vector3) -> out:color4
  fractal3d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, position:vector3) -> out:vector2
  fractal3d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, position:vector3) -> out:vector3
  fractal3d: (amplitude:float, octaves:integer, lacunarity:float, diminish:float, position:vector3) -> out:vector4
  fractal3d: (amplitude:vector3, octaves:integer, lacunarity:float, diminish:float, position:vector3) -> out:color3
  fractal3d: (amplitude:vector4, octaves:integer, lacunarity:float, diminish:float, position:vector3) -> out:color4
  noise2d: (amplitude:float, pivot:float, texcoord:vector2) -> out:color3
  noise2d: (amplitude:float, pivot:float, texcoord:vector2) -> out:color4
  noise2d: (amplitude:float, pivot:float, texcoord:vector2) -> out:vector2
  noise2d: (amplitude:float, pivot:float, texcoord:vector2) -> out:vector3
  noise2d: (amplitude:float, pivot:float, texcoord:vector2) -> out:vector4
  noise2d: (amplitude:vector3, pivot:float, texcoord:vector2) -> out:color3
  noise2d: (amplitude:vector4, pivot:float, texcoord:vector2) -> out:color4
  noise3d: (amplitude:float, pivot:float, position:vector3) -> out:color3
  noise3d: (amplitude:float, pivot:float, position:vector3) -> out:color4
  noise3d: (amplitude:float, pivot:float, position:vector3) -> out:vector2
  noise3d: (amplitude:float, pivot:float, position:vector3) -> out:vector3
  noise3d: (amplitude:float, pivot:float, position:vector3) -> out:vector4
  noise3d: (amplitude:vector3, pivot:float, position:vector3) -> out:color3
  noise3d: (amplitude:vector4, pivot:float, position:vector3) -> out:color4

Copy link
Contributor

@niklasharrysson niklasharrysson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fantastic! Will be super useful for tracking differences between the data libraries and the specification.

@jstone-lucasfilm jstone-lucasfilm merged commit e0f8e15 into AcademySoftwareFoundation:main Dec 16, 2025
33 checks passed
@jstone-lucasfilm jstone-lucasfilm deleted the dev_compare_nodedefs branch December 16, 2025 16:22
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