Skip to content

Commit

Permalink
Merge pull request #2113 from Autodesk/t_gamaj/MAYA-121735/fix_tangen…
Browse files Browse the repository at this point in the history
…t_inputs

MAYA-121735: Add UV tangents directly in MaterialX
  • Loading branch information
seando-adsk authored Feb 22, 2022
2 parents a2be5f6 + e8a5e99 commit 09a4347
Show file tree
Hide file tree
Showing 15 changed files with 1,082 additions and 178 deletions.
19 changes: 19 additions & 0 deletions lib/mayaUsd/render/MaterialXGenOgsXml/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ list(APPEND LIGHT_IMPLEMENTATIONS
libraries/mx_lighting_maya_v2.glsl
)

list(APPEND NODE_DECLARATIONS
libraries/maya_surfaces.mtlx
libraries/usd_utilities.mtlx
)

list(APPEND NODE_IMPLEMENTATIONS
libraries/usd_utilities_genglsl_impl.mtlx
libraries/mx_texcoordtangents_vector3.glsl
libraries/mx_arbitrarytangents_vector3.glsl
)

# -----------------------------------------------------------------------------
# promote headers
# -----------------------------------------------------------------------------
Expand All @@ -35,3 +46,11 @@ mayaUsd_promoteHeaderList(HEADERS ${HEADERS} SUBDIR render/MaterialXGenOgsXml)
install(FILES ${LIGHT_IMPLEMENTATIONS}
DESTINATION ${CMAKE_INSTALL_PREFIX}/libraries/pbrlib/genglsl/ogsxml
)

install(FILES ${NODE_DECLARATIONS}
DESTINATION ${CMAKE_INSTALL_PREFIX}/libraries/adsk/maya
)

install(FILES ${NODE_IMPLEMENTATIONS}
DESTINATION ${CMAKE_INSTALL_PREFIX}/libraries/adsk/maya/genglsl
)
297 changes: 297 additions & 0 deletions lib/mayaUsd/render/MaterialXGenOgsXml/libraries/maya_surfaces.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
<?xml version="1.0"?>
<materialx version="1.38">

<!-- ======================================================================== -->
<!-- Maya surface node definitions -->
<!-- ======================================================================== -->

<!-- Node: Lambert -->
<nodedef name="MayaND_lambert_surfaceshader" node="MayaLambert" nodegroup="npbr" doc="Maya Lambert surface shader" version="1.0" isdefaultversion="true">
<input name="diffuse" type="float" value="0.8" />
<input name="color" type="color3" value="0.5, 0.5, 0.5" />
<input name="transparency" type="color3" value="0.0, 0.0, 0.0" />
<input name="incandescence" type="color3" value="0.0, 0.0, 0.0" />
<input name="normalCamera" type="vector3" defaultgeomprop="Nworld" />
<output name="outColor" type="surfaceshader" />
</nodedef>

<!-- Node: Phong -->
<nodedef name="MayaND_phong_surfaceshader" node="MayaPhong" nodegroup="npbr" doc="Maya Phong surface shader" version="1.0" isdefaultversion="true">
<!-- lambert -->
<input name="diffuse" type="float" value="0.8" />
<input name="color" type="color3" value="0.5, 0.5, 0.5" />
<input name="transparency" type="color3" value="0.0, 0.0, 0.0" />
<input name="incandescence" type="color3" value="0.0, 0.0, 0.0" />
<input name="normalCamera" type="vector3" defaultgeomprop="Nworld" />

<!-- reflect -->
<input name="specularColor" type="color3" value="0.5, 0.5, 0.5" />
<input name="reflectivity" type="float" value="0.5" />
<input name="reflectedColor" type="color3" value="0.0, 0.0, 0.0" />
<input name="tangent" type="vector3" defaultgeomprop="Tworld" />

<!-- phong -->
<input name="cosinePower" type="float" value="20.0" />

<output name="outColor" type="surfaceshader" />
</nodedef>

<!-- Node: Blinn -->
<nodedef name="MayaND_blinn_surfaceshader" node="MayaBlinn" nodegroup="npbr" doc="Maya Blinn surface shader" version="1.0" isdefaultversion="true">
<!-- lambert -->
<input name="diffuse" type="float" value="0.8" />
<input name="color" type="color3" value="0.5, 0.5, 0.5" />
<input name="transparency" type="color3" value="0.0, 0.0, 0.0" />
<input name="incandescence" type="color3" value="0.0, 0.0, 0.0" />
<input name="normalCamera" type="vector3" defaultgeomprop="Nworld" />

<!-- reflect -->
<input name="specularColor" type="color3" value="0.5, 0.5, 0.5" />
<input name="reflectivity" type="float" value="0.5" />
<input name="reflectedColor" type="color3" value="0.0, 0.0, 0.0" />
<input name="tangent" type="vector3" defaultgeomprop="Tworld" />

<!-- blinn -->
<input name="eccentricity" type="float" value="0.3" />
<input name="specularRollOff" type="float" value="0.7" />

<output name="outColor" type="surfaceshader" />
</nodedef>

<!-- ======================================================================== -->
<!-- Maya surface node PBR nodegraph implementations -->
<!-- -->
<!-- These implementations do not try to replicate Maya behavior exactly. -->
<!-- They will use the smallest MaterialX graph that is close enough. -->
<!-- ======================================================================== -->

<!-- Node: Lambert -->
<nodegraph name="MayaIMP_lambert_surfaceshader" nodedef="MayaND_lambert_surfaceshader">
<!-- Diffuse Layer -->
<burley_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="diffuse" />
<input name="color" type="color3" interfacename="color" />
<input name="roughness" type="float" value="0.0" />
<input name="normal" type="vector3" interfacename="normalCamera" />
</burley_diffuse_bsdf>

<!-- Emission Layer -->
<uniform_edf name="emission_edf" type="EDF">
<input name="color" type="color3" interfacename="incandescence" />
</uniform_edf>

<!-- Node <surface> only supports monochromatic opacity so use the luminance of input opacity color -->
<luminance name="transparency_luminance" type="color3">
<input name="in" type="color3" interfacename="transparency" />
</luminance>
<swizzle name="transparency_luminance_r" type="float">
<input name="in" type="color3" nodename="transparency_luminance" />
<param name="channels" type="string" value="r" />
</swizzle>
<subtract name="cutout_opacity" type="float">
<input name="in1" type="float" value="1.0" />
<input name="in2" type="float" nodename="transparency_luminance_r" />
</subtract>

<!-- Surface Shader Constructor -->
<surface name="surface_constructor" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="diffuse_bsdf" />
<input name="edf" type="EDF" nodename="emission_edf" />
<input name="opacity" type="float" nodename="cutout_opacity" />
</surface>

<!-- Output -->
<output name="outColor" type="surfaceshader" nodename="surface_constructor" />
</nodegraph>

<!-- Node: Phong -->
<nodegraph name="MayaIMP_phong_surfaceshader" nodedef="MayaND_phong_surfaceshader">
<!-- Diffuse Layer -->
<burley_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="diffuse" />
<input name="color" type="color3" interfacename="color" />
<input name="roughness" type="float" value="0.0" />
<input name="normal" type="vector3" interfacename="normalCamera" />
</burley_diffuse_bsdf>

<!-- Node <surface> only supports monochromatic opacity so use the luminance of input opacity color -->
<luminance name="transparency_luminance" type="color3">
<input name="in" type="color3" interfacename="transparency" />
</luminance>
<swizzle name="transparency_luminance_r" type="float">
<input name="in" type="color3" nodename="transparency_luminance" />
<param name="channels" type="string" value="r" />
</swizzle>
<subtract name="cutout_opacity" type="float">
<input name="in1" type="float" value="1.0" />
<input name="in2" type="float" nodename="transparency_luminance_r" />
</subtract>

<!-- Transmission Layer. Used to emulate transparency. -->
<dielectric_bsdf name="transmission_bsdf" type="BSDF">
<input name="weight" type="float" value="1" />
<input name="tint" type="color3" value="1, 1, 1" />
<input name="ior" type="float" value="1.5" />
<input name="roughness" type="vector2" value="0.0, 0.0" />
<input name="normal" type="vector3" interfacename="normalCamera" />
<input name="tangent" type="vector3" interfacename="tangent" />
<input name="scatter_mode" type="string" value="T" />
</dielectric_bsdf>
<mix name="transmission_mix" type="BSDF">
<input name="fg" type="BSDF" nodename="diffuse_bsdf" />
<input name="bg" type="BSDF" nodename="transmission_bsdf" />
<input name="mix" type="float" nodename="cutout_opacity" />
</mix>

<!-- roughness = sqrt(1.0 / (0.454 * cosinePower + 3.357)) -->
<multiply name="mul0" type="float">
<input name="in1" type="float" interfacename="cosinePower" />
<input name="in2" type="float" value="0.454" />
</multiply>
<add name="add0" type="float">
<input name="in1" type="float" value="3.357" />
<input name="in2" type="float" nodename="mul0" />
</add>
<divide name="div0" type="float">
<input name="in1" type="float" value="1.0" />
<input name="in2" type="float" nodename="add0" />
</divide>
<sqrt name="roughness" type="float">
<input name="in" type="float" nodename="div0" />
</sqrt>

<!-- Specular Workflow -->
<roughness_anisotropy name="specular_roughness" type="vector2">
<input name="roughness" type="float" nodename="roughness" />
<input name="anisotropy" type="float" value="0" />
</roughness_anisotropy>
<generalized_schlick_bsdf name="specular_bsdf1" type="BSDF">
<input name="weight" type="float" value="1" />
<input name="color0" type="color3" interfacename="specularColor" />
<input name="color90" type="color3" value="1, 1, 1" />
<input name="roughness" type="vector2" nodename="specular_roughness" />
<input name="normal" type="vector3" interfacename="normalCamera" />
<input name="tangent" type="vector3" interfacename="tangent" />
</generalized_schlick_bsdf>
<layer name="specular_workflow_bsdf" type="BSDF">
<input name="top" type="BSDF" nodename="specular_bsdf1" />
<input name="base" type="BSDF" nodename="transmission_mix" />
</layer>

<!-- reflectivity implemented as a coat layer -->
<dielectric_bsdf name="coat_dielectric_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="reflectivity" />
<input name="tint" type="color3" interfacename="reflectedColor" />
<input name="ior" type="float" value="1.5" />
<input name="roughness" type="vector2" value="0.0, 0.0" />
<input name="normal" type="vector3" interfacename="normalCamera" />
<input name="tangent" type="vector3" interfacename="tangent" />
</dielectric_bsdf>
<layer name="coat_bsdf" type="BSDF">
<input name="top" type="BSDF" nodename="coat_dielectric_bsdf" />
<input name="base" type="BSDF" nodename="specular_workflow_bsdf" />
</layer>

<!-- Emission Layer -->
<uniform_edf name="emission_edf" type="EDF">
<input name="color" type="color3" interfacename="incandescence" />
</uniform_edf>

<!-- Surface Shader Constructor -->
<surface name="surface_constructor" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="coat_bsdf" />
<input name="edf" type="EDF" nodename="emission_edf" />
<input name="opacity" type="float" nodename="cutout_opacity" />
</surface>

<!-- Output -->
<output name="outColor" type="surfaceshader" nodename="surface_constructor" />
</nodegraph>

<!-- Node: Blinn -->
<nodegraph name="MayaIMP_blinn_surfaceshader" nodedef="MayaND_blinn_surfaceshader">
<!-- Diffuse Layer -->
<burley_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="diffuse" />
<input name="color" type="color3" interfacename="color" />
<input name="roughness" type="float" value="0.0" />
<input name="normal" type="vector3" interfacename="normalCamera" />
</burley_diffuse_bsdf>

<!-- Node <surface> only supports monochromatic opacity so use the luminance of input opacity color -->
<luminance name="transparency_luminance" type="color3">
<input name="in" type="color3" interfacename="transparency" />
</luminance>
<swizzle name="transparency_luminance_r" type="float">
<input name="in" type="color3" nodename="transparency_luminance" />
<param name="channels" type="string" value="r" />
</swizzle>
<subtract name="cutout_opacity" type="float">
<input name="in1" type="float" value="1.0" />
<input name="in2" type="float" nodename="transparency_luminance_r" />
</subtract>

<!-- Transmission Layer. Used to emulate transparency. -->
<dielectric_bsdf name="transmission_bsdf" type="BSDF">
<input name="weight" type="float" value="1" />
<input name="tint" type="color3" value="1, 1, 1" />
<input name="ior" type="float" value="1.5" />
<input name="roughness" type="vector2" value="0.0, 0.0" />
<input name="normal" type="vector3" interfacename="normalCamera" />
<input name="tangent" type="vector3" interfacename="tangent" />
<input name="scatter_mode" type="string" value="T" />
</dielectric_bsdf>
<mix name="transmission_mix" type="BSDF">
<input name="fg" type="BSDF" nodename="diffuse_bsdf" />
<input name="bg" type="BSDF" nodename="transmission_bsdf" />
<input name="mix" type="float" nodename="cutout_opacity" />
</mix>

<!-- Specular Workflow -->
<roughness_anisotropy name="specular_roughness" type="vector2">
<input name="roughness" type="float" interfacename="eccentricity" />
<input name="anisotropy" type="float" value="0" />
</roughness_anisotropy>
<generalized_schlick_bsdf name="specular_bsdf1" type="BSDF">
<input name="weight" type="float" interfacename="specularRollOff" />
<input name="color0" type="color3" interfacename="specularColor" />
<input name="color90" type="color3" value="1, 1, 1" />
<input name="roughness" type="vector2" nodename="specular_roughness" />
<input name="normal" type="vector3" interfacename="normalCamera" />
<input name="tangent" type="vector3" interfacename="tangent" />
</generalized_schlick_bsdf>
<layer name="specular_workflow_bsdf" type="BSDF">
<input name="top" type="BSDF" nodename="specular_bsdf1" />
<input name="base" type="BSDF" nodename="transmission_mix" />
</layer>

<!-- reflectivity implemented as a coat layer -->
<dielectric_bsdf name="coat_dielectric_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="reflectivity" />
<input name="tint" type="color3" interfacename="reflectedColor" />
<input name="ior" type="float" value="1.5" />
<input name="roughness" type="vector2" value="0.0, 0.0" />
<input name="normal" type="vector3" interfacename="normalCamera" />
<input name="tangent" type="vector3" interfacename="tangent" />
</dielectric_bsdf>
<layer name="coat_bsdf" type="BSDF">
<input name="top" type="BSDF" nodename="coat_dielectric_bsdf" />
<input name="base" type="BSDF" nodename="specular_workflow_bsdf" />
</layer>

<!-- Emission Layer -->
<uniform_edf name="emission_edf" type="EDF">
<input name="color" type="color3" interfacename="incandescence" />
</uniform_edf>

<!-- Surface Shader Constructor -->
<surface name="surface_constructor" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="coat_bsdf" />
<input name="edf" type="EDF" nodename="emission_edf" />
<input name="opacity" type="float" nodename="cutout_opacity" />
</surface>

<!-- Output -->
<output name="outColor" type="surfaceshader" nodename="surface_constructor" />
</nodegraph>
</materialx>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
void mx_arbitrarytangents_vector3(vec3 position, vec3 normal, out vec3 tangent)
{
// Get screen space derivatives of position
vec3 dPdx = dFdx(position);

// Ensure position derivatives are perpendicular to normal
tangent = normalize(dPdx - dot(dPdx, normal) * normal);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
void mx_texcoordtangents_vector3(vec3 position, vec3 normal, vec2 texcoord, out vec3 tangent)
{
// Calculation of TBN matrix and terminology based on "Surface
// Gradient-Based Bump Mapping Framework" (2020)

// Get screen space derivatives of position
vec3 dPdx = dFdx(position);
vec3 dPdy = dFdy(position);

// Ensure position derivatives are perpendicular to normal
vec3 sigmaX = dPdx - dot(dPdx, normal) * normal;
vec3 sigmaY = dPdy - dot(dPdy, normal) * normal;

float flipSign = dot(dPdy, cross(normal, dPdx)) < 0 ? -1 : 1;

// Get screen space derivatives of st
vec2 dSTdx = dFdx(texcoord);
vec2 dSTdy = dFdy(texcoord);

// Get determinant and determinant sign of st matrix
float det = dot(dSTdx, vec2(dSTdy.y, -dSTdy.x));
float signDet = det < 0 ? -1 : 1;

// Get first column of inv st matrix
// Don't divide by det, but scale by its sign
vec2 invC0 = signDet * vec2(dSTdy.y, -dSTdx.y);

vec3 T = sigmaX * invC0.x + sigmaY * invC0.y;

if (abs(det) > 0) {
T = normalize(T);
}

tangent = T;
}
24 changes: 24 additions & 0 deletions lib/mayaUsd/render/MaterialXGenOgsXml/libraries/usd_utilities.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<materialx version="1.38">

<!-- ======================================================================== -->
<!-- Utilities specific to USD handling -->
<!-- ======================================================================== -->

<!-- Node: texcoordtangents: Generate world tangents from derivatives of position
and texcoord -->
<nodedef name="MayaND_texcoordtangents_vector3" node="texcoordtangents" nodegroup="math">
<input name="position" type="vector3" defaultgeomprop="Pworld" />
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
<input name="texcoord" type="vector2" defaultgeomprop="UV0" />
<output name="out" type="vector3" />
</nodedef>

<!-- Node: arbitrarytangents: Completely arbitrary tangent for when there is no
texcoord space available -->
<nodedef name="MayaND_arbitrarytangents_vector3" node="arbitrarytangents" nodegroup="math">
<input name="position" type="vector3" defaultgeomprop="Pworld" />
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
<output name="out" type="vector3" />
</nodedef>
</materialx>
Loading

0 comments on commit 09a4347

Please sign in to comment.