From bedc293cd5feda33bb307444209c30756ebb1eef Mon Sep 17 00:00:00 2001 From: Nicolas Savva Date: Tue, 16 May 2023 09:36:20 -0700 Subject: [PATCH 1/3] Add blackbody PBR node implementations. Fix blackbody node MaterialXGen tests. --- libraries/pbrlib/genglsl/mx_blackbody.glsl | 49 +++++++++++++++++++ .../pbrlib/genglsl/pbrlib_genglsl_impl.mtlx | 3 ++ .../pbrlib/genmsl/pbrlib_genmsl_impl.mtlx | 3 ++ libraries/pbrlib/genosl/mx_blackbody.osl | 49 +++++++++++++++++++ .../pbrlib/genosl/pbrlib_genosl_impl.legacy | 3 ++ .../pbrlib/genosl/pbrlib_genosl_impl.mtlx | 3 ++ .../standard_surface_blackbody.mtlx | 23 +++++++++ .../MaterialXGenGlsl/GenGlsl.cpp | 2 +- .../MaterialXTest/MaterialXGenMdl/GenMdl.cpp | 2 +- .../MaterialXTest/MaterialXGenMsl/GenMsl.cpp | 2 +- .../MaterialXTest/MaterialXGenOsl/GenOsl.cpp | 2 +- .../MaterialXGenShader/GenShaderUtil.cpp | 1 - source/MaterialXView/Editor.cpp | 2 +- 13 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 libraries/pbrlib/genglsl/mx_blackbody.glsl create mode 100644 libraries/pbrlib/genosl/mx_blackbody.osl create mode 100644 resources/Materials/Examples/StandardSurface/standard_surface_blackbody.mtlx diff --git a/libraries/pbrlib/genglsl/mx_blackbody.glsl b/libraries/pbrlib/genglsl/mx_blackbody.glsl new file mode 100644 index 0000000000..affde5aa1f --- /dev/null +++ b/libraries/pbrlib/genglsl/mx_blackbody.glsl @@ -0,0 +1,49 @@ +/// XYZ to Rec.709 RGB colorspace conversion +const mat3 XYZ_to_RGB = mat3( 3.2406, -0.9689, 0.0557, + -1.5372, 1.8758, -0.2040, + -0.4986, 0.0415, 1.0570); + +void mx_blackbody(float temperatureKelvin, out vec3 colorValue) +{ + float xc, yc; + float t, t2, t3, xc2, xc3; + + t = 1000.0 / temperatureKelvin; + t2 = t * t; + t3 = t * t * t; + + // if value outside valid range of approximation clamp to accepted temperature range + clamp(temperatureKelvin, 1667.0, 25000.0); + + + // Cubic spline approximation for Kelvin temperature to sRGB conversion + // (https://en.wikipedia.org/wiki/Planckian_locus#Approximation) + if (temperatureKelvin < 4000.0) { // 1667K <= temperatureKelvin < 4000K + xc = -0.2661239 * t3 - 0.2343580 * t2 + 0.8776956 * t + 0.179910; + } + else { // 4000K <= temperatureKelvin <= 25000K + xc = -3.0258469 * t3 + 2.1070379 * t2 + 0.2226347 * t + 0.240390; + } + xc2 = xc * xc; + xc3 = xc * xc * xc; + + if (temperatureKelvin < 2222.0) { // 1667K <= temperatureKelvin < 2222K + yc = -1.1063814 * xc3 - 1.34811020 * xc2 + 2.18555832 * xc - 0.20219683; + } + else if (temperatureKelvin < 4000.0) { // 2222K <= temperatureKelvin < 4000K + yc = -0.9549476 * xc3 - 1.37418593 * xc2 + 2.09137015 * xc - 0.16748867; + } + else { // 4000K <= temperatureKelvin <= 25000K + yc = 3.0817580 * xc3 - 5.87338670 * xc2 + 3.75112997 * xc - 0.37001483; + } + + if (yc <= 0.0) { // avoid division by zero + colorValue = vec3(1.0); + return; + } + + vec3 XYZ = vec3(xc / yc, 1.0, (1.0 - xc - yc) / yc); + + colorValue = XYZ_to_RGB * XYZ; + colorValue = max(colorValue, vec3(0.0)); +} diff --git a/libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx b/libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx index b94f513d82..fa4617375f 100644 --- a/libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx +++ b/libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx @@ -74,4 +74,7 @@ + + + diff --git a/libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx b/libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx index 1900f1e824..8d1d2a4729 100644 --- a/libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx +++ b/libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx @@ -71,4 +71,7 @@ + + + diff --git a/libraries/pbrlib/genosl/mx_blackbody.osl b/libraries/pbrlib/genosl/mx_blackbody.osl new file mode 100644 index 0000000000..3fa1025d9d --- /dev/null +++ b/libraries/pbrlib/genosl/mx_blackbody.osl @@ -0,0 +1,49 @@ +void mx_blackbody(float temperature, output color color_value) +{ + float xc, yc; + float t, t2, t3, xc2, xc3; + + t = 1000.0 / temperature; + t2 = t * t; + t3 = t * t * t; + + // if value outside valid range of approximation clamp to accepted temperature range + clamp(temperature, 1667.0, 25000.0); + + + // Cubic spline approximation for Kelvin temperature to sRGB conversion + // (https://en.wikipedia.org/wiki/Planckian_locus#Approximation) + if (temperature < 4000.0) { // 1667K <= temperature < 4000K + xc = -0.2661239 * t3 - 0.2343580 * t2 + 0.8776956 * t + 0.179910; + } + else { // 4000K <= temperature <= 25000K + xc = -3.0258469 * t3 + 2.1070379 * t2 + 0.2226347 * t + 0.240390; + } + xc2 = xc * xc; + xc3 = xc * xc * xc; + + if (temperature < 2222.0) { // 1667K <= temperature < 2222K + yc = -1.1063814 * xc3 - 1.34811020 * xc2 + 2.18555832 * xc - 0.20219683; + } + else if (temperature < 4000.0) { // 2222K <= temperature < 4000K + yc = -0.9549476 * xc3 - 1.37418593 * xc2 + 2.09137015 * xc - 0.16748867; + } + else { // 4000K <= temperature <= 25000K + yc = 3.0817580 * xc3 - 5.87338670 * xc2 + 3.75112997 * xc - 0.37001483; + } + + if (yc <= 0.0) { // avoid division by zero + color_value = color(1.0); + return; + } + + vector XYZ = vector(xc / yc, 1.0, (1 - xc - yc) / yc); + + /// XYZ to Rec.709 RGB colorspace conversion + matrix XYZ_to_RGB = matrix( 3.2406, -0.9689, 0.0557, + -1.5372, 1.8758, -0.2040, + -0.4986, 0.0415, 1.0570); + + color_value = transform(XYZ_to_RGB, XYZ); + color_value = max(color_value, vector(0.0)); +} diff --git a/libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy b/libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy index d7ccf80906..6ab7cc9e61 100644 --- a/libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy +++ b/libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy @@ -71,4 +71,7 @@ + + + diff --git a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx index b37dc79fcd..7a38f0fb12 100644 --- a/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx +++ b/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx @@ -71,4 +71,7 @@ + + + diff --git a/resources/Materials/Examples/StandardSurface/standard_surface_blackbody.mtlx b/resources/Materials/Examples/StandardSurface/standard_surface_blackbody.mtlx new file mode 100644 index 0000000000..761ba57239 --- /dev/null +++ b/resources/Materials/Examples/StandardSurface/standard_surface_blackbody.mtlx @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp b/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp index a357651cb7..5039ea2f9e 100644 --- a/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp +++ b/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp @@ -85,7 +85,7 @@ TEST_CASE("GenShader: GLSL Implementation Check", "[genglsl]") mx::StringSet generatorSkipNodeTypes; mx::StringSet generatorSkipNodeDefs; - GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 48); + GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 47); } TEST_CASE("GenShader: GLSL Unique Names", "[genglsl]") diff --git a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp index c58d754b92..7ffad31552 100644 --- a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp +++ b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp @@ -93,7 +93,7 @@ TEST_CASE("GenShader: MDL Implementation Check", "[genmdl]") generatorSkipNodeTypes.insert("light"); mx::StringSet generatorSkipNodeDefs; - GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 49); + GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 48); } diff --git a/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp b/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp index 8393acfca7..9b618ae1aa 100644 --- a/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp +++ b/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp @@ -84,7 +84,7 @@ TEST_CASE("GenShader: MSL Implementation Check", "[genmsl]") mx::StringSet generatorSkipNodeTypes; mx::StringSet generatorSkipNodeDefs; - GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 48); + GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 47); } TEST_CASE("GenShader: MSL Unique Names", "[genmsl]") diff --git a/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp b/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp index b6e71732b6..8befd2ade8 100644 --- a/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp +++ b/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp @@ -89,7 +89,7 @@ TEST_CASE("GenShader: OSL Implementation Check", "[genosl]") generatorSkipNodeTypes.insert("light"); mx::StringSet generatorSkipNodeDefs; - GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 49); + GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 48); } TEST_CASE("GenShader: OSL Unique Names", "[genosl]") diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index 2db73f3bb6..e8331c8cc9 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -94,7 +94,6 @@ void checkImplementations(mx::GenContext& context, "arrayappend", "displacement", "volume", - "blackbody", "curveadjust", "conical_edf", "measured_edf", diff --git a/source/MaterialXView/Editor.cpp b/source/MaterialXView/Editor.cpp index a4c6d3f675..ff91f0f129 100644 --- a/source/MaterialXView/Editor.cpp +++ b/source/MaterialXView/Editor.cpp @@ -701,7 +701,7 @@ ng::FloatBox* createFloatWidget(ng::Widget* parent, const std::string& la if (ui) { - std::pair range(0.0f, 0.0f); + std::pair range(0.0f, 1.0f); if (ui->uiMin) { box->set_min_value(ui->uiMin->asA()); From 0cd998e1a9eda08659ebc55e65b6da9df03ce549 Mon Sep 17 00:00:00 2001 From: Nicolas Savva Date: Wed, 31 May 2023 15:11:05 -0700 Subject: [PATCH 2/3] Fix blackbody node clamping. --- libraries/pbrlib/genglsl/mx_blackbody.glsl | 7 +++---- libraries/pbrlib/genosl/mx_blackbody.osl | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/libraries/pbrlib/genglsl/mx_blackbody.glsl b/libraries/pbrlib/genglsl/mx_blackbody.glsl index affde5aa1f..55d5c87541 100644 --- a/libraries/pbrlib/genglsl/mx_blackbody.glsl +++ b/libraries/pbrlib/genglsl/mx_blackbody.glsl @@ -8,14 +8,13 @@ void mx_blackbody(float temperatureKelvin, out vec3 colorValue) float xc, yc; float t, t2, t3, xc2, xc3; + // if value outside valid range of approximation clamp to accepted temperature range + temperatureKelvin = clamp(temperatureKelvin, 1667.0, 25000.0); + t = 1000.0 / temperatureKelvin; t2 = t * t; t3 = t * t * t; - // if value outside valid range of approximation clamp to accepted temperature range - clamp(temperatureKelvin, 1667.0, 25000.0); - - // Cubic spline approximation for Kelvin temperature to sRGB conversion // (https://en.wikipedia.org/wiki/Planckian_locus#Approximation) if (temperatureKelvin < 4000.0) { // 1667K <= temperatureKelvin < 4000K diff --git a/libraries/pbrlib/genosl/mx_blackbody.osl b/libraries/pbrlib/genosl/mx_blackbody.osl index 3fa1025d9d..8b4de5ba9f 100644 --- a/libraries/pbrlib/genosl/mx_blackbody.osl +++ b/libraries/pbrlib/genosl/mx_blackbody.osl @@ -3,14 +3,13 @@ void mx_blackbody(float temperature, output color color_value) float xc, yc; float t, t2, t3, xc2, xc3; + // if value outside valid range of approximation clamp to accepted temperature range + temperature = clamp(temperature, 1667.0, 25000.0); + t = 1000.0 / temperature; t2 = t * t; t3 = t * t * t; - // if value outside valid range of approximation clamp to accepted temperature range - clamp(temperature, 1667.0, 25000.0); - - // Cubic spline approximation for Kelvin temperature to sRGB conversion // (https://en.wikipedia.org/wiki/Planckian_locus#Approximation) if (temperature < 4000.0) { // 1667K <= temperature < 4000K From 831642c9f177bef148d6247396cd812363eafd26 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 12 Jul 2023 10:00:51 -0700 Subject: [PATCH 3/3] Move example to test suite --- .../standard_surface_blackbody.mtlx | 23 ------------------- .../TestSuite/pbrlib/bsdf/blackbody.mtlx | 16 +++++++++++++ 2 files changed, 16 insertions(+), 23 deletions(-) delete mode 100644 resources/Materials/Examples/StandardSurface/standard_surface_blackbody.mtlx create mode 100644 resources/Materials/TestSuite/pbrlib/bsdf/blackbody.mtlx diff --git a/resources/Materials/Examples/StandardSurface/standard_surface_blackbody.mtlx b/resources/Materials/Examples/StandardSurface/standard_surface_blackbody.mtlx deleted file mode 100644 index 761ba57239..0000000000 --- a/resources/Materials/Examples/StandardSurface/standard_surface_blackbody.mtlx +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/blackbody.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/blackbody.mtlx new file mode 100644 index 0000000000..f2d9b193f3 --- /dev/null +++ b/resources/Materials/TestSuite/pbrlib/bsdf/blackbody.mtlx @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + +