From 3acd5fac9e579927cdcad480ac48367419d99fa0 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 20 Apr 2022 10:40:05 -0700 Subject: [PATCH 1/3] Initial refraction approximation in GLSL This changelist introduces a rough approximation of refraction in GLSL, allowing transmissive materials such as glass to respond visually to changes in specular_IOR, specular_roughness, and transmission_color. Because this initial approximation is limited to a single render pass, only the environment radiance map is currently visible in refractions, and opaque objects behind transmissive surfaces are not yet visible. --- javascript/MaterialXView/source/viewer.js | 3 +- .../genglsl/lib/mx_environment_fis.glsl | 7 +- .../genglsl/lib/mx_microfacet_specular.glsl | 20 ++++- .../pbrlib/genglsl/mx_dielectric_bsdf.glsl | 30 +++++--- .../genglsl/mx_generalized_schlick_bsdf.glsl | 19 ++--- .../standard_surface_glass_tinted.mtlx | 15 ++++ .../TestSuite/pbrlib/bsdf/dielectric.mtlx | 73 +------------------ .../pbrlib/bsdf/generalized_schlick.mtlx | 71 +++++++++++++++--- .../transparency_nodedef_test.mtlx | 25 ------- .../surfaceshader/transparency_test.mtlx | 16 ---- .../Nodes/SurfaceNodeGlsl.cpp | 26 ++++--- .../Nodes/UnlitSurfaceNodeGlsl.cpp | 4 - .../MaterialXGenShader/HwShaderGenerator.cpp | 8 ++ source/MaterialXGenShader/HwShaderGenerator.h | 4 + source/MaterialXGenShader/Util.cpp | 3 +- source/MaterialXGenShader/Util.h | 2 +- source/MaterialXRender/LightHandler.h | 61 ++++++++++++---- source/MaterialXRenderGlsl/GlslProgram.cpp | 2 + source/MaterialXRenderGlsl/GlslRenderer.cpp | 5 -- source/MaterialXRenderGlsl/GlslRenderer.h | 11 ++- .../MaterialXGenShader/GenShader.cpp | 2 +- .../MaterialXRenderGlsl/RenderGlsl.cpp | 4 + 22 files changed, 224 insertions(+), 187 deletions(-) create mode 100644 resources/Materials/Examples/StandardSurface/standard_surface_glass_tinted.mtlx 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..49940e6a65 100644 --- a/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx +++ b/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx @@ -5,49 +5,44 @@ - - + - - + - - + - - @@ -57,66 +52,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx index b4e51053b6..79f07ef680 100644 --- a/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx +++ b/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx @@ -1,20 +1,67 @@ - - - - - - - - + + + + + + - + - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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().srgbToLinear()); } // From 4f67b551dfda0f45e855bc3a31735705932d843d Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 20 Apr 2022 19:15:37 -0700 Subject: [PATCH 2/3] Fix colorspace of unit test refraction --- source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp b/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp index a0a95569dc..f57b1cb8b8 100644 --- a/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp +++ b/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp @@ -103,7 +103,7 @@ void GlslShaderRenderTester::registerLights(mx::DocumentPtr document, _lightHandler->setEnvIrradianceMap(envIrradiance); _lightHandler->setEnvSampleCount(1024); _lightHandler->setRefractionEnv(false); - _lightHandler->setRefractionColor(_renderer->getScreenColor().srgbToLinear()); + _lightHandler->setRefractionColor(_renderer->getScreenColor()); } // From 8486ede0d10f9efba0c52c4e94fec69d833e2dec Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Fri, 22 Apr 2022 16:53:23 -0700 Subject: [PATCH 3/3] Simplify unit tests --- .../TestSuite/pbrlib/bsdf/dielectric.mtlx | 58 +++++++---------- .../pbrlib/bsdf/generalized_schlick.mtlx | 62 +++++++------------ 2 files changed, 44 insertions(+), 76 deletions(-) diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx index 49940e6a65..6f6c3f03aa 100644 --- a/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx +++ b/resources/Materials/TestSuite/pbrlib/bsdf/dielectric.mtlx @@ -1,57 +1,43 @@ - - - + + - - + + - - - - + + + - - + + - - - - + + + - - + + - - - - - - - - - - - - - - - - + + + + + - - + + - + diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx index 79f07ef680..52a00023f7 100644 --- a/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx +++ b/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx @@ -1,67 +1,49 @@ - - - + + - - + + - - - - + + + - - + + - - - - + + + - - + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + - +