Skip to content

Proposal : Deterministic Default Instance Resolution - #3028

Open
kwokcb wants to merge 3 commits into
AcademySoftwareFoundation:mainfrom
kwokcb:isdefaultversion_proposal
Open

Proposal : Deterministic Default Instance Resolution #3028
kwokcb wants to merge 3 commits into
AcademySoftwareFoundation:mainfrom
kwokcb:isdefaultversion_proposal

Conversation

@kwokcb

@kwokcb kwokcb commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Deterministic Default Instance Resolution

Issue

For node definition categories which have two or more nodedef variants with the same output type but different input arguments, if insufficient input arguments are specified the logic to indicate which variant instantiate is undefined.

For MaterialX core the variant chosen is the first one found in memory -- thus if the order of loading (placement in the MaterialX document ) differs than the variant chosen may change. Any integration using MaterialX may choose their own logic which can be inconsistent as well.

Proposal

Allow for definitions with the same category to specify isdefaultversion = true to indicate which definition variant is being instantiate when ambiguous.

The current requirement that only one variant may set isdefaultversion does not change..

Changes to existing specification

  • "Loosen" the current specification language to indicate that a version attribute does not need to be specified for isdefaultversion to be specified.

Examples

Existing Definitions

randomcolor differs only in in which may be a float or integer.

<nodedef name="ND_randomcolor_float" node="randomcolor" nodegroup="procedural3d">
    <input name="in" type="float" uiname="Input" uisoftmin="0.0" uisoftmax="10.0" value="0.0" />
    <input name="huelow" type="float" uiname="Hue Low" uisoftmin="0.0" uisoftmax="1.0" value="0" />
    <input name="huehigh" type="float" uiname="Hue High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="saturationlow" type="float" uiname="Saturation Low" uisoftmin="0.0" uisoftmax="1.0" value="0.825" />
    <input name="saturationhigh" type="float" uiname="Saturation High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="brightnesslow" type="float" uiname="Brightness Low" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="brightnesshigh" type="float" uiname="Brightness High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="seed" type="integer" uiname="Seed" value="0" />
    <output name="out" type="color3" />
  </nodedef>
  <nodedef name="ND_randomcolor_integer" node="randomcolor" nodegroup="procedural3d">
    <input name="in" type="integer" uiname="Input" uisoftmin="0" uisoftmax="10" value="0" />
    <input name="huelow" type="float" uiname="Hue Low" uisoftmin="0.0" uisoftmax="1.0" value="0" />
    <input name="huehigh" type="float" uiname="Hue High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="saturationlow" type="float" uiname="Saturation Low" uisoftmin="0.0" uisoftmax="1.0" value="0.825" />
    <input name="saturationhigh" type="float" uiname="Saturation High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="brightnesslow" type="float" uiname="Brightness Low" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="brightnesshigh" type="float" uiname="Brightness High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="seed" type="integer" uiname="Seed" value="0" />
    <output name="out" type="color3" />
  </nodedef>

normalmap is another example which only differs in scale type

<nodedef name="ND_normalmap_float" node="normalmap" nodegroup="math">
    <input name="in" type="vector3" value="0.5, 0.5, 1.0" />
    <input name="scale" type="float" value="1.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" />
    <input name="bitangent" type="vector3" defaultgeomprop="Bworld" />
    <output name="out" type="vector3" defaultinput="normal" />
  </nodedef>
  <nodedef name="ND_normalmap_vector2" node="normalmap" nodegroup="math">
    <input name="in" type="vector3" value="0.5, 0.5, 1.0" />
    <input name="scale" type="vector2" value="1.0, 1.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" />
    <input name="bitangent" type="vector3" defaultgeomprop="Bworld" />
    <output name="out" type="vector3" defaultinput="normal" />
  </nodedef>

There are public example which show this ambiguity. For example "Emerald Peaks Wallpaper" (and many others) from AMD GPUOpen material site uses this declaration:

  <normalmap name="node_normals" type="vector3">
    <input name="in" type="vector3" nodename="node_image_vector3_10" />
  </normalmap>

As scale is not specified the instance could be ND_normalmap_float or ND_normalmap_vector2

Updated Definitions

If isdefaultvalue was specified for one of the variants then there would be no ambiguity. For the examples the first variant is tagged as the "default"

<nodedef name="ND_randomcolor_float" node="randomcolor" nodegroup="procedural3d" isdefaultversion="true"/>
 <nodedef name="ND_randomcolor_integer" node="randomcolor" nodegroup="procedural3d">

<nodedef name="ND_normalmap_float" node="normalmap" nodegroup="math" isdefaultversion="true">
<nodedef name="ND_normalmap_vector2" node="normalmap" nodegroup="math">

kwokcb added 3 commits August 10, 2026 14:49
… checking exact or rough matches.

Previously it would always return the first found from either exact or rough matches.
This is additive and will not affect any existing logic since no library nodes set this attribute for non-versioned nodedefs.

Add unit test to new and modifying existing definition behaviour.
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.

1 participant