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.87k stars 352 forks source link

Graph Editor / Viewer: Value changes do not update if shader recompile is required #1394

Open kwokcb opened 1 year ago

kwokcb commented 1 year ago

Changes to input values which actually are topological changes which require the shader to be rebuilt are not caught -- resulting in the appearance of not working. Value changes currently directly modify shader inputs for efficiency.

This does not necessarily apply to all backend targets but any that call C++ to generate new code such as conditionals. Enumerants also will fall into this category if a single choice is encoded when generating (e.g. such as image node texture addressing. Value changes which affect transparent display may also not be caught.

e.g. is a graph with a switch node where a change in the which selection input will result in nothing updating.

<?xml version="1``.0"?>
<materialx version="1.38" colorspace="lin_rec709">
  <switch name="switch_color3" type="color3" xpos="2.195652" ypos="-0.344828">
    <input name="in1" type="color3" value="1, 0, 0" />
    <input name="in2" type="color3" value="0, 1, 0" />
    <input name="in3" type="color3" value="0, 0, 1" />
    <input name="in4" type="color3" value="1, 1, 0" />
    <input name="in5" type="color3" value="0, 1, 1" />
    <input name="which" type="float" value="3" />
  </switch>
  <standard_surface name="standard_surface_surfaceshader" type="surfaceshader" xpos="4.797101" ypos="-1.818966">
    <input name="base_color" type="color3" nodename="switch_color3" />
  </standard_surface>
  <surfacematerial name="surfacematerial" type="material" xpos="9.782609" ypos="-1.112069">
    <input name="surfaceshader" type="surfaceshader" nodename="standard_surface_surfaceshader" />
  </surfacematerial>
</materialx>

if the condition is being fed by an interface input, then changes at the interface level which affect a conditional should be considered, though a full downstream traversal could be "expensive" at least the first level interface should work. e.g. image which would be this graph:

<?xml version="1.0"?>
<materialx version="1.38" colorspace="lin_rec709">
  <standard_surface name="standard_surface_surfaceshader" type="surfaceshader" xpos="4.789855" ypos="-1.818966">
    <input name="base_color" type="color3" output="output_color3" nodegraph="conditional_graph" />
  </standard_surface>
  <surfacematerial name="surfacematerial" type="material" xpos="9.782609" ypos="-1.112069">
    <input name="surfaceshader" type="surfaceshader" nodename="standard_surface_surfaceshader" />
  </surfacematerial>
  <nodegraph name="conditional_graph">
    <switch name="switch_color3" type="color3" xpos="12.318841" ypos="-0.818965">
      <input name="in1" type="color3" interfacename="input_color3" />
      <input name="in2" type="color3" interfacename="input_color4" />
      <input name="in3" type="color3" interfacename="input_color5" />
      <input name="in4" type="color3" interfacename="input_color6" />
      <input name="in5" type="color3" interfacename="input_color7" />
      <input name="which" type="float" interfacename="input_float" />
    </switch>
    <output name="output_color3" type="color3" nodename="switch_color3" xpos="17.391304" ypos="0.000000" />
    <input name="input_color3" type="color3" value="0.882641, 0.0604252, 0.0604252" xpos="7.246377" ypos="-3.086207" />
    <input name="input_color4" type="color3" value="0.138486, 0.858191, 0.156082" xpos="7.246377" ypos="-1.741379" />
    <input name="input_color5" type="color3" value="0.674283, 0.792176, 0.0503584" xpos="7.246377" ypos="-0.396552" />
    <input name="input_color6" type="color3" value="0.0883316, 0.0666782, 0.699266" xpos="7.246377" ypos="0.939655" />
    <input name="input_color7" type="color3" value="0, 0.190147, 0.547677" xpos="7.246377" ypos="2.275862" />
    <input name="input_float" type="float" value="0" xpos="7.246377" ypos="3.612069" />
  </nodegraph>
</materialx>
kwokcb commented 1 year ago

Found that a shader rebuild is also required when changing the input streams being used. Otherwise the shader will always reuse emit stream requirements from the last code generation.

Nodes to consider would include and`.