Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LOOKDEVX-1847 - Fix broken normal maps #3307

Merged
merged 1 commit into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions lib/mayaUsd/render/vp2RenderDelegate/material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,8 @@ void _AddMissingTangents(mx::DocumentPtr& mtlxDoc)
{
// We will need at least one geompropvalue reader to generate tangents:
mx::NodePtr stReader;
// If we find one implicit texcoord input we can still try to generate texcoord tangents:
bool hasOneImplicitTexcoordInput = false;

// List of all items to fix:
using nodeInput = std::pair<mx::NodePtr, std::string>;
Expand Down Expand Up @@ -833,6 +835,10 @@ void _AddMissingTangents(mx::DocumentPtr& mtlxDoc)
&& !material->getConnectedOutput(input->getName())) {
materialTobjectInputs.emplace_back(material, input->getName());
}
if (geomPropString == _mtlxTokens->UV0
&& !material->getConnectedOutput(input->getName())) {
hasOneImplicitTexcoordInput = true;
}
}
}
}
Expand Down Expand Up @@ -884,6 +890,10 @@ void _AddMissingTangents(mx::DocumentPtr& mtlxDoc)
&& node->getConnectedNodeName(input->getName()).empty()) {
graphTobjectInputs.emplace_back(node, input->getName());
}
if (geomPropString == _mtlxTokens->UV0
&& node->getConnectedNodeName(input->getName()).empty()) {
hasOneImplicitTexcoordInput = true;
}
}
}
// Check if it is an explicit tangent reader:
Expand All @@ -900,15 +910,19 @@ void _AddMissingTangents(mx::DocumentPtr& mtlxDoc)

// Create the tangent generator:
mx::NodePtr tangentGenerator;
if (stReader) {
if (stReader || hasOneImplicitTexcoordInput) {
tangentGenerator = nodeGraph->addNode(
_mtlxTokens->texcoordtangents.GetString(),
_mtlxTokens->Tw_reader.GetString(),
_mtlxTokens->vector3.GetString());
tangentGenerator->addInput(
_mtlxTokens->texcoord.GetString(), _mtlxTokens->vector2.GetString());
tangentGenerator->setConnectedNodeName(
_mtlxTokens->texcoord.GetString(), stReader->getName());
if (stReader) {
// Use an explicit geomprop reader if one was found, otherwise, leave it to the
// implicit geomprop reader code in shadergen.
tangentGenerator->setConnectedNodeName(
_mtlxTokens->texcoord.GetString(), stReader->getName());
}
} else {
tangentGenerator = nodeGraph->addNode(
_mtlxTokens->arbitrarytangents.GetString(),
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,13 @@ def testDemoQuads(self):
cmds.move(0, 8, 0, 'persp')
cmds.rotate(-90, 0, 0, 'persp')

# Add a light to see bump mapping:
light = cmds.directionalLight(rgb=(1, 1, 1))
transform = cmds.listRelatives(light, parent=True)[0]
cmds.xform(transform, ro=(105, 25, 130), ws=True)
cmds.setAttr(light+".intensity", 2)
panel = mayaUtils.activeModelPanel()
cmds.modelEditor(panel, edit=True, displayTextures=True)
cmds.modelEditor(panel, edit=True, lights=True, displayLights="all", displayTextures=True)

self._StartTest('DemoQuads')

Expand Down
186 changes: 158 additions & 28 deletions test/testSamples/MaterialX/DemoQuads.usda
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def Scope "mtl"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
color3f inputs:base_color.connect = </mtl/imageR8U/image1.outputs:out>
float inputs:specular = 0.0
float inputs:specular = 0
token outputs:out
}

Expand All @@ -296,7 +296,7 @@ def Scope "mtl"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
color3f inputs:base_color.connect = </mtl/imageR16F/image1.outputs:out>
float inputs:specular = 0.0
float inputs:specular = 0
token outputs:out
}

Expand All @@ -316,7 +316,7 @@ def Scope "mtl"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
color3f inputs:base_color.connect = </mtl/imageR32F/image1.outputs:out>
float inputs:specular = 0.0
float inputs:specular = 0
token outputs:out
}

Expand All @@ -336,8 +336,8 @@ def Scope "mtl"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
color3f inputs:base_color.connect = </mtl/imageRG8U/combine31.outputs:out>
float inputs:specular = 0.0
color3f inputs:opacity.connect = </mtl/imageRG8U/combine32.outputs:out>
float inputs:specular = 0
token outputs:out
}

Expand Down Expand Up @@ -385,8 +385,8 @@ def Scope "mtl"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
color3f inputs:base_color.connect = </mtl/imageRG16F/combine31.outputs:out>
float inputs:specular = 0.0
color3f inputs:opacity.connect = </mtl/imageRG16F/combine32.outputs:out>
float inputs:specular = 0
token outputs:out
}

Expand Down Expand Up @@ -425,7 +425,7 @@ def Scope "mtl"
color3f outputs:out
}
}

def Material "imageRG32F"
{
token outputs:mtlx:surface.connect = </mtl/imageRG32F/imageRG32F.outputs:out>
Expand All @@ -434,8 +434,8 @@ def Scope "mtl"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
color3f inputs:base_color.connect = </mtl/imageRG32F/combine31.outputs:out>
float inputs:specular = 0.0
color3f inputs:opacity.connect = </mtl/imageRG32F/combine32.outputs:out>
float inputs:specular = 0
token outputs:out
}

Expand Down Expand Up @@ -475,56 +475,42 @@ def Scope "mtl"
}
}

def Material "Background" (
prepend apiSchemas = ["NodeGraphNodeAPI"]
)
def Material "Background"
{
token outputs:mtlx:surface.connect = </mtl/Background/ss1.outputs:out>
uniform float2 ui:nodegraph:node:pos = (5.514378, 1.9555556)

def Shader "ss1" (
prepend apiSchemas = ["NodeGraphNodeAPI"]
)
def Shader "ss1"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
color3f inputs:base_color.connect = </mtl/Background/image1.outputs:out>
float inputs:specular = 0.0
float inputs:specular = 0
token outputs:out
uniform float2 ui:nodegraph:node:pos = (1.2722223, -0.2)
}

def Shader "image1" (
prepend apiSchemas = ["NodeGraphNodeAPI"]
)
def Shader "image1"
{
uniform token info:id = "ND_image_color3"
asset inputs:file = @textures/normalSpiral.png@
float2 inputs:texcoord.connect = </mtl/Background/place2d1.outputs:out>
color3f outputs:out
uniform float2 ui:nodegraph:node:pos = (-0.75555557, -0.4888889)
}

def Shader "geompropvalue1" (
prepend apiSchemas = ["NodeGraphNodeAPI"]
)
def Shader "geompropvalue1"
{
uniform token info:id = "ND_geompropvalue_vector2"
string inputs:geomprop = "st"
float2 outputs:out
uniform float2 ui:nodegraph:node:pos = (-4.05, 0.46666667)
}

def Shader "place2d1" (
prepend apiSchemas = ["NodeGraphNodeAPI"]
)
def Shader "place2d1"
{
uniform token info:id = "ND_place2d_vector2"
float2 inputs:scale = (0.2, 0.2)
float2 inputs:texcoord.connect = </mtl/Background/geompropvalue1.outputs:out>
float2 outputs:out
uniform float2 ui:nodegraph:node:pos = (-2.538889, 0.92777777)
}
}

def Material "standard_surfaceUV1_3"
{
token outputs:mtlx:surface.connect = </mtl/standard_surfaceUV1_3/standard_surfaceUV1_1.outputs:out>
Expand Down Expand Up @@ -580,6 +566,68 @@ def Scope "mtl"
float2 outputs:out
}
}

def Material "standard_surface1"
{
token outputs:mtlx:surface.connect = </mtl/standard_surface1/standard_surface1.outputs:out>

def Shader "standard_surface1"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
float3 inputs:normal.connect = </mtl/standard_surface1/normalmap1.outputs:out>
token outputs:out
}

def Shader "normalmap1"
{
uniform token info:id = "ND_normalmap"
float3 inputs:normal.connect = </mtl/standard_surface1/image1.outputs:out>
float3 outputs:out
}

def Shader "image1"
{
uniform token info:id = "ND_image_vector3"
asset inputs:file = @textures/mesh_wire_norm.png@
string inputs:filtertype = "closest"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No geompropvalue node, so will default to "st"

float3 outputs:out
}
}

def Material "standard_surface2"
{
token outputs:mtlx:surface.connect = </mtl/standard_surface2/standard_surface1.outputs:out>

def Shader "standard_surface1"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
float3 inputs:normal.connect = </mtl/standard_surface2/normalmap1.outputs:out>
token outputs:out
}

def Shader "normalmap1"
{
uniform token info:id = "ND_normalmap"
float3 inputs:in.connect = </mtl/standard_surface2/image1.outputs:out>
float3 outputs:out
}

def Shader "image1"
{
uniform token info:id = "ND_image_vector3"
asset inputs:file = @textures/mesh_wire_norm.png@
string inputs:filtertype = "closest"
float2 inputs:texcoord.connect = </mtl/standard_surface2/geompropvalue1.outputs:out>
float3 outputs:out
}

def Shader "geompropvalue1"
{
uniform token info:id = "ND_geompropvalue_vector2"
string inputs:geomprop = "st1"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In this case, since this is the geompropreader connected to the normalmap image, this will be also connected to the auto-added texcoordtangents node.

float2 outputs:out
}
}
}

def Mesh "Background" (
Expand Down Expand Up @@ -614,3 +662,85 @@ def Mesh "Background" (
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}

def Mesh "pMultiUVPlane5" (
prepend apiSchemas = ["MaterialBindingAPI"]
kind = "component"
)
{
uniform bool doubleSided = 1
float3[] extent = [(-0.5, 0, -0.5), (0.5, 0, 0.5)]
int[] faceVertexCounts = [4]
int[] faceVertexIndices = [0, 1, 3, 2]
rel material:binding = </mtl/standard_surface1>
point3f[] points = [(-0.5, 0, 0.5), (0.5, 0, 0.5), (-0.5, 0, -0.5), (0.5, 0, -0.5)]
color3f[] primvars:displayColor = [(0.13320851, 0.13320851, 0.13320851)] (
customData = {
dictionary Maya = {
bool generated = 1
}
}
)
texCoord2f[] primvars:st1 = [(1.5051357, 0.5019881), (0.4980119, 1.5051357), (0.5019881, -0.50513566), (-0.50513566, 0.4980119)] (
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using UVs tilted 45 and 135 degrees to make sure we are not using the arbitrary tangent generator.

customData = {
dictionary Maya = {
token name = "map1"
}
}
interpolation = "faceVarying"
)
texCoord2f[] primvars:st = [(0.50056624, -0.00038683414), (1.0003868, 0.50056624), (-0.00038683414, 0.49943376), (0.49943376, 1.0003868)] (
customData = {
dictionary Maya = {
token name = "uvSet1"
}
}
interpolation = "faceVarying"
)
int[] primvars:st1:indices = [0, 1, 3, 2]
int[] primvars:st:indices = [0, 1, 3, 2]
token visibility = "inherited"
double3 xformOp:translate = (-2.2, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate"]
}

def Mesh "pMultiUVPlane6" (
prepend apiSchemas = ["MaterialBindingAPI"]
kind = "component"
)
{
uniform bool doubleSided = 1
float3[] extent = [(-0.5, 0, -0.5), (0.5, 0, 0.5)]
int[] faceVertexCounts = [4]
int[] faceVertexIndices = [0, 1, 3, 2]
rel material:binding = </mtl/standard_surface2>
point3f[] points = [(-0.5, 0, 0.5), (0.5, 0, 0.5), (-0.5, 0, -0.5), (0.5, 0, -0.5)]
color3f[] primvars:displayColor = [(0.13320851, 0.13320851, 0.13320851)] (
customData = {
dictionary Maya = {
bool generated = 1
}
}
)
texCoord2f[] primvars:st1 = [(1.5051357, 0.5019881), (0.4980119, 1.5051357), (0.5019881, -0.50513566), (-0.50513566, 0.4980119)] (
customData = {
dictionary Maya = {
token name = "map1"
}
}
interpolation = "faceVarying"
)
texCoord2f[] primvars:st = [(0.50056624, -0.00038683414), (1.0003868, 0.50056624), (-0.00038683414, 0.49943376), (0.49943376, 1.0003868)] (
customData = {
dictionary Maya = {
token name = "uvSet1"
}
}
interpolation = "faceVarying"
)
int[] primvars:st1:indices = [0, 1, 3, 2]
int[] primvars:st:indices = [0, 1, 3, 2]
token visibility = "inherited"
double3 xformOp:translate = (-2.2, 0, 1.1)
uniform token[] xformOpOrder = ["xformOp:translate"]
}

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.