diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js
index 5bd432d713..6e684e01e4 100644
--- a/javascript/MaterialXView/source/viewer.js
+++ b/javascript/MaterialXView/source/viewer.js
@@ -382,7 +382,8 @@ export class Material
u_envRadiance: { value: radianceTexture },
u_envRadianceMips: { value: Math.trunc(Math.log2(Math.max(radianceTexture.image.width, radianceTexture.image.height))) + 1 },
u_envRadianceSamples: { value: 16 },
- u_envIrradiance: { value: irradianceTexture }
+ u_envIrradiance: { value: irradianceTexture },
+ u_refractionEnv: { value: true }
});
// Create Three JS Material
diff --git a/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl b/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl
index 66e8ab08a6..cee193514d 100644
--- a/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl
+++ b/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl
@@ -34,7 +34,7 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio
// Compute the half vector and incoming light direction.
vec3 H = mx_ggx_importance_sample_NDF(Xi, alpha);
- vec3 L = -reflect(V, H);
+ vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, H, fd.ior.x) : -reflect(V, H);
// Compute dot products for this sample.
float NdotH = clamp(H.z, M_FLOAT_EPS, 1.0);
@@ -54,13 +54,16 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio
// Compute the geometric term.
float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);
+ // Compute the combined FG term, which is inverted for refraction.
+ vec3 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G;
+
// Add the radiance contribution of this sample.
// From https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
// incidentLight = sampleColor * NdotL
// microfacetSpecular = D * F * G / (4 * NdotL * NdotV)
// pdf = D * NdotH / (4 * VdotH)
// radiance = incidentLight * microfacetSpecular / pdf
- radiance += sampleColor * F * G * VdotH / (NdotV * NdotH);
+ radiance += sampleColor * FG * VdotH / (NdotV * NdotH);
}
// Normalize and return the final radiance.
diff --git a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl
index ea5ad4caa3..4d9fedc77f 100644
--- a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl
+++ b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl
@@ -26,6 +26,9 @@ struct FresnelData
// Thin film
float tf_thickness;
float tf_ior;
+
+ // Refraction
+ bool refraction;
};
// https://media.disneyanimation.com/uploads/production/publication_asset/48/asset/s2012_pbs_disney_brdf_notes_v3.pdf
@@ -217,6 +220,13 @@ float mx_ior_to_f0(float ior)
return mx_square((ior - 1.0) / (ior + 1.0));
}
+// Convert normal-incidence reflectivity to real-valued index of refraction.
+float mx_f0_to_ior(float F0)
+{
+ float sqrtF0 = sqrt(F0);
+ return (1.0 + sqrtF0) / (1.0 - sqrtF0);
+}
+
// https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/
float mx_fresnel_dielectric(float cosTheta, float ior)
{
@@ -387,7 +397,7 @@ vec3 mx_fresnel_airy(float cosTheta, vec3 ior, vec3 extinction, float tf_thickne
FresnelData mx_init_fresnel_data(int model)
{
- return FresnelData(model, vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), 0.0, 0.0, 0.0);
+ return FresnelData(model, vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), 0.0, 0.0, 0.0, false);
}
FresnelData mx_init_fresnel_dielectric(float ior)
@@ -462,6 +472,14 @@ vec3 mx_compute_fresnel(float cosTheta, FresnelData fd)
}
}
+// Compute the refraction of a ray through a solid sphere.
+vec3 mx_refraction_solid_sphere(vec3 R, vec3 N, float ior)
+{
+ R = refract(R, N, 1.0 / ior);
+ vec3 N1 = normalize(R * dot(R, N) - N * 0.5);
+ return refract(R, N1, ior);
+}
+
vec2 mx_latlong_projection(vec3 dir)
{
float latitude = -asin(dir.y) * M_PI_INV + 0.5;
diff --git a/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl b/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl
index c5b62ecb1b..2b4535066e 100644
--- a/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl
+++ b/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl
@@ -27,7 +27,7 @@ void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, floa
}
else
{
- fd = mx_init_fresnel_dielectric(ior);
+ fd = mx_init_fresnel_dielectric(ior);
}
vec3 F = mx_compute_fresnel(VdotH, fd);
float D = mx_ggx_NDF(Ht, safeAlpha);
@@ -44,14 +44,7 @@ void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, floa
void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
- if (scatter_mode == 1)
- {
- bsdf.response = tint * weight;
- bsdf.throughput = bsdf.response;
- return;
- }
-
- if (weight < M_FLOAT_EPS)
+ if (weight < M_FLOAT_EPS || scatter_mode == 0)
{
return;
}
@@ -61,20 +54,29 @@ void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior,
FresnelData fd;
if (bsdf.thickness > 0.0)
+ {
fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
+ }
else
+ {
fd = mx_init_fresnel_dielectric(ior);
-
+ }
vec3 F = mx_compute_fresnel(NdotV, fd);
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(safeAlpha);
+
float F0 = mx_ior_to_f0(ior);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
bsdf.throughput = 1.0 - dirAlbedo * weight;
- bsdf.response = (scatter_mode == 2) ? tint * weight * bsdf.throughput : vec3(0.0);
+ // For now, we approximate the appearance of dielectric transmission as
+ // glossy environment map refraction, ignoring any scene geometry that
+ // might be visible through the surface.
+ fd.refraction = true;
+ vec3 Li = $refractionEnv ? mx_environment_radiance(N, V, X, safeAlpha, distribution, fd) : $refractionColor;
+ bsdf.response = Li * tint * weight;
}
void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
@@ -90,14 +92,18 @@ void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec
FresnelData fd;
if (bsdf.thickness > 0.0)
+ {
fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior);
+ }
else
+ {
fd = mx_init_fresnel_dielectric(ior);
-
+ }
vec3 F = mx_compute_fresnel(NdotV, fd);
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(safeAlpha);
+
float F0 = mx_ior_to_f0(ior);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
diff --git a/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl b/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl
index 89b7693059..a71ea5adb5 100644
--- a/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl
+++ b/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl
@@ -36,14 +36,7 @@ void mx_generalized_schlick_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlus
void mx_generalized_schlick_bsdf_transmission(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
- if (scatter_mode == 1)
- {
- bsdf.response = color0 * weight;
- bsdf.throughput = bsdf.response;
- return;
- }
-
- if (weight < M_FLOAT_EPS)
+ if (weight < M_FLOAT_EPS || scatter_mode == 0)
{
return;
}
@@ -56,12 +49,20 @@ void mx_generalized_schlick_bsdf_transmission(vec3 V, float weight, vec3 color0,
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(safeAlpha);
+
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, color0, color90) * comp;
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);
- bsdf.response = (scatter_mode == 2) ? color0 * weight * bsdf.throughput : vec3(0.0);
+ // For now, we approximate the appearance of Schlick transmission as
+ // glossy environment map refraction, ignoring any scene geometry that
+ // might be visible through the surface.
+ float avgF0 = dot(color0, vec3(1.0 / 3.0));
+ fd.refraction = true;
+ fd.ior.x = mx_f0_to_ior(avgF0);
+ vec3 Li = $refractionEnv ? mx_environment_radiance(N, V, X, safeAlpha, distribution, fd) : $refractionColor;
+ bsdf.response = Li * color0 * weight;
}
void mx_generalized_schlick_bsdf_indirect(vec3 V, float weight, vec3 color0, vec3 color90, float exponent, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
diff --git a/resources/Materials/Examples/StandardSurface/standard_surface_glass_tinted.mtlx b/resources/Materials/Examples/StandardSurface/standard_surface_glass_tinted.mtlx
new file mode 100644
index 0000000000..0248477d43
--- /dev/null
+++ b/resources/Materials/Examples/StandardSurface/standard_surface_glass_tinted.mtlx
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx
index 8aec9e5469..6f6c3f03aa 100644
--- a/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx
+++ b/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx
@@ -1,122 +1,43 @@
-
-
-
+
+
-
-
-
+
+
-
-
-
-
+
+
+
-
-
-
+
+
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
+
-
+
diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx
index b4e51053b6..52a00023f7 100644
--- a/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx
+++ b/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx
@@ -1,20 +1,49 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/Materials/TestSuite/pbrlib/surfaceshader/transparency_nodedef_test.mtlx b/resources/Materials/TestSuite/pbrlib/surfaceshader/transparency_nodedef_test.mtlx
index 549fad4ce3..5d36fed57a 100644
--- a/resources/Materials/TestSuite/pbrlib/surfaceshader/transparency_nodedef_test.mtlx
+++ b/resources/Materials/TestSuite/pbrlib/surfaceshader/transparency_nodedef_test.mtlx
@@ -17,16 +17,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -45,35 +35,27 @@
-
-
-
-
-
-
-
-
@@ -86,9 +68,6 @@
-
-
-
@@ -115,24 +94,20 @@
-
-
-
-
diff --git a/resources/Materials/TestSuite/pbrlib/surfaceshader/transparency_test.mtlx b/resources/Materials/TestSuite/pbrlib/surfaceshader/transparency_test.mtlx
index 65c93c1d4d..e96756715f 100644
--- a/resources/Materials/TestSuite/pbrlib/surfaceshader/transparency_test.mtlx
+++ b/resources/Materials/TestSuite/pbrlib/surfaceshader/transparency_test.mtlx
@@ -17,16 +17,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -45,10 +35,8 @@
-
-
@@ -62,9 +50,6 @@
-
-
-
@@ -91,7 +76,6 @@
-
diff --git a/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp
index a65faa9799..c0a9f8b46b 100644
--- a/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp
+++ b/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp
@@ -196,28 +196,30 @@ void SurfaceNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& conte
}
//
- // Handle surface transparency
+ // Handle surface transmission.
//
- if (bsdf && context.getOptions().hwTransparency)
+ if (bsdf)
{
shadergen.emitComment("Calculate the BSDF transmission for viewing direction", stage);
shadergen.emitScopeBegin(stage);
-
context.pushClosureContext(&_callTransmission);
shadergen.emitFunctionCall(*bsdf, context, stage);
- context.popClosureContext();
-
- shadergen.emitLine(outTransparency + " = " + bsdf->getOutput()->getVariable() + ".response", stage);
+ shadergen.emitLine(outColor + " += " + bsdf->getOutput()->getVariable() + ".response", stage);
shadergen.emitScopeEnd(stage);
- shadergen.emitLineBreak(stage);
+ context.popClosureContext();
+ }
- shadergen.emitComment("Mix in opacity which affect the total result", stage);
+ //
+ // Handle surface opacity.
+ //
+ if (bsdf && context.getOptions().hwTransparency)
+ {
+ 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);
- }
- else
- {
- shadergen.emitLine(outTransparency + " = vec3(0.0)", stage);
+ shadergen.emitScopeEnd(stage);
+ shadergen.emitLineBreak(stage);
}
shadergen.emitScopeEnd(stage);
diff --git a/source/MaterialXGenGlsl/Nodes/UnlitSurfaceNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/UnlitSurfaceNodeGlsl.cpp
index 2d2168c921..ad72bf08b8 100644
--- a/source/MaterialXGenGlsl/Nodes/UnlitSurfaceNodeGlsl.cpp
+++ b/source/MaterialXGenGlsl/Nodes/UnlitSurfaceNodeGlsl.cpp
@@ -45,10 +45,6 @@ void UnlitSurfaceNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext&
shadergen.emitLine(outColor + " *= " + surfaceOpacity, stage);
shadergen.emitLine(outTransparency + " = mix(vec3(1.0), " + outTransparency + ", " + surfaceOpacity + ")", stage);
}
- else
- {
- shadergen.emitLine(outTransparency + " = vec3(0.0)", stage);
- }
END_SHADER_STAGE(stage, Stage::PIXEL)
}
diff --git a/source/MaterialXGenShader/HwShaderGenerator.cpp b/source/MaterialXGenShader/HwShaderGenerator.cpp
index eca4db6edf..72f2bf26a2 100644
--- a/source/MaterialXGenShader/HwShaderGenerator.cpp
+++ b/source/MaterialXGenShader/HwShaderGenerator.cpp
@@ -57,6 +57,8 @@ namespace HW
const string T_ENV_RADIANCE_MIPS = "$envRadianceMips";
const string T_ENV_RADIANCE_SAMPLES = "$envRadianceSamples";
const string T_ENV_IRRADIANCE = "$envIrradiance";
+ const string T_REFRACTION_ENV = "$refractionEnv";
+ const string T_REFRACTION_COLOR = "$refractionColor";
const string T_ALBEDO_TABLE = "$albedoTable";
const string T_ALBEDO_TABLE_SIZE = "$albedoTableSize";
const string T_AMB_OCC_MAP = "$ambOccMap";
@@ -109,6 +111,8 @@ namespace HW
const string ENV_RADIANCE_MIPS = "u_envRadianceMips";
const string ENV_RADIANCE_SAMPLES = "u_envRadianceSamples";
const string ENV_IRRADIANCE = "u_envIrradiance";
+ const string REFRACTION_ENV = "u_refractionEnv";
+ const string REFRACTION_COLOR = "u_refractionColor";
const string ALBEDO_TABLE = "u_albedoTable";
const string ALBEDO_TABLE_SIZE = "u_albedoTableSize";
const string AMB_OCC_MAP = "u_ambOccMap";
@@ -204,6 +208,8 @@ HwShaderGenerator::HwShaderGenerator(SyntaxPtr syntax) :
_tokenSubstitutions[HW::T_ENV_RADIANCE_MIPS] = HW::ENV_RADIANCE_MIPS;
_tokenSubstitutions[HW::T_ENV_RADIANCE_SAMPLES] = HW::ENV_RADIANCE_SAMPLES;
_tokenSubstitutions[HW::T_ENV_IRRADIANCE] = HW::ENV_IRRADIANCE;
+ _tokenSubstitutions[HW::T_REFRACTION_ENV] = HW::REFRACTION_ENV;
+ _tokenSubstitutions[HW::T_REFRACTION_COLOR] = HW::REFRACTION_COLOR;
_tokenSubstitutions[HW::T_ALBEDO_TABLE] = HW::ALBEDO_TABLE;
_tokenSubstitutions[HW::T_ALBEDO_TABLE_SIZE] = HW::ALBEDO_TABLE_SIZE;
_tokenSubstitutions[HW::T_SHADOW_MAP] = HW::SHADOW_MAP;
@@ -306,6 +312,8 @@ ShaderPtr HwShaderGenerator::createShader(const string& name, ElementPtr element
psPrivateUniforms->add(Type::INTEGER, HW::T_ENV_RADIANCE_MIPS, Value::createValue(1));
psPrivateUniforms->add(Type::INTEGER, HW::T_ENV_RADIANCE_SAMPLES, Value::createValue(16));
psPrivateUniforms->add(Type::FILENAME, HW::T_ENV_IRRADIANCE);
+ psPrivateUniforms->add(Type::BOOLEAN, HW::T_REFRACTION_ENV);
+ psPrivateUniforms->add(Type::COLOR3, HW::T_REFRACTION_COLOR);
}
// Add uniforms for the directional albedo table.
diff --git a/source/MaterialXGenShader/HwShaderGenerator.h b/source/MaterialXGenShader/HwShaderGenerator.h
index 17b09ef850..38068ab7a5 100644
--- a/source/MaterialXGenShader/HwShaderGenerator.h
+++ b/source/MaterialXGenShader/HwShaderGenerator.h
@@ -125,6 +125,8 @@ namespace HW
extern MX_GENSHADER_API const string T_ENV_RADIANCE_MIPS;
extern MX_GENSHADER_API const string T_ENV_RADIANCE_SAMPLES;
extern MX_GENSHADER_API const string T_ENV_IRRADIANCE;
+ extern MX_GENSHADER_API const string T_REFRACTION_ENV;
+ extern MX_GENSHADER_API const string T_REFRACTION_COLOR;
extern MX_GENSHADER_API const string T_ALBEDO_TABLE;
extern MX_GENSHADER_API const string T_ALBEDO_TABLE_SIZE;
extern MX_GENSHADER_API const string T_AMB_OCC_MAP;
@@ -179,6 +181,8 @@ namespace HW
extern MX_GENSHADER_API const string ENV_RADIANCE_MIPS;
extern MX_GENSHADER_API const string ENV_RADIANCE_SAMPLES;
extern MX_GENSHADER_API const string ENV_IRRADIANCE;
+ extern MX_GENSHADER_API const string REFRACTION_ENV;
+ extern MX_GENSHADER_API const string REFRACTION_COLOR;
extern MX_GENSHADER_API const string ALBEDO_TABLE;
extern MX_GENSHADER_API const string ALBEDO_TABLE_SIZE;
extern MX_GENSHADER_API const string AMB_OCC_MAP;
diff --git a/source/MaterialXGenShader/Util.cpp b/source/MaterialXGenShader/Util.cpp
index 069ddb148d..39b882039b 100644
--- a/source/MaterialXGenShader/Util.cpp
+++ b/source/MaterialXGenShader/Util.cpp
@@ -90,8 +90,7 @@ namespace
// Inputs on a surface shader which are checked for transparency
const OpaqueTestPairList inputPairList = { {"opacity", 1.0f},
- {"existence", 1.0f},
- {"transmission", 0.0f} };
+ {"existence", 1.0f} };
// Check against the interface if a node is passed in to check against
diff --git a/source/MaterialXGenShader/Util.h b/source/MaterialXGenShader/Util.h
index ef4763860f..0619302cf8 100644
--- a/source/MaterialXGenShader/Util.h
+++ b/source/MaterialXGenShader/Util.h
@@ -20,7 +20,7 @@ MATERIALX_NAMESPACE_BEGIN
class ShaderGenerator;
/// Returns true if the given element is a surface shader with the potential
-/// of beeing transparent. This can be used by HW shader generators to determine
+/// of being transparent. This can be used by HW shader generators to determine
/// if a shader will require transparency handling.
///
/// Note: This function will check some common cases for how a surface
diff --git a/source/MaterialXRender/LightHandler.h b/source/MaterialXRender/LightHandler.h
index 71036b13d8..79796aff78 100644
--- a/source/MaterialXRender/LightHandler.h
+++ b/source/MaterialXRender/LightHandler.h
@@ -37,7 +37,8 @@ class MX_RENDER_API LightHandler
_lightTransform(Matrix44::IDENTITY),
_directLighting(true),
_indirectLighting(true),
- _envSampleCount(DEFAULT_ENV_SAMPLE_COUNT)
+ _envSampleCount(DEFAULT_ENV_SAMPLE_COUNT),
+ _refractionEnv(true)
{
}
virtual ~LightHandler() { }
@@ -112,18 +113,6 @@ class MX_RENDER_API LightHandler
return _envIrradianceMap;
}
- /// Set the directional albedo table
- void setAlbedoTable(ImagePtr table)
- {
- _albedoTable = table;
- }
-
- /// Return the directional albedo table
- ImagePtr getAlbedoTable() const
- {
- return _albedoTable;
- }
-
/// Set the environment lighting sample count.
void setEnvSampleCount(int count)
{
@@ -136,6 +125,46 @@ class MX_RENDER_API LightHandler
return _envSampleCount;
}
+ /// Set environment visibility in refractions.
+ void setRefractionEnv(bool enable)
+ {
+ _refractionEnv = enable;
+ }
+
+ /// Return environment visibility in refractions.
+ int getRefractionEnv() const
+ {
+ return _refractionEnv;
+ }
+
+ /// Set the uniform refraction color.
+ void setRefractionColor(const Color3& color)
+ {
+ _refractionColor = color;
+ }
+
+ /// Return the uniform refraction color.
+ Color3 getRefractionColor() const
+ {
+ return _refractionColor;
+ }
+
+ /// @}
+ /// @name Albedo Table
+ /// @{
+
+ /// Set the directional albedo table
+ void setAlbedoTable(ImagePtr table)
+ {
+ _albedoTable = table;
+ }
+
+ /// Return the directional albedo table
+ ImagePtr getAlbedoTable() const
+ {
+ return _albedoTable;
+ }
+
/// @}
/// @name Light Sources
/// @{
@@ -202,9 +231,13 @@ class MX_RENDER_API LightHandler
ImagePtr _envRadianceMap;
ImagePtr _envIrradianceMap;
- ImagePtr _albedoTable;
int _envSampleCount;
+ bool _refractionEnv;
+ Color3 _refractionColor;
+
+ ImagePtr _albedoTable;
+
vector _lightSources;
std::unordered_map _lightIdMap;
};
diff --git a/source/MaterialXRenderGlsl/GlslProgram.cpp b/source/MaterialXRenderGlsl/GlslProgram.cpp
index e2e7b00ea0..615974d964 100644
--- a/source/MaterialXRenderGlsl/GlslProgram.cpp
+++ b/source/MaterialXRenderGlsl/GlslProgram.cpp
@@ -600,6 +600,8 @@ void GlslProgram::bindLighting(LightHandlerPtr lightHandler, ImageHandlerPtr ima
}
}
}
+ bindUniform(HW::REFRACTION_ENV, Value::createValue(lightHandler->getRefractionEnv()), false);
+ bindUniform(HW::REFRACTION_COLOR, Value::createValue(lightHandler->getRefractionColor()), false);
// Bind direct lighting properties.
if (hasUniform(HW::NUM_ACTIVE_LIGHT_SOURCES))
diff --git a/source/MaterialXRenderGlsl/GlslRenderer.cpp b/source/MaterialXRenderGlsl/GlslRenderer.cpp
index c8e88cbebd..053d410951 100644
--- a/source/MaterialXRenderGlsl/GlslRenderer.cpp
+++ b/source/MaterialXRenderGlsl/GlslRenderer.cpp
@@ -324,9 +324,4 @@ void GlslRenderer::drawScreenSpaceQuad(const Vector2& uvMin, const Vector2& uvMa
checkGlErrors("after draw screen-space quad");
}
-void GlslRenderer::setScreenColor(const Color3& screenColor)
-{
- _screenColor = screenColor;
-}
-
MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXRenderGlsl/GlslRenderer.h b/source/MaterialXRenderGlsl/GlslRenderer.h
index e7e81cdf8b..ac632ec133 100644
--- a/source/MaterialXRenderGlsl/GlslRenderer.h
+++ b/source/MaterialXRenderGlsl/GlslRenderer.h
@@ -103,7 +103,16 @@ class MX_RENDERGLSL_API GlslRenderer : public ShaderRenderer
void drawScreenSpaceQuad(const Vector2& uvMin = Vector2(0.0f), const Vector2& uvMax = Vector2(1.0f));
/// Set the screen background color.
- void setScreenColor(const Color3& screenColor);
+ void setScreenColor(const Color3& screenColor)
+ {
+ _screenColor = screenColor;
+ }
+
+ /// Return the screen background color.
+ Color3 getScreenColor() const
+ {
+ return _screenColor;
+ }
/// @}
diff --git a/source/MaterialXTest/MaterialXGenShader/GenShader.cpp b/source/MaterialXTest/MaterialXGenShader/GenShader.cpp
index b855622d34..78839c47f7 100644
--- a/source/MaterialXTest/MaterialXGenShader/GenShader.cpp
+++ b/source/MaterialXTest/MaterialXGenShader/GenShader.cpp
@@ -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 transparencyTest = { false, true, true, true, true };
+ std::vector transparencyTest = { false, false, true, true, true };
for (size_t i=0; igetImageHandler()->acquireImage(options.irradianceIBLPath);
REQUIRE(envRadiance);
REQUIRE(envIrradiance);
+
+ // Apply light settings for render tests.
_lightHandler->setEnvRadianceMap(envRadiance);
_lightHandler->setEnvIrradianceMap(envIrradiance);
_lightHandler->setEnvSampleCount(1024);
+ _lightHandler->setRefractionEnv(false);
+ _lightHandler->setRefractionColor(_renderer->getScreenColor());
}
//