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 transmission rendering option #928

Merged
merged 1 commit into from
May 2, 2022
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
32 changes: 15 additions & 17 deletions source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,11 @@ void SurfaceNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& conte
const ShaderNode* bsdf = bsdfInput->getConnectedSibling();
if (bsdf)
{
if (context.getOptions().hwTransparency)
{
shadergen.emitLineBegin(stage);
shadergen.emitString("float surfaceOpacity = ", stage);
shadergen.emitInput(node.getInput("opacity"), context, stage);
shadergen.emitLineEnd(stage);
shadergen.emitLineBreak(stage);
}
shadergen.emitLineBegin(stage);
shadergen.emitString("float surfaceOpacity = ", stage);
shadergen.emitInput(node.getInput("opacity"), context, stage);
shadergen.emitLineEnd(stage);
shadergen.emitLineBreak(stage);

//
// Handle direct lighting
Expand Down Expand Up @@ -196,30 +193,31 @@ void SurfaceNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& conte
}

//
// Handle surface transmission.
// Handle surface transmission and opacity.
//
if (bsdf)
{
shadergen.emitComment("Calculate the BSDF transmission for viewing direction", stage);
shadergen.emitScopeBegin(stage);
context.pushClosureContext(&_callTransmission);
shadergen.emitFunctionCall(*bsdf, context, stage);
shadergen.emitLine(outColor + " += " + bsdf->getOutput()->getVariable() + ".response", stage);
if (context.getOptions().hwTransmissionRenderMethod == TRANSMISSION_REFRACTION)
{
shadergen.emitLine(outColor + " += " + bsdf->getOutput()->getVariable() + ".response", stage);
}
else
{
shadergen.emitLine(outTransparency + " += " + bsdf->getOutput()->getVariable() + ".throughput", stage);
}
shadergen.emitScopeEnd(stage);
context.popClosureContext();
}

//
// Handle surface opacity.
//
if (bsdf && context.getOptions().hwTransparency)
{
shadergen.emitLineBreak(stage);
shadergen.emitComment("Compute and apply surface opacity", stage);
shadergen.emitScopeBegin(stage);
shadergen.emitLine(outColor + " *= surfaceOpacity", stage);
shadergen.emitLine(outTransparency + " = mix(vec3(1.0), " + outTransparency + ", surfaceOpacity)", stage);
shadergen.emitScopeEnd(stage);
shadergen.emitLineBreak(stage);
}

shadergen.emitScopeEnd(stage);
Expand Down
19 changes: 8 additions & 11 deletions source/MaterialXGenGlsl/Nodes/UnlitSurfaceNodeGlsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,14 @@ void UnlitSurfaceNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext&
const ShaderInput* emissionColor = node.getInput("emission_color");
shadergen.emitLine(outColor + " = " + shadergen.getUpstreamResult(emission, context) + " * " + shadergen.getUpstreamResult(emissionColor, context), stage);

if (context.getOptions().hwTransparency)
{
const ShaderInput* transmission = node.getInput("transmission");
const ShaderInput* transmissionColor = node.getInput("transmission_color");
shadergen.emitLine(outTransparency + " = " + shadergen.getUpstreamResult(transmission, context) + " * " + shadergen.getUpstreamResult(transmissionColor, context), stage);

const ShaderInput* opacity = node.getInput("opacity");
const string surfaceOpacity = shadergen.getUpstreamResult(opacity, context);
shadergen.emitLine(outColor + " *= " + surfaceOpacity, stage);
shadergen.emitLine(outTransparency + " = mix(vec3(1.0), " + outTransparency + ", " + surfaceOpacity + ")", stage);
}
const ShaderInput* transmission = node.getInput("transmission");
const ShaderInput* transmissionColor = node.getInput("transmission_color");
shadergen.emitLine(outTransparency + " = " + shadergen.getUpstreamResult(transmission, context) + " * " + shadergen.getUpstreamResult(transmissionColor, context), stage);

const ShaderInput* opacity = node.getInput("opacity");
const string surfaceOpacity = shadergen.getUpstreamResult(opacity, context);
shadergen.emitLine(outColor + " *= " + surfaceOpacity, stage);
shadergen.emitLine(outTransparency + " = mix(vec3(1.0), " + outTransparency + ", " + surfaceOpacity + ")", stage);

END_SHADER_STAGE(stage, Stage::PIXEL)
}
Expand Down
15 changes: 15 additions & 0 deletions source/MaterialXGenShader/GenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ enum HwDirectionalAlbedoMethod
DIRECTIONAL_ALBEDO_MONTE_CARLO
};

/// Method to use for transmission rendering
enum HwTransmissionRenderMethod
{
/// Use a refraction approximation for transmission rendering
TRANSMISSION_REFRACTION,

/// Use opacity for transmission rendering
TRANSMISSION_OPACITY,
};

/// @class GenOptions
/// Class holding options to configure shader generation.
class MX_GENSHADER_API GenOptions
Expand All @@ -73,6 +83,7 @@ class MX_GENSHADER_API GenOptions
hwTransparency(false),
hwSpecularEnvironmentMethod(SPECULAR_ENVIRONMENT_FIS),
hwDirectionalAlbedoMethod(DIRECTIONAL_ALBEDO_ANALYTIC),
hwTransmissionRenderMethod(TRANSMISSION_REFRACTION),
hwWriteDepthMoments(false),
hwShadowMap(false),
hwAmbientOcclusion(false),
Expand Down Expand Up @@ -131,6 +142,10 @@ class MX_GENSHADER_API GenOptions
/// for HW shader targets.
HwDirectionalAlbedoMethod hwDirectionalAlbedoMethod;

/// Sets the method to use for transmission rendering
/// for HW shader targets.
HwTransmissionRenderMethod hwTransmissionRenderMethod;

/// Enables the writing of depth moments for HW shader targets.
/// Defaults to false.
bool hwWriteDepthMoments;
Expand Down
3 changes: 2 additions & 1 deletion source/MaterialXGenShader/Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ namespace

// Inputs on a surface shader which are checked for transparency
const OpaqueTestPairList inputPairList = { {"opacity", 1.0f},
{"existence", 1.0f} };
{"existence", 1.0f},
{"transmission", 0.0f} };


// Check against the interface if a node is passed in to check against
Expand Down
2 changes: 1 addition & 1 deletion source/MaterialXTest/MaterialXGenShader/GenShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ TEST_CASE("GenShader: Transparency Regression Check", "[genshader]")
"Materials/TestSuite/pbrlib/surfaceshader/transparency_nodedef_test.mtlx",
"Materials/TestSuite/pbrlib/surfaceshader/transparency_test.mtlx",
};
std::vector<bool> transparencyTest = { false, false, true, true, true };
std::vector<bool> transparencyTest = { false, true, true, true, true };
for (size_t i=0; i<testFiles.size(); i++)
{
const mx::FilePath& testFile = resourcePath / testFiles[i];
Expand Down
9 changes: 9 additions & 0 deletions source/MaterialXView/Viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,15 @@ void Viewer::createAdvancedSettings(Widget* parent)
reloadShaders();
});

ng::CheckBox* refractionBox = new ng::CheckBox(advancedPopup, "Transmission Refraction");
refractionBox->set_checked(_genContext.getOptions().hwTransmissionRenderMethod == mx::TRANSMISSION_REFRACTION);
refractionBox->set_callback([this](bool enable)
{
_genContext.getOptions().hwTransmissionRenderMethod = enable ? mx::TRANSMISSION_REFRACTION : mx::TRANSMISSION_OPACITY;
_genContextEssl.getOptions().hwTransmissionRenderMethod = _genContext.getOptions().hwTransmissionRenderMethod;
reloadShaders();
});

Widget* albedoGroup = new Widget(advancedPopup);
albedoGroup->set_layout(new ng::BoxLayout(ng::Orientation::Horizontal));
new ng::Label(albedoGroup, "Albedo Method:");
Expand Down