autodesk-forks / MaterialX

MaterialX C++ and Python libraries
http://www.materialx.org/
Apache License 2.0
107 stars 23 forks source link

Node flattening issue updates #1173

Closed bernardkwok closed 3 years ago

bernardkwok commented 3 years ago

Issues summary:

  1. Upstream nodegraph connections were not being taken into account only nodename connections.
  2. Nodegraph outputs were not being connected to nodes which were flattened (within a nodegraph)
  3. Flattened node connected to downstream output was not being handled.

Test case: (nodes in yellow are definitions. image (bitmap, bitmap_remap + normal_map within layered_inputGraph, and image layered definition for shader_layered: image

Snippet of flattend graph with 3 key nodes remaining connected. image with flattened upstream graph (layered_inputGraph): image

Test output works for test case given currently:


<?xml version="1.0"?>
<materialx version="1.38" colorspace="lin_rec709" xmlns:xi="http://www.w3.org/2001/XInclude"> 
  <surfacematerial name="material_layered" type="material">
    <input name="surfaceshader" type="surfaceshader" nodename="standard_surface0" output="" />
  </surfacematerial>
  <luminance name="coat_value_color3" type="color3">
    <input name="in" type="color3" value="1, 1, 1" colorspace="gamma24" />
  </luminance>
  <swizzle name="N_r_color3" type="float">
    <input name="in" type="color3" nodename="coat_value_color3" />
    <input name="channels" type="string" value="r" />
  </swizzle>
  <swizzle name="N_g_color3" type="float">
    <input name="in" type="color3" nodename="coat_value_color3" />
    <input name="channels" type="string" value="g" />
  </swizzle>
  <swizzle name="N_b_color3" type="float">
    <input name="in" type="color3" nodename="coat_value_color3" />
    <input name="channels" type="string" value="b" />
  </swizzle>
  <switch name="N_sw_color3" type="float">
    <input name="in1" type="float" nodename="N_r_color3" />
    <input name="in2" type="float" nodename="N_g_color3" />
    <input name="in3" type="float" nodename="N_b_color3" />
    <input name="which" type="integer" value="0" />
  </switch>
  <subtract name="oneminus_surfaniso0" type="float">
    <input name="in1" type="float" value="1.0" />
    <input name="in2" type="float" value="0" />
  </subtract>
  <sqrt name="sqrt1minus_surfaniso0" type="float">
    <input name="in" type="float" nodename="oneminus_surfaniso0" />
  </sqrt>
  <multiply name="coat_roughness_value" type="float">
    <input name="in1" type="float" nodename="sqrt1minus_surfaniso0" />
    <input name="in2" type="float" value="0.0774597" />
  </multiply>
  <multiply name="twotimes_surfaniso0" type="float">
    <input name="in1" type="float" value="2.0" />
    <input name="in2" type="float" value="0" />
  </multiply>
  <multiply name="pow2_surfaniso0" type="float">
    <input name="in1" type="float" value="0" />
    <input name="in2" type="float" value="0" />
  </multiply>
  <subtract name="coat_anisotropy_value" type="float">
    <input name="in1" type="float" nodename="twotimes_surfaniso0" />
    <input name="in2" type="float" nodename="pow2_surfaniso0" />
  </subtract>
  <constant name="surface_rotation_param" type="float">
    <input name="value" type="float" value="0" />
  </constant>
  <divide name="div_rotation0" type="float">
    <input name="in1" type="float" nodename="surface_rotation_param" />
    <input name="in2" type="float" value="360.0" />
  </divide>
  <modulo name="coat_rotation_value" type="float">
    <input name="in1" type="float" nodename="div_rotation0" />
  </modulo>
  <constant name="layered_f0_param" type="float">
    <input name="value" type="float" value="0.0602702" />
  </constant>
  <sqrt name="sqrt_layeredf0" type="float">
    <input name="in" type="float" nodename="layered_f0_param" />
  </sqrt>
  <add name="oneplus_sqrtlayeredf0" type="float">
    <input name="in1" type="float" value="1.0" />
    <input name="in2" type="float" nodename="sqrt_layeredf0" />
  </add>
  <subtract name="oneminus_sqrtlayeredf0" type="float">
    <input name="in1" type="float" value="1.0" />
    <input name="in2" type="float" nodename="sqrt_layeredf0" />
  </subtract>
  <divide name="coat_IOR_value" type="float">
    <input name="in1" type="float" nodename="oneplus_sqrtlayeredf0" />
    <input name="in2" type="float" nodename="oneminus_sqrtlayeredf0" />
  </divide>
  <constant name="layered_roughness_param" type="float">
    <input name="value" type="float" value="0.447214" />
  </constant>
  <constant name="layered_anisotropy_param" type="float">
    <input name="value" type="float" value="0.95" />
  </constant>
  <subtract name="oneminus_layeraniso0" type="float">
    <input name="in1" type="float" value="1.0" />
    <input name="in2" type="float" nodename="layered_anisotropy_param" />
  </subtract>
  <sqrt name="sqrt1minus_layeraniso0" type="float">
    <input name="in" type="float" nodename="oneminus_layeraniso0" />
  </sqrt>
  <multiply name="specular_roughness_value" type="float">
    <input name="in1" type="float" nodename="sqrt1minus_layeraniso0" />
    <input name="in2" type="float" nodename="layered_roughness_param" />
  </multiply>
  <multiply name="twotimes_layeraniso0" type="float">
    <input name="in1" type="float" value="2.0" />
    <input name="in2" type="float" nodename="layered_anisotropy_param" />
  </multiply>
  <multiply name="pow2_layeraniso0" type="float">
    <input name="in1" type="float" nodename="layered_anisotropy_param" />
    <input name="in2" type="float" nodename="layered_anisotropy_param" />
  </multiply>
  <subtract name="specular_anisotropy_value" type="float">
    <input name="in1" type="float" nodename="twotimes_layeraniso0" />
    <input name="in2" type="float" nodename="pow2_layeraniso0" />
  </subtract>
  <constant name="layered_rotation_param" type="float">
    <input name="value" type="float" value="0" output="layered_rotation_map_output" nodegraph="layered_inputGraph" />
  </constant>
  <divide name="div_rotation1" type="float">
    <input name="in1" type="float" nodename="layered_rotation_param" />
    <input name="in2" type="float" value="360.0" />
  </divide>
  <modulo name="specular_rotation_value" type="float">
    <input name="in1" type="float" nodename="div_rotation1" />
  </modulo>
  <constant name="layered_fraction_param" type="float">
    <input name="value" type="float" value="0.15" />
  </constant>
  <constant name="layered_diffuse_param" type="color3">
    <input name="value" type="color3" value="0.0998528, 0.0998528, 0.0998528" colorspace="gamma24" />
  </constant>
  <constant name="layered_bottom_f0_param" type="color3">
    <input name="value" type="color3" value="1, 1, 1" output="layered_bottom_f0_map_output" nodegraph="layered_inputGraph" />
  </constant>
  <subtract name="oneminus_layerfraction" type="float">
    <input name="in1" type="float" value="1.0" />
    <input name="in2" type="float" nodename="layered_fraction_param" />
  </subtract>
  <multiply name="oneminuslf_x_layerdiffuse" type="color3">
    <input name="in1" type="color3" nodename="layered_diffuse_param" />
    <input name="in2" type="float" nodename="oneminus_layerfraction" />
  </multiply>
  <multiply name="lfract_x_lbottomf0" type="color3">
    <input name="in1" type="color3" nodename="layered_bottom_f0_param" />
    <input name="in2" type="float" nodename="layered_fraction_param" />
  </multiply>
  <add name="base_color_value" type="color3">
    <input name="in1" type="color3" nodename="lfract_x_lbottomf0" />
    <input name="in2" type="color3" nodename="oneminuslf_x_layerdiffuse" />
  </add>
  <ifequal name="layered_fraction_value" type="float">
    <input name="in1" type="float" nodename="oneminus_layerfraction" />
    <input name="in2" type="float" nodename="layered_fraction_param" />
    <input name="value1" type="boolean" value="true" />
    <input name="value2" type="boolean" value="true" />
  </ifequal>
  <standard_surface name="standard_surface0" type="surfaceshader" version="1.0.1">
    <input name="normal" type="vector3" value="1, 1, 1" defaultgeomprop="Nobject" output="layered_normal_map_output" nodegraph="layered_inputGraph" />
    <input name="coat_normal" type="vector3" value="1, 1, 1" defaultgeomprop="Nobject" />
    <input name="opacity" type="color3" value="1, 1, 1" />
    <input name="coat" type="float" nodename="N_sw_color3" output="" />
    <input name="metalness" type="float" nodename="layered_fraction_value" />
    <input name="specular" type="float" value="0.0" />
    <input name="base" type="float" value="1.0" />
    <input name="coat_color" type="color3" value="1.0, 1.0, 1.0" />
    <input name="coat_roughness" type="float" nodename="coat_roughness_value" />
    <input name="coat_anisotropy" type="float" nodename="coat_anisotropy_value" />
    <input name="coat_rotation" type="float" nodename="coat_rotation_value" />
    <input name="coat_IOR" type="float" nodename="coat_IOR_value" />
    <input name="specular_roughness" type="float" nodename="specular_roughness_value" />
    <input name="specular_anisotropy" type="float" nodename="specular_anisotropy_value" />
    <input name="specular_rotation" type="float" nodename="specular_rotation_value" />
    <input name="base_color" type="color3" nodename="base_color_value" />
  </standard_surface>
  <nodegraph name="layered_inputGraph">
    <divide name="total_scale" type="vector2">
      <input name="in1" type="vector2" value="1.0, 1.0" />
      <input name="in2" type="vector2" value="0.33, 0.33" unit="inch" unittype="distance" />
    </divide>
    <add name="total_offset" type="vector2">
      <input name="in1" type="vector2" />
      <input name="in2" type="vector2" value="0.0, 0.0" />
    </add>
    <multiply name="rotation_angle_param" type="float">
      <input name="in1" type="float" />
      <input name="in2" type="float" value="-1.0" />
    </multiply>
    <texcoord name="texcoord1" type="vector2" />
    <subtract name="N_subpivot2" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord1" />
      <input name="in2" type="vector2" value="0.0, 0.0" />
    </subtract>
    <divide name="N_applyscale2" type="vector2">
      <input name="in1" type="vector2" nodename="N_subpivot2" />
      <input name="in2" type="vector2" nodename="total_scale" />
    </divide>
    <rotate2d name="N_applyrot2" type="vector2">
      <input name="in" type="vector2" nodename="N_applyscale2" />
      <input name="amount" type="float" value="0" nodename="rotation_angle_param" />
    </rotate2d>
    <subtract name="N_applyoffset2" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyrot2" />
      <input name="in2" type="vector2" nodename="total_offset" />
    </subtract>
    <add name="N_addpivot2" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyoffset2" />
      <input name="in2" type="vector2" value="0.0, 0.0" />
    </add>
    <image name="b_image" type="color3">
      <input name="file" type="filename" value="" colorspace="srgb_texture" />
      <input name="uaddressmode" type="string" />
      <input name="vaddressmode" type="string" />
      <input name="texcoord" type="vector2" nodename="N_addpivot2" output="" />
    </image>
    <multiply name="image_brightness" type="color3">
      <input name="in1" type="color3" nodename="b_image" />
      <input name="in2" type="float" />
    </multiply>
    <invert name="image_invert" type="color3">
      <input name="in" type="color3" nodename="image_brightness" />
    </invert>
    <ifequal name="image_convert" type="color3">
      <input name="in1" type="color3" nodename="image_invert" />
      <input name="in2" type="color3" nodename="image_brightness" />
      <input name="value1" type="boolean" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="layered_bottom_f0_map_output" type="color3" nodename="image_convert" output="" />
    <divide name="total_scale2" type="vector2">
      <input name="in1" type="vector2" value="1.0, 1.0" />
      <input name="in2" type="vector2" value="0.33, 0.33" unit="inch" unittype="distance" />
    </divide>
    <add name="total_offset2" type="vector2">
      <input name="in1" type="vector2" />
      <input name="in2" type="vector2" value="0.0, 0.0" />
    </add>
    <multiply name="rotation_angle_param2" type="float">
      <input name="in1" type="float" />
      <input name="in2" type="float" value="-1.0" />
    </multiply>
    <texcoord name="texcoord2" type="vector2" />
    <subtract name="N_subpivot" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord2" />
      <input name="in2" type="vector2" value="0.0, 0.0" />
    </subtract>
    <divide name="N_applyscale" type="vector2">
      <input name="in1" type="vector2" nodename="N_subpivot" />
      <input name="in2" type="vector2" nodename="total_scale2" />
    </divide>
    <rotate2d name="N_applyrot" type="vector2">
      <input name="in" type="vector2" nodename="N_applyscale" />
      <input name="amount" type="float" value="0" nodename="rotation_angle_param2" />
    </rotate2d>
    <subtract name="N_applyoffset" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyrot" />
      <input name="in2" type="vector2" nodename="total_offset2" />
    </subtract>
    <add name="N_addpivot" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyoffset" />
      <input name="in2" type="vector2" value="0.0, 0.0" />
    </add>
    <image name="b_image2" type="vector3">
      <input name="file" type="filename" value="" colorspace="lin_rec709" />
      <input name="uaddressmode" type="string" />
      <input name="vaddressmode" type="string" />
      <input name="texcoord" type="vector2" nodename="N_addpivot" output="" />
    </image>
    <multiply name="b_image_negate_y" type="vector3">
      <input name="in1" type="vector3" nodename="b_image2" />
      <input name="in2" type="vector3" value="1.0, -1.0, 1.0" />
    </multiply>
    <add name="b_image_invert_y" type="vector3">
      <input name="in1" type="vector3" value="0.0, 1.0, 0.0" />
      <input name="in2" type="vector3" nodename="b_image_negate_y" />
    </add>
    <normalmap name="impl_normalmap" type="vector3">
      <input name="in" type="vector3" nodename="b_image_invert_y" />
      <input name="scale" type="float" />
      <input name="space" type="string" value="tangent" />
    </normalmap>
    <output name="layered_normal_map_output" type="vector3" nodename="impl_normalmap" output="" />
    <divide name="total_scale3" type="vector2">
      <input name="in1" type="vector2" value="1.0, 1.0" />
      <input name="in2" type="vector2" value="0.33, 0.33" unit="inch" unittype="distance" />
    </divide>
    <add name="total_offset3" type="vector2">
      <input name="in1" type="vector2" />
      <input name="in2" type="vector2" value="0.0, 0.0" />
    </add>
    <multiply name="rotation_angle_param3" type="float">
      <input name="in1" type="float" />
      <input name="in2" type="float" value="-1.0" />
    </multiply>
    <texcoord name="texcoord3" type="vector2" />
    <subtract name="N_subpivot3" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord3" />
      <input name="in2" type="vector2" value="0.0, 0.0" />
    </subtract>
    <divide name="N_applyscale3" type="vector2">
      <input name="in1" type="vector2" nodename="N_subpivot3" />
      <input name="in2" type="vector2" nodename="total_scale3" />
    </divide>
    <rotate2d name="N_applyrot3" type="vector2">
      <input name="in" type="vector2" nodename="N_applyscale3" />
      <input name="amount" type="float" value="0" nodename="rotation_angle_param3" />
    </rotate2d>
    <subtract name="N_applyoffset3" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyrot3" />
      <input name="in2" type="vector2" nodename="total_offset3" />
    </subtract>
    <add name="N_addpivot3" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyoffset3" />
      <input name="in2" type="vector2" value="0.0, 0.0" />
    </add>
    <image name="b_image3" type="color3">
      <input name="file" type="filename" value="" colorspace="lin_rec709" />
      <input name="uaddressmode" type="string" />
      <input name="vaddressmode" type="string" />
      <input name="texcoord" type="vector2" nodename="N_addpivot3" output="" />
    </image>
    <multiply name="image_brightness2" type="color3">
      <input name="in1" type="color3" nodename="b_image3" />
      <input name="in2" type="float" />
    </multiply>
    <invert name="image_invert2" type="color3">
      <input name="in" type="color3" nodename="image_brightness2" />
    </invert>
    <ifequal name="image_convert2" type="color3">
      <input name="in1" type="color3" nodename="image_invert2" />
      <input name="in2" type="color3" nodename="image_brightness2" />
      <input name="value1" type="boolean" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <swizzle name="N_r_color3" type="float">
      <input name="in" type="color3" nodename="image_convert2" />
      <input name="channels" type="string" value="r" />
    </swizzle>
    <swizzle name="N_g_color3" type="float">
      <input name="in" type="color3" nodename="image_convert2" />
      <input name="channels" type="string" value="g" />
    </swizzle>
    <swizzle name="N_b_color3" type="float">
      <input name="in" type="color3" nodename="image_convert2" />
      <input name="channels" type="string" value="b" />
    </swizzle>
    <switch name="N_sw_color3" type="float">
      <input name="in1" type="float" nodename="N_r_color3" />
      <input name="in2" type="float" nodename="N_g_color3" />
      <input name="in3" type="float" nodename="N_b_color3" />
      <input name="which" type="integer" value="0" />
    </switch>
    <remap name="value_remapped" type="float">
      <input name="in" type="float" nodename="N_sw_color3" output="" />
      <input name="outlow" type="float" value="0" />
      <input name="outhigh" type="float" value="180" />
    </remap>
    <output name="layered_rotation_map_output" type="float" nodename="value_remapped" output="" />
  </nodegraph>
</materialx>
`
`