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

Add fileTextureVerticalFlip option for MDL generation #1418

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
12 changes: 6 additions & 6 deletions libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@
<!-- ======================================================================== -->

<!-- <image> -->
<implementation name="IM_image_float_genmdl" nodedef="ND_image_float" sourcecode="mx::stdlib::mx_image_float({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}})" target="genmdl">
<implementation name="IM_image_float_genmdl" nodedef="ND_image_float" sourcecode="mx::stdlib::mx_image_float({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
<input name="default" type="float" implname="default_value" />
</implementation>
<implementation name="IM_image_color3_genmdl" nodedef="ND_image_color3" sourcecode="mx::stdlib::mx_image_color3({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}})" target="genmdl">
<implementation name="IM_image_color3_genmdl" nodedef="ND_image_color3" sourcecode="mx::stdlib::mx_image_color3({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
<input name="default" type="color3" implname="default_value" />
</implementation>
<implementation name="IM_image_color4_genmdl" nodedef="ND_image_color4" sourcecode="mx::stdlib::mx_image_color4({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}})" target="genmdl">
<implementation name="IM_image_color4_genmdl" nodedef="ND_image_color4" sourcecode="mx::stdlib::mx_image_color4({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
<input name="default" type="color4" implname="default_value" />
</implementation>
<implementation name="IM_image_vector2_genmdl" nodedef="ND_image_vector2" sourcecode="mx::stdlib::mx_image_vector2({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}})" target="genmdl">
<implementation name="IM_image_vector2_genmdl" nodedef="ND_image_vector2" sourcecode="mx::stdlib::mx_image_vector2({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
<input name="default" type="vector2" implname="default_value" />
</implementation>
<implementation name="IM_image_vector3_genmdl" nodedef="ND_image_vector3" sourcecode="mx::stdlib::mx_image_vector3({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}})" target="genmdl">
<implementation name="IM_image_vector3_genmdl" nodedef="ND_image_vector3" sourcecode="mx::stdlib::mx_image_vector3({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
<input name="default" type="vector3" implname="default_value" />
</implementation>
<implementation name="IM_image_vector4_genmdl" nodedef="ND_image_vector4" sourcecode="mx::stdlib::mx_image_vector4({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}})" target="genmdl">
<implementation name="IM_image_vector4_genmdl" nodedef="ND_image_vector4" sourcecode="mx::stdlib::mx_image_vector4({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
<input name="default" type="vector4" implname="default_value" />
</implementation>

Expand Down
9 changes: 9 additions & 0 deletions source/MaterialXGenMdl/MdlShaderGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <MaterialXGenMdl/Nodes/ClosureCompoundNodeMdl.h>
#include <MaterialXGenMdl/Nodes/ClosureSourceCodeNodeMdl.h>
#include <MaterialXGenMdl/Nodes/SwizzleNodeMdl.h>
#include <MaterialXGenMdl/Nodes/ImageNodeMdl.h>

#include <MaterialXGenShader/GenContext.h>
#include <MaterialXGenShader/Shader.h>
Expand Down Expand Up @@ -187,6 +188,14 @@ MdlShaderGenerator::MdlShaderGenerator() :

// <!-- <sheen_bsdf> -->
registerImplementation("IM_sheen_bsdf_" + MdlShaderGenerator::TARGET, LayerableNodeMdl::create);

// <!-- <image> -->
registerImplementation("IM_image_float_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create);
registerImplementation("IM_image_color3_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create);
registerImplementation("IM_image_color4_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create);
registerImplementation("IM_image_vector2_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create);
registerImplementation("IM_image_vector3_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create);
registerImplementation("IM_image_vector4_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create);
}

ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, GenContext& context) const
Expand Down
50 changes: 50 additions & 0 deletions source/MaterialXGenMdl/Nodes/ImageNodeMdl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//

#include <MaterialXGenMdl/Nodes/ImageNodeMdl.h>
#include <MaterialXGenShader/ShaderGenerator.h>
#include <MaterialXGenShader/Shader.h>
#include <MaterialXGenShader/GenContext.h>

MATERIALX_NAMESPACE_BEGIN

const string ImageNodeMdl::FLIP_V = "flip_v";

ShaderNodeImplPtr ImageNodeMdl::create()
{
return std::make_shared<ImageNodeMdl>();
}

void ImageNodeMdl::addInputs(ShaderNode& node, GenContext& context) const
{
BASE::addInputs(node, context);
node.addInput(ImageNodeMdl::FLIP_V, Type::BOOLEAN)->setUniform();
}

bool ImageNodeMdl::isEditable(const ShaderInput& input) const
{
if (input.getName() == ImageNodeMdl::FLIP_V)
{
return false;
}
return BASE::isEditable(input);
}

void ImageNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext& context, ShaderStage& stage) const
{
DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
{
ShaderNode& node = const_cast<ShaderNode&>(_node);
ShaderInput* flipUInput = node.getInput(ImageNodeMdl::FLIP_V);
ValuePtr value = TypedValue<bool>::createValue(context.getOptions().fileTextureVerticalFlip);
if (flipUInput)
{
flipUInput->setValue(value);
}
BASE::emitFunctionCall(_node, context, stage);
}
}

MATERIALX_NAMESPACE_END
34 changes: 34 additions & 0 deletions source/MaterialXGenMdl/Nodes/ImageNodeMdl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//

#ifndef MATERIALX_IMAGENODEMDL_H
#define MATERIALX_IMAGENODEMDL_H

#include <MaterialXGenMdl/Export.h>

#include "SourceCodeNodeMdl.h"

MATERIALX_NAMESPACE_BEGIN

/// Image node implementation for MDL
class MX_GENMDL_API ImageNodeMdl : public SourceCodeNodeMdl
{
using BASE = SourceCodeNodeMdl;

public:
static const string FLIP_V; ///< the empty string ""

static ShaderNodeImplPtr create();

void addInputs(ShaderNode& node, GenContext& context) const override;

bool isEditable(const ShaderInput& input) const override;

void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
};

MATERIALX_NAMESPACE_END

#endif
54 changes: 48 additions & 6 deletions source/MaterialXGenMdl/mdl/materialx/stdlib.mdl
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ export float mx_image_float(
anno::description("Enumeration {constant,clamp,periodic,mirror}."),
anno::display_name("Frame End Action"),
anno::unused()
]],
uniform bool mxp_flip_v = false
[[
anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."),
anno::hidden()
]]
)
[[
Expand All @@ -153,7 +158,9 @@ export float mx_image_float(
return mxp_default;

float returnValue = ::tex::lookup_float(tex: mxp_file,
coord: mxp_texcoord,
coord: mxp_flip_v
? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y)
: mxp_texcoord,
wrap_u: map_addressmode(mxp_uaddressmode),
wrap_v: map_addressmode(mxp_vaddressmode));
return returnValue;
Expand Down Expand Up @@ -207,6 +214,11 @@ export color mx_image_color3(
anno::description("Enumeration {constant,clamp,periodic,mirror}."),
anno::display_name("Frame End Action"),
anno::unused()
]],
uniform bool mxp_flip_v = false
[[
anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."),
anno::hidden()
]]
)
[[
Expand All @@ -221,7 +233,9 @@ export color mx_image_color3(
return mxp_default;

color returnValue = ::tex::lookup_color(tex: mxp_file,
coord: mxp_texcoord,
coord: mxp_flip_v
? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y)
: mxp_texcoord,
wrap_u: map_addressmode(mxp_uaddressmode),
wrap_v: map_addressmode(mxp_vaddressmode));
return returnValue;
Expand Down Expand Up @@ -275,6 +289,11 @@ export color4 mx_image_color4(
anno::description("Enumeration {constant,clamp,periodic,mirror}."),
anno::display_name("Frame End Action"),
anno::unused()
]],
uniform bool mxp_flip_v = false
[[
anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."),
anno::hidden()
]]
)
[[
Expand All @@ -289,7 +308,9 @@ export color4 mx_image_color4(
return mxp_default;

color4 returnValue = mk_color4( ::tex::lookup_float4(tex: mxp_file,
coord: mxp_texcoord,
coord: mxp_flip_v
? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y)
: mxp_texcoord,
wrap_u: map_addressmode(mxp_uaddressmode),
wrap_v: map_addressmode(mxp_vaddressmode)));
return returnValue;
Expand Down Expand Up @@ -343,6 +364,11 @@ export float2 mx_image_vector2(
anno::description("Enumeration {constant,clamp,periodic,mirror}."),
anno::display_name("Frame End Action"),
anno::unused()
]],
uniform bool mxp_flip_v = false
[[
anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."),
anno::hidden()
]]
)
[[
Expand All @@ -357,7 +383,9 @@ export float2 mx_image_vector2(
return mxp_default;

float2 returnValue = ::tex::lookup_float2(tex: mxp_file,
coord: mxp_texcoord,
coord: mxp_flip_v
? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y)
: mxp_texcoord,
wrap_u: map_addressmode(mxp_uaddressmode),
wrap_v: map_addressmode(mxp_vaddressmode));
return returnValue;
Expand Down Expand Up @@ -411,6 +439,11 @@ export float3 mx_image_vector3(
anno::description("Enumeration {constant,clamp,periodic,mirror}."),
anno::display_name("Frame End Action"),
anno::unused()
]],
uniform bool mxp_flip_v = false
[[
anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."),
anno::hidden()
]]
)
[[
Expand All @@ -425,7 +458,9 @@ export float3 mx_image_vector3(
return mxp_default;

float3 returnValue = ::tex::lookup_float3(tex: mxp_file,
coord: mxp_texcoord,
coord: mxp_flip_v
? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y)
: mxp_texcoord,
wrap_u: map_addressmode(mxp_uaddressmode),
wrap_v: map_addressmode(mxp_vaddressmode));
return returnValue;
Expand Down Expand Up @@ -479,6 +514,11 @@ export float4 mx_image_vector4(
anno::description("Enumeration {constant,clamp,periodic,mirror}."),
anno::display_name("Frame End Action"),
anno::unused()
]],
uniform bool mxp_flip_v = false
[[
anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."),
anno::hidden()
]]
)
[[
Expand All @@ -493,7 +533,9 @@ export float4 mx_image_vector4(
return mxp_default;

float4 returnValue = ::tex::lookup_float4(tex: mxp_file,
coord: mxp_texcoord,
coord: mxp_flip_v
? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y)
: mxp_texcoord,
wrap_u: map_addressmode(mxp_uaddressmode),
wrap_v: map_addressmode(mxp_vaddressmode));
return returnValue;
Expand Down
18 changes: 17 additions & 1 deletion source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,10 @@ void MdlShaderGeneratorTester::compileSource(const std::vector<mx::FilePath>& so
std::string iblFile = (rootPath / "resources/lights/san_giuseppe_bridge.hdr").asString();
renderCommand += " --hdr \"" + iblFile + "\" --hdr_rotate 90";
// set scene
renderCommand += " --uv_scale 0.5 1.0 --uv_offset 0.0 0.0 --uv_repeat --uv_flip";
renderCommand += " --uv_scale 0.5 1.0 --uv_offset 0.0 0.0 --uv_repeat";
renderCommand += " --uv_flip"; // this will flip the v coordinate of the vertices, which flips all the
// UV operations. In contrast, the fileTextureVerticalFlip option will
// only flip the image access nodes.
renderCommand += " --camera 0 0 3 0 0 0 --fov 45";

// set the material
Expand Down Expand Up @@ -365,6 +368,19 @@ TEST_CASE("GenShader: MDL Shader Generation", "[genmdl]")

mx::GenOptions genOptions;
genOptions.targetColorSpaceOverride = "lin_rec709";

// Flipping the texture lookups for the test renderer only.
// This is because OSL testrender does not allow to change the UV layout of their sphere (yet) and the MaterialX test suite
// adopts the OSL behavior in order to produce comparable results. This means that raw texture coordinates, or procedurals
// that use the texture coordinates, do not match what might be expected when reading the MaterialX spec:
// "[...] the image is mapped onto the geometry based on geometry UV coordinates, with the lower-left corner of an image
// mapping to the (0,0) UV coordinate [...]"
// This means for MDL: here, and only here in the test suite, we flip the UV coordinates of mesh using the `--uv_flip` option
// of the renderer, and to correct the image orientation, we apply `fileTextureVerticalFlip`.
// In regular MDL integrations this is not needed because MDL and MaterialX define the texture space equally with the origin
// at the bottom left.
genOptions.fileTextureVerticalFlip = true;

mx::FilePath optionsFilePath = searchPath.find("resources/Materials/TestSuite/_options.mtlx");
tester.validate(genOptions, optionsFilePath);
}