Skip to content

Commit

Permalink
Update normalmap node to 1.39 (#1911)
Browse files Browse the repository at this point in the history
- I have added the null-check from GLSL and MSL to the OSL and MDL backends for consistency. As an alternative, it could be removed from all implementations.

- Tangent vector renormalization in OSL seems like a concern that should be handled by the implementation providing the geometry streams. I removed it.
  • Loading branch information
pablode authored Jul 3, 2024
1 parent ac11732 commit 30f694f
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 70 deletions.
18 changes: 5 additions & 13 deletions libraries/stdlib/genglsl/mx_normalmap.glsl
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
void mx_normalmap_vector2(vec3 value, int map_space, vec2 normal_scale, vec3 N, vec3 T, out vec3 result)
void mx_normalmap_vector2(vec3 value, vec2 normal_scale, vec3 N, vec3 T, vec3 B, out vec3 result)
{
// Decode the normal map.
value = (value == vec3(0.0f)) ? vec3(0.0, 0.0, 1.0) : value * 2.0 - 1.0;
value = (value == vec3(0.0)) ? vec3(0.0, 0.0, 1.0) : value * 2.0 - 1.0;

// Transform from tangent space if needed.
if (map_space == 0)
{
vec3 B = normalize(cross(N, T));
value.xy *= normal_scale;
value = T * value.x + B * value.y + N * value.z;
}
value = T * value.x * normal_scale.x + B * value.y * normal_scale.y + N * value.z;

// Normalize the result.
result = normalize(value);
}

void mx_normalmap_float(vec3 value, int map_space, float normal_scale, vec3 N, vec3 T, out vec3 result)
void mx_normalmap_float(vec3 value, float normal_scale, vec3 N, vec3 T, vec3 B, out vec3 result)
{
mx_normalmap_vector2(value, map_space, vec2(normal_scale), N, T, result);
mx_normalmap_vector2(value, vec2(normal_scale), N, T, B, result);
}
4 changes: 2 additions & 2 deletions libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
<!-- <triplanarprojection> -->

<!-- <normalmap> -->
<implementation name="IM_normalmap_float_genmdl" nodedef="ND_normalmap_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_normalmap_float(mxp_in:{{in}}, mxp_space:{{space}}, mxp_scale:{{scale}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}})" target="genmdl" />
<implementation name="IM_normalmap_vector2_genmdl" nodedef="ND_normalmap_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_normalmap_vector2(mxp_in:{{in}}, mxp_space:{{space}}, mxp_scale:{{scale}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}})" target="genmdl" />
<implementation name="IM_normalmap_float_genmdl" nodedef="ND_normalmap_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_normalmap_float(mxp_in:{{in}}, mxp_scale:{{scale}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_bitangent:{{bitangent}})" target="genmdl" />
<implementation name="IM_normalmap_vector2_genmdl" nodedef="ND_normalmap_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_normalmap_vector2(mxp_in:{{in}}, mxp_scale:{{scale}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_bitangent:{{bitangent}})" target="genmdl" />

<!-- ======================================================================== -->
<!-- Procedural nodes -->
Expand Down
18 changes: 5 additions & 13 deletions libraries/stdlib/genmsl/mx_normalmap.metal
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
void mx_normalmap_vector2(vec3 value, int map_space, vec2 normal_scale, vec3 N, vec3 T, out vec3 result)
void mx_normalmap_vector2(vec3 value, vec2 normal_scale, vec3 N, vec3 T, vec3 B, out vec3 result)
{
// Decode the normal map.
value = all(value == vec3(0.0f)) ? vec3(0.0, 0.0, 1.0) : value * 2.0 - 1.0;
value = all(value == vec3(0.0)) ? vec3(0.0, 0.0, 1.0) : value * 2.0 - 1.0;

// Transform from tangent space if needed.
if (map_space == 0)
{
vec3 B = normalize(cross(N, T));
value.xy *= normal_scale;
value = T * value.x + B * value.y + N * value.z;
}
value = T * value.x * normal_scale.x + B * value.y * normal_scale.y + N * value.z;

// Normalize the result.
result = normalize(value);
}

void mx_normalmap_float(vec3 value, int map_space, float normal_scale, vec3 N, vec3 T, out vec3 result)
void mx_normalmap_float(vec3 value, float normal_scale, vec3 N, vec3 T, vec3 B, out vec3 result)
{
mx_normalmap_vector2(value, map_space, vec2(normal_scale), N, T, result);
mx_normalmap_vector2(value, vec2(normal_scale), N, T, B, result);
}
21 changes: 9 additions & 12 deletions libraries/stdlib/genosl/mx_normalmap.osl
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
void mx_normalmap_vector2(vector value, string map_space, vector2 normal_scale, vector N, vector U, output vector result)
void mx_normalmap_vector2(vector value, vector2 normal_scale, vector N, vector T, vector B, output vector result)
{
// Tangent space
if (map_space == "tangent")
vector decodedValue;
if (value == vector(0.0))
{
vector v = value * 2.0 - 1.0;
vector T = normalize(U - dot(U, N) * N);
vector B = normalize(cross(N, T));
result = normalize(T * v[0] * normal_scale.x + B * v[1] * normal_scale.y + N * v[2]);
decodedValue = vector(0.0, 0.0, 1.0);
}
// Object space
else
{
vector n = value * 2.0 - 1.0;
result = normalize(n);
decodedValue = value * 2.0 - 1.0;
}

result = normalize(T * decodedValue[0] * normal_scale.x + B * decodedValue[1] * normal_scale.y + N * decodedValue[2]);
}

void mx_normalmap_float(vector value, string map_space, float normal_scale, vector N, vector U, output vector result)
void mx_normalmap_float(vector value, float normal_scale, vector N, vector T, vector B, output vector result)
{
mx_normalmap_vector2(value, map_space, vector2(normal_scale, normal_scale), N, U, result);
mx_normalmap_vector2(value, vector2(normal_scale, normal_scale), N, T, B, result);
}
4 changes: 2 additions & 2 deletions libraries/stdlib/stdlib_defs.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -2604,18 +2604,18 @@
-->
<nodedef name="ND_normalmap_float" node="normalmap" nodegroup="math">
<input name="in" type="vector3" value="0.5, 0.5, 1.0" />
<input name="space" type="string" value="tangent" enum="tangent, object" uniform="true" />
<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="space" type="string" value="tangent" enum="tangent, object" uniform="true" />
<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>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<normalmap name="normalmap" type="vector3">
<input name="in" type="vector3" nodename="tiledimage" />
<input name="scale" type="float" value="1.1" />
<input name="space" type="string" value="tangent" />
</normalmap>
<tiledimage name="tiledimage" type="vector3">
<input name="file" type="filename" value="resources/images/mesh_wire_norm.png" />
Expand All @@ -40,7 +39,6 @@
<normalmap name="normalmap_vector2" type="vector3">
<input name="in" type="vector3" nodename="tiledimage2" />
<input name="scale" type="vector2" value="1.1, 1.1" />
<input name="space" type="string" value="tangent" />
</normalmap>
<tiledimage name="tiledimage2" type="vector3">
<input name="file" type="filename" value="resources/images/mesh_wire_norm.png" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
</convert>
<normalmap name="N_normalmap" type="vector3">
<input name="in" type="vector3" nodename="N_convert" />
<input name="space" type="string" value="object" />
</normalmap>
<UsdPreviewSurface name="N_surface" type="surfaceshader">
<input name="normal" type="vector3" nodename="N_normalmap" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
<normalmap name="impl_normalmap" type="vector3">
<input name="in" type="vector3" nodename="c3tov3" />
<input name="scale" type="float" value="1.5" />
<input name="space" type="string" value="tangent" />
</normalmap>
<output name="normal_map_output" type="vector3" nodename="impl_normalmap" />
</nodegraph>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,6 @@
<normalmap name="impl_normalmap" type="vector3">
<input name="in" type="vector3" nodename="b_image_invert_y" />
<input name="scale" type="float" interfacename="normal_scale" />
<input name="space" type="string" value="tangent" />
</normalmap>
<output name="out" type="vector3" nodename="impl_normalmap" />
</nodegraph>
Expand Down
20 changes: 19 additions & 1 deletion source/MaterialXCore/Version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1316,10 +1316,28 @@ void Document::upgradeVersion()
input2->setName("inx");
}
}
else if (node->getNodeDefString() == "ND_normalmap")
else if (nodeCategory == "normalmap")
{
// ND_normalmap was renamed to ND_normalmap_float
node->setNodeDefString("ND_normalmap_float");

node->removeInput("space");

// If the normal or tangent inputs are set, the bitangent input should be normalize(cross(N, T))
InputPtr normalInput = node->getInput("normal");
InputPtr tangentInput = node->getInput("tangent");
if (normalInput || tangentInput)
{
GraphElementPtr graph = node->getAncestorOfType<GraphElement>();
NodePtr crossNode = graph->addNode("crossproduct", graph->createValidChildName("normalmap_cross"), "vector3");
copyInputWithBindings(node, "normal", crossNode, "in1");
copyInputWithBindings(node, "tangent", crossNode, "in2");

NodePtr normalizeNode = graph->addNode("normalize", graph->createValidChildName("normalmap_cross_norm"), "vector3");
normalizeNode->addInput("in", "vector3")->setConnectedNode(crossNode);

node->addInput("bitangent", "vector3")->setConnectedNode(normalizeNode);
}
}
}
for (NodePtr node : unusedNodes)
Expand Down
30 changes: 8 additions & 22 deletions source/MaterialXGenMdl/mdl/materialx/stdlib_1_6.mdl
Original file line number Diff line number Diff line change
Expand Up @@ -2094,46 +2094,32 @@ export float4 mx_transformmatrix_vector4(

export float3 mx_normalmap_vector2(
float3 mxp_in = float3(0.5, 0.5, 1.0),
uniform string mxp_space = string("tangent")
[[
anno::description("Enumeration {tangent, object}.")
]],
float2 mxp_scale = float2(1.0, 1.0),
float3 mxp_normal = float3(::state::transform_normal(::state::coordinate_internal,::state::coordinate_world,::state::normal())),
float3 mxp_tangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_u(0)))
float3 mxp_tangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_u(0))),
float3 mxp_bitangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_v(0)))
)
[[
anno::description("Node Group: math")
]]
{
if (mxp_space == "tangent")
{
float3 v = mxp_in * 2.0 - 1.0;
float3 binormal = ::math::normalize(::math::cross(mxp_normal, mxp_tangent));
return ::math::normalize(mxp_tangent * v.x * mxp_scale.x + binormal * v.y * mxp_scale.y + mxp_normal * v.z);
}
else
{
float3 n = mxp_in * 2.0 - 1.0;
return ::math::normalize(n);
}
float3 v = (mxp_in == float3(0.0)) ? float3(0.0, 0.0, 1.0) : mxp_in * 2.0 - 1.0;

return ::math::normalize(mxp_tangent * v.x * mxp_scale.x + mxp_bitangent * v.y * mxp_scale.y + mxp_normal * v.z);
}

export float3 mx_normalmap_float(
float3 mxp_in = float3(0.5, 0.5, 1.0),
uniform string mxp_space = string("tangent")
[[
anno::description("Enumeration {tangent, object}.")
]],
float mxp_scale = float(1.0),
float3 mxp_normal = float3(::state::transform_normal(::state::coordinate_internal,::state::coordinate_world,::state::normal())),
float3 mxp_tangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_u(0)))
float3 mxp_tangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_u(0))),
float3 mxp_bitangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_v(0)))
)
[[
anno::description("Node Group: math")
]]
{
return mx_normalmap_vector2(mxp_in, mxp_space, float2(mxp_scale, mxp_scale), mxp_normal, mxp_tangent);
return mx_normalmap_vector2(mxp_in, float2(mxp_scale, mxp_scale), mxp_normal, mxp_tangent, mxp_bitangent);
}

export float3x3 mx_transpose_matrix33(
Expand Down
7 changes: 7 additions & 0 deletions source/MaterialXRenderMsl/MslPipelineStateObject.mm
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,13 @@ int GetStrideOfMetalType(MTLDataType type)
bindAttribute(renderCmdEncoder, foundList, mesh);
}

// Bind bitangents
findInputs(HW::IN_BITANGENT, attributeList, foundList, true);
if (foundList.size())
{
bindAttribute(renderCmdEncoder, foundList, mesh);
}

// Bind colors
// Search for anything that starts with the color prefix
findInputs(HW::IN_COLOR + "_", attributeList, foundList, false);
Expand Down

0 comments on commit 30f694f

Please sign in to comment.