Skip to content

Commit bedc293

Browse files
Add blackbody PBR node implementations.
Fix blackbody node MaterialXGen tests.
1 parent d11219c commit bedc293

13 files changed

Lines changed: 138 additions & 6 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/// XYZ to Rec.709 RGB colorspace conversion
2+
const mat3 XYZ_to_RGB = mat3( 3.2406, -0.9689, 0.0557,
3+
-1.5372, 1.8758, -0.2040,
4+
-0.4986, 0.0415, 1.0570);
5+
6+
void mx_blackbody(float temperatureKelvin, out vec3 colorValue)
7+
{
8+
float xc, yc;
9+
float t, t2, t3, xc2, xc3;
10+
11+
t = 1000.0 / temperatureKelvin;
12+
t2 = t * t;
13+
t3 = t * t * t;
14+
15+
// if value outside valid range of approximation clamp to accepted temperature range
16+
clamp(temperatureKelvin, 1667.0, 25000.0);
17+
18+
19+
// Cubic spline approximation for Kelvin temperature to sRGB conversion
20+
// (https://en.wikipedia.org/wiki/Planckian_locus#Approximation)
21+
if (temperatureKelvin < 4000.0) { // 1667K <= temperatureKelvin < 4000K
22+
xc = -0.2661239 * t3 - 0.2343580 * t2 + 0.8776956 * t + 0.179910;
23+
}
24+
else { // 4000K <= temperatureKelvin <= 25000K
25+
xc = -3.0258469 * t3 + 2.1070379 * t2 + 0.2226347 * t + 0.240390;
26+
}
27+
xc2 = xc * xc;
28+
xc3 = xc * xc * xc;
29+
30+
if (temperatureKelvin < 2222.0) { // 1667K <= temperatureKelvin < 2222K
31+
yc = -1.1063814 * xc3 - 1.34811020 * xc2 + 2.18555832 * xc - 0.20219683;
32+
}
33+
else if (temperatureKelvin < 4000.0) { // 2222K <= temperatureKelvin < 4000K
34+
yc = -0.9549476 * xc3 - 1.37418593 * xc2 + 2.09137015 * xc - 0.16748867;
35+
}
36+
else { // 4000K <= temperatureKelvin <= 25000K
37+
yc = 3.0817580 * xc3 - 5.87338670 * xc2 + 3.75112997 * xc - 0.37001483;
38+
}
39+
40+
if (yc <= 0.0) { // avoid division by zero
41+
colorValue = vec3(1.0);
42+
return;
43+
}
44+
45+
vec3 XYZ = vec3(xc / yc, 1.0, (1.0 - xc - yc) / yc);
46+
47+
colorValue = XYZ_to_RGB * XYZ;
48+
colorValue = max(colorValue, vec3(0.0));
49+
}

libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,7 @@
7474
<!-- <artistic_ior> -->
7575
<implementation name="IM_artistic_ior_genglsl" nodedef="ND_artistic_ior" file="mx_artistic_ior.glsl" function="mx_artistic_ior" target="genglsl" />
7676

77+
<!-- <blackbody> -->
78+
<implementation name="IM_blackbody_genglsl" nodedef="ND_blackbody" file="mx_blackbody.glsl" function="mx_blackbody" target="genglsl" />
79+
7780
</materialx>

libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,7 @@
7171
<!-- <artistic_ior> -->
7272
<implementation name="IM_artistic_ior_genmsl" nodedef="ND_artistic_ior" file="../genglsl/mx_artistic_ior.glsl" function="mx_artistic_ior" target="genmsl" />
7373

74+
<!-- <blackbody> -->
75+
<implementation name="IM_blackbody_genmsl" nodedef="ND_blackbody" file="../genglsl/mx_blackbody.glsl" function="mx_blackbody" target="genmsl" />
76+
7477
</materialx>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
void mx_blackbody(float temperature, output color color_value)
2+
{
3+
float xc, yc;
4+
float t, t2, t3, xc2, xc3;
5+
6+
t = 1000.0 / temperature;
7+
t2 = t * t;
8+
t3 = t * t * t;
9+
10+
// if value outside valid range of approximation clamp to accepted temperature range
11+
clamp(temperature, 1667.0, 25000.0);
12+
13+
14+
// Cubic spline approximation for Kelvin temperature to sRGB conversion
15+
// (https://en.wikipedia.org/wiki/Planckian_locus#Approximation)
16+
if (temperature < 4000.0) { // 1667K <= temperature < 4000K
17+
xc = -0.2661239 * t3 - 0.2343580 * t2 + 0.8776956 * t + 0.179910;
18+
}
19+
else { // 4000K <= temperature <= 25000K
20+
xc = -3.0258469 * t3 + 2.1070379 * t2 + 0.2226347 * t + 0.240390;
21+
}
22+
xc2 = xc * xc;
23+
xc3 = xc * xc * xc;
24+
25+
if (temperature < 2222.0) { // 1667K <= temperature < 2222K
26+
yc = -1.1063814 * xc3 - 1.34811020 * xc2 + 2.18555832 * xc - 0.20219683;
27+
}
28+
else if (temperature < 4000.0) { // 2222K <= temperature < 4000K
29+
yc = -0.9549476 * xc3 - 1.37418593 * xc2 + 2.09137015 * xc - 0.16748867;
30+
}
31+
else { // 4000K <= temperature <= 25000K
32+
yc = 3.0817580 * xc3 - 5.87338670 * xc2 + 3.75112997 * xc - 0.37001483;
33+
}
34+
35+
if (yc <= 0.0) { // avoid division by zero
36+
color_value = color(1.0);
37+
return;
38+
}
39+
40+
vector XYZ = vector(xc / yc, 1.0, (1 - xc - yc) / yc);
41+
42+
/// XYZ to Rec.709 RGB colorspace conversion
43+
matrix XYZ_to_RGB = matrix( 3.2406, -0.9689, 0.0557,
44+
-1.5372, 1.8758, -0.2040,
45+
-0.4986, 0.0415, 1.0570);
46+
47+
color_value = transform(XYZ_to_RGB, XYZ);
48+
color_value = max(color_value, vector(0.0));
49+
}

libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,7 @@
7171
<!-- <artistic_ior> -->
7272
<implementation name="IM_artistic_ior_genosl" nodedef="ND_artistic_ior" file="mx_artistic_ior.osl" function="mx_artistic_ior" target="genosl" />
7373

74+
<!-- <blackbody> -->
75+
<implementation name="IM_blackbody_genosl" nodedef="ND_blackbody" file="mx_blackbody.osl" function="mx_blackbody" target="genosl" />
76+
7477
</materialx>

libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,7 @@
7171
<!-- <artistic_ior> -->
7272
<implementation name="IM_artistic_ior_genosl" nodedef="ND_artistic_ior" file="mx_artistic_ior.osl" function="mx_artistic_ior" target="genosl" />
7373

74+
<!-- <blackbody> -->
75+
<implementation name="IM_blackbody_genosl" nodedef="ND_blackbody" file="mx_blackbody.osl" function="mx_blackbody" target="genosl" />
76+
7477
</materialx>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0"?>
2+
<materialx version="1.38" colorspace="lin_rec709">
3+
<nodegraph name="NG_blackbody">
4+
<input name="blackbody_temperature" type="float" value="5000.0" uimin="1500.0" uimax="25000.0" uistep="100.0" uiname="Blackbody Temperature Kelvin" />
5+
<blackbody name="blackbody_color_out" type="color3">
6+
<input name="temperature" type="float" interfacename="blackbody_temperature" uivisible="true"/>
7+
</blackbody>
8+
<output name="emission_color_output" type="color3" nodename="blackbody_color_out" />
9+
</nodegraph>
10+
<standard_surface name="SR_blackbody" type="surfaceshader">
11+
<input name="base" type="float" value="0.0" />
12+
<input name="base_color" type="color3" value="1.0, 1.0, 1.0" />
13+
<input name="specular" type="float" value="0.0" />
14+
<input name="specular_color" type="color3" value="1.0, 1.0, 1.0" />
15+
<input name="specular_roughness" type="float" value="0" />
16+
<input name="metalness" type="float" value="1" />
17+
<input name="emission" type="float" value="1" />
18+
<input name="emission_color" type="color3" nodegraph="NG_blackbody" output="emission_color_output" />
19+
</standard_surface>
20+
<surfacematerial name="Blackbody" type="material">
21+
<input name="surfaceshader" type="surfaceshader" nodename="SR_blackbody" />
22+
</surfacematerial>
23+
</materialx>

source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ TEST_CASE("GenShader: GLSL Implementation Check", "[genglsl]")
8585

8686
mx::StringSet generatorSkipNodeTypes;
8787
mx::StringSet generatorSkipNodeDefs;
88-
GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 48);
88+
GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 47);
8989
}
9090

9191
TEST_CASE("GenShader: GLSL Unique Names", "[genglsl]")

source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ TEST_CASE("GenShader: MDL Implementation Check", "[genmdl]")
9393
generatorSkipNodeTypes.insert("light");
9494
mx::StringSet generatorSkipNodeDefs;
9595

96-
GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 49);
96+
GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 48);
9797
}
9898

9999

source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ TEST_CASE("GenShader: MSL Implementation Check", "[genmsl]")
8484

8585
mx::StringSet generatorSkipNodeTypes;
8686
mx::StringSet generatorSkipNodeDefs;
87-
GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 48);
87+
GenShaderUtil::checkImplementations(context, generatorSkipNodeTypes, generatorSkipNodeDefs, 47);
8888
}
8989

9090
TEST_CASE("GenShader: MSL Unique Names", "[genmsl]")

0 commit comments

Comments
 (0)