Skip to content

Commit

Permalink
Merge remote-tracking branch 'aswf/dev_1.39' into simplify_thin_film
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasharrysson committed Jul 16, 2023
2 parents 83343eb + 426389c commit e07012f
Show file tree
Hide file tree
Showing 20 changed files with 227 additions and 34 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# MaterialX Version
set(MATERIALX_MAJOR_VERSION 1)
set(MATERIALX_MINOR_VERSION 39)
set(MATERIALX_BUILD_VERSION 1)
set(MATERIALX_BUILD_VERSION 0)
set(MATERIALX_LIBRARY_VERSION ${MATERIALX_MAJOR_VERSION}.${MATERIALX_MINOR_VERSION}.${MATERIALX_BUILD_VERSION})

# Cmake setup
Expand Down
48 changes: 48 additions & 0 deletions libraries/pbrlib/genglsl/mx_blackbody.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/// 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;

// 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;

// 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));
}
3 changes: 3 additions & 0 deletions libraries/pbrlib/genglsl/pbrlib_genglsl_impl.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,7 @@
<!-- <artistic_ior> -->
<implementation name="IM_artistic_ior_genglsl" nodedef="ND_artistic_ior" file="mx_artistic_ior.glsl" function="mx_artistic_ior" target="genglsl" />

<!-- <blackbody> -->
<implementation name="IM_blackbody_genglsl" nodedef="ND_blackbody" file="mx_blackbody.glsl" function="mx_blackbody" target="genglsl" />

</materialx>
3 changes: 3 additions & 0 deletions libraries/pbrlib/genmsl/pbrlib_genmsl_impl.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,7 @@
<!-- <artistic_ior> -->
<implementation name="IM_artistic_ior_genmsl" nodedef="ND_artistic_ior" file="../genglsl/mx_artistic_ior.glsl" function="mx_artistic_ior" target="genmsl" />

<!-- <blackbody> -->
<implementation name="IM_blackbody_genmsl" nodedef="ND_blackbody" file="../genglsl/mx_blackbody.glsl" function="mx_blackbody" target="genmsl" />

</materialx>
48 changes: 48 additions & 0 deletions libraries/pbrlib/genosl/mx_blackbody.osl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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;

// 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));
}
3 changes: 3 additions & 0 deletions libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,7 @@
<!-- <artistic_ior> -->
<implementation name="IM_artistic_ior_genosl" nodedef="ND_artistic_ior" file="mx_artistic_ior.osl" function="mx_artistic_ior" target="genosl" />

<!-- <blackbody> -->
<implementation name="IM_blackbody_genosl" nodedef="ND_blackbody" file="mx_blackbody.osl" function="mx_blackbody" target="genosl" />

</materialx>
3 changes: 3 additions & 0 deletions libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,7 @@
<!-- <artistic_ior> -->
<implementation name="IM_artistic_ior_genosl" nodedef="ND_artistic_ior" file="mx_artistic_ior.osl" function="mx_artistic_ior" target="genosl" />

<!-- <blackbody> -->
<implementation name="IM_blackbody_genosl" nodedef="ND_blackbody" file="mx_blackbody.osl" function="mx_blackbody" target="genosl" />

</materialx>
10 changes: 10 additions & 0 deletions libraries/stdlib/stdlib_defs.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -2546,6 +2546,16 @@
<output name="out" type="stringarray" defaultinput="in1" />
</nodedef>

<!--
Node: <trianglewave>
Generate a triangle wave from the given scalar input.
The generated wave ranges from zero to one and repeats on integer boundaries.
-->
<nodedef name="ND_trianglewave_float" node="trianglewave" nodegroup="math">
<input name="in" type="float" value="0" />
<output name="out" type="float" />
</nodedef>

<!-- ======================================================================== -->
<!-- Adjustment nodes -->
<!-- ======================================================================== -->
Expand Down
26 changes: 26 additions & 0 deletions libraries/stdlib/stdlib_ng.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,32 @@
</magnitude>
<output name="out" type="float" nodename="N_mtlxmagnitude" />
</nodegraph>

<!--
Node: <trianglewave>
Generate a triangle wave from the given scalar input.
The generated wave ranges from zero to one and repeats on integer boundaries.
-->
<nodegraph name="NG_trianglewave_float" nodedef="ND_trianglewave_float">
<absval name="absval1" type="float">
<input name="in" type="float" interfacename="in" />
</absval>
<modulo name="modulo1" type="float">
<input name="in1" type="float" nodename="absval1" />
</modulo>
<subtract name="subtract1" type="float">
<input name="in1" type="float" nodename="modulo1" />
<input name="in2" type="float" value="0.5" />
</subtract>
<absval name="absval2" type="float">
<input name="in" type="float" nodename="subtract1" />
</absval>
<subtract name="subtract2" type="float">
<input name="in1" type="float" value="0.5" />
<input name="in2" type="float" nodename="absval2" />
</subtract>
<output name="out" type="float" nodename="subtract2" />
</nodegraph>

<!-- ======================================================================== -->
<!-- Adjustment nodes -->
Expand Down
16 changes: 16 additions & 0 deletions resources/Materials/TestSuite/pbrlib/bsdf/blackbody.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<materialx version="1.38" colorspace="lin_rec709">
<nodegraph name="NG_blackbody">
<input name="blackbody_temperature" type="float" value="5000.0" uimin="1500.0" uimax="25000.0" uistep="100.0" uiname="Blackbody Temperature Kelvin" />
<blackbody name="blackbody_color_out" type="color3">
<input name="temperature" type="float" interfacename="blackbody_temperature" />
</blackbody>
<output name="emission_color_output" type="color3" nodename="blackbody_color_out" />
</nodegraph>
<surface_unlit name="SR_blackbody" type="surfaceshader">
<input name="emission_color" type="color3" nodegraph="NG_blackbody" output="emission_color_output" />
</surface_unlit>
<surfacematerial name="Blackbody" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="SR_blackbody" />
</surfacematerial>
</materialx>
4 changes: 2 additions & 2 deletions source/MaterialXCore/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ void Document::upgradeVersion()
}

// Upgrade from 1.37 to 1.38
if (majorVersion == 1 && minorVersion >= 37)
if (majorVersion == 1 && minorVersion == 37)
{
// Convert color2 types to vector2
const StringMap COLOR2_CHANNEL_MAP = { { "r", "x" }, { "a", "y" } };
Expand Down Expand Up @@ -1432,7 +1432,7 @@ void Document::upgradeVersion()
}

// Upgrade from 1.38 to 1.39
if (majorVersion == 1 && minorVersion >= 38)
if (majorVersion == 1 && minorVersion == 38)
{
const StringSet BSDF_WITH_THINFILM = { "dielectric_bsdf", "conductor_bsdf", "generalized_schlick_bsdf" };
const string LAYER = "layer";
Expand Down
79 changes: 56 additions & 23 deletions source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl
Original file line number Diff line number Diff line change
Expand Up @@ -649,14 +649,39 @@ export material mx_displacement_vector3(
);


// helper function to mix two scattering volumes:
// - combined scattering coefficient is just the sum of the two
// - VDF mixer weight is the relative probability of encountering the corresponding
// particle type
// NOTE: mixer weight should be a color, but due to a bug in current MDL compilers
// the color mixers don't accept non-uniform weights yet
struct volume_mix_return {
color scattering_coefficient;
float mix_weight1; // mix_weight2 = 1.0 - mix_weight1, can use any mixer
};
volume_mix_return volume_mix(
color scattering_coefficient1,
float weight1,
color scattering_coefficient2,
float weight2)
{
color s1 = weight1 * scattering_coefficient1;
color s = s1 + weight2 * scattering_coefficient2;
return volume_mix_return(scattering_coefficient: s, mix_weight1: math::average(s1 / s));
}

export material mx_mix_bsdf(
material mxp_fg = material() [[ anno::usage( "materialx:bsdf") ]],
material mxp_bg = material() [[ anno::usage( "materialx:bsdf") ]],
float mxp_mix = 0.0
) [[
anno::usage( "materialx:bsdf")
]]
= material(
= let {
volume_mix_return v = volume_mix(
mxp_fg.volume.scattering_coefficient, mxp_mix,
mxp_bg.volume.scattering_coefficient, (1.0f - mxp_mix));
} in material(
surface: material_surface(
scattering: df::weighted_layer(
weight: mxp_mix,
Expand All @@ -667,15 +692,14 @@ export material mx_mix_bsdf(
// we need to carry volume properties along for SSS
ior: mxp_fg.ior, // NOTE: IOR is uniform, cannot mix here
volume: material_volume(
scattering: df::clamped_mix(
scattering: df::unbounded_mix(
df::vdf_component[](
df::vdf_component( mxp_mix, mxp_fg.volume.scattering),
df::vdf_component( 1.0 - mxp_mix, mxp_bg.volume.scattering))
df::vdf_component(v.mix_weight1, mxp_fg.volume.scattering),
df::vdf_component(1.0 - v.mix_weight1, mxp_bg.volume.scattering))
),
absorption_coefficient: mxp_mix * mxp_fg.volume.absorption_coefficient +
(1.0 - mxp_mix) * mxp_bg.volume.absorption_coefficient,
scattering_coefficient: mxp_mix * mxp_fg.volume.scattering_coefficient +
(1.0 - mxp_mix) * mxp_bg.volume.scattering_coefficient
scattering_coefficient: v.scattering_coefficient
)
);

Expand All @@ -689,7 +713,7 @@ export material mx_mix_edf(
= material(
surface: material_surface(
emission: material_emission(
emission: df::clamped_mix(
emission: df::unbounded_mix( // unbounded_mix is cheaper
df::edf_component[](
df::edf_component( mxp_mix, mxp_fg.surface.emission.emission),
df::edf_component( 1.0 - mxp_mix, mxp_bg.surface.emission.emission))
Expand All @@ -707,18 +731,21 @@ export material mx_mix_vdf(
) [[
anno::usage( "materialx:vdf")
]]
= material(
= let {
volume_mix_return v = volume_mix(
mxp_fg.volume.scattering_coefficient, mxp_mix,
mxp_bg.volume.scattering_coefficient, (1.0f - mxp_mix));
} in material(
ior: mxp_fg.ior, // NOTE: IOR is uniform, cannot mix here
volume: material_volume(
scattering: df::clamped_mix(
scattering: df::unbounded_mix(
df::vdf_component[](
df::vdf_component( mxp_mix, mxp_fg.volume.scattering),
df::vdf_component( 1.0 - mxp_mix, mxp_bg.volume.scattering))
df::vdf_component( v.mix_weight1, mxp_fg.volume.scattering),
df::vdf_component( 1.0 - v.mix_weight1, mxp_bg.volume.scattering))
),
absorption_coefficient: mxp_mix * mxp_fg.volume.absorption_coefficient +
(1.0 - mxp_mix) * mxp_bg.volume.absorption_coefficient,
scattering_coefficient: mxp_mix * mxp_fg.volume.scattering_coefficient +
(1.0 - mxp_mix) * mxp_bg.volume.scattering_coefficient
scattering_coefficient: v.scattering_coefficient
)
);

Expand All @@ -731,7 +758,11 @@ export material mx_add_bsdf(
) [[
anno::usage( "materialx:bsdf")
]]
= material(
= let {
volume_mix_return v = volume_mix(
mxp_in1.volume.scattering_coefficient, 1.0f,
mxp_in2.volume.scattering_coefficient, 1.0f);
} in material(
surface: material_surface(
scattering: df::unbounded_mix(
df::bsdf_component[](
Expand All @@ -744,13 +775,12 @@ export material mx_add_bsdf(
volume: material_volume(
scattering: df::unbounded_mix(
df::vdf_component[](
df::vdf_component( 1.0, mxp_in1.volume.scattering),
df::vdf_component( 1.0, mxp_in2.volume.scattering))
df::vdf_component( v.mix_weight1, mxp_in1.volume.scattering),
df::vdf_component( 1.0 - v.mix_weight1, mxp_in2.volume.scattering))
),
absorption_coefficient: mxp_in1.volume.absorption_coefficient +
mxp_in2.volume.absorption_coefficient,
scattering_coefficient: mxp_in1.volume.scattering_coefficient +
mxp_in2.volume.scattering_coefficient
scattering_coefficient: v.scattering_coefficient
)
);

Expand Down Expand Up @@ -786,19 +816,22 @@ export material mx_add_vdf(
) [[
anno::usage( "materialx:vdf")
]]
= material(
= let {
volume_mix_return v = volume_mix(
mxp_in1.volume.scattering_coefficient, 1.0f,
mxp_in2.volume.scattering_coefficient, 1.0f);
} in material(
// assuming mixing the IOR is the best we can do here
ior: 0.5 * mxp_in1.ior + 0.5 * mxp_in2.ior,
volume: material_volume(
scattering: df::unbounded_mix(
df::vdf_component[](
df::vdf_component( 1.0, mxp_in1.volume.scattering),
df::vdf_component( 1.0, mxp_in2.volume.scattering))
df::vdf_component( v.mix_weight1, mxp_in1.volume.scattering),
df::vdf_component( 1.0 - v.mix_weight1, mxp_in2.volume.scattering))
),
absorption_coefficient: mxp_in1.volume.absorption_coefficient +
mxp_in2.volume.absorption_coefficient,
scattering_coefficient: mxp_in1.volume.scattering_coefficient +
mxp_in2.volume.scattering_coefficient
scattering_coefficient: v.scattering_coefficient
)
);

Expand Down
4 changes: 2 additions & 2 deletions source/MaterialXGenMdl/mdl/materialx/stdlib.mdl
Original file line number Diff line number Diff line change
Expand Up @@ -2981,7 +2981,7 @@ export material mx_mix_surfaceshader(
base: mxp_bg.surface.scattering
),
emission: material_emission(
emission: df::clamped_mix(
emission: df::unbounded_mix( // unbounded_mix is cheaper
df::edf_component[](
df::edf_component( mxp_mix, mxp_fg.surface.emission.emission),
df::edf_component( 1.0 - mxp_mix, mxp_bg.surface.emission.emission))
Expand All @@ -2994,7 +2994,7 @@ export material mx_mix_surfaceshader(
// we need to carry volume properties along for SSS
ior: mxp_fg.ior, // NOTE: IOR is uniform, cannot mix here
volume: material_volume(
scattering: df::clamped_mix(
scattering: df::unbounded_mix( // unbounded_mix is cheaper
df::vdf_component[](
df::vdf_component( mxp_mix, mxp_fg.volume.scattering),
df::vdf_component( 1.0 - mxp_mix, mxp_bg.volume.scattering))
Expand Down
Loading

0 comments on commit e07012f

Please sign in to comment.