Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for EON diffuse #1822

Merged
1 change: 1 addition & 0 deletions libraries/bxdf/open_pbr_surface.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@
<input name="color" type="color3" nodename="base_color_nonnegative" />
<input name="roughness" type="float" interfacename="base_diffuse_roughness" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
<input name="energy_compensation" type="boolean" value="true" />
</oren_nayar_diffuse_bsdf>
<convert name="subsurface_selector" type="float">
<input name="in" type="boolean" interfacename="geometry_thin_walled" />
Expand Down
31 changes: 29 additions & 2 deletions libraries/pbrlib/genglsl/lib/mx_microfacet_diffuse.glsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "mx_microfacet.glsl"

// Based on the implementation of Oren-Nayar diffuse in Open Shading Language.
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/blob/main/src/testrender/shading.cpp
// Qualitative Oren-Nayar diffuse with improvements from Fujii:
// https://mimosa-pudica.net/improved-oren-nayar.html
float mx_oren_nayar_diffuse(float NdotV, float NdotL, float LdotV, float roughness)
{
float s = LdotV - NdotL * NdotV;
jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -79,6 +79,33 @@ float mx_oren_nayar_diffuse_dir_albedo(float NdotV, float roughness)
return clamp(dirAlbedo, 0.0, 1.0);
}

float mx_oren_nayar_diffuse_avg_albedo(float NdotV, float roughness)
{
float sigma2 = mx_square(roughness);
float A = 1.0 - 0.5 * (sigma2 / (sigma2 + 0.33));
float B = 0.45 * sigma2 / (sigma2 + 0.09);
return A + (2.0 / 3.0 - 64.0 / (45.0 * M_PI)) * B;
jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved
}

// Energy compensation for Oren-Nayar diffuse from the OpenPBR project at openpbr.org.
vec3 mx_oren_nayar_diffuse_energy_compensation(float NdotV, float NdotL, float roughness, vec3 color)
{
// Compute directional and average albedos.
float dirAlbedoV = mx_oren_nayar_diffuse_dir_albedo(NdotV, roughness);
float dirAlbedoL = mx_oren_nayar_diffuse_dir_albedo(NdotL, roughness);
float avgAlbedo = mx_oren_nayar_diffuse_avg_albedo(NdotV, roughness);

// Compute the multi-scatter color term.
vec3 rhoMultiScatter = mx_square(color) * avgAlbedo /
(vec3(1.0) - color * max(0.0, 1.0 - avgAlbedo));

// Return the final energy compensation.
return rhoMultiScatter *
max(M_FLOAT_EPS, 1.0 - dirAlbedoV) *
max(M_FLOAT_EPS, 1.0 - dirAlbedoL) /
max(M_FLOAT_EPS, 1.0 - avgAlbedo);
}

// https://media.disneyanimation.com/uploads/production/publication_asset/48/asset/s2012_pbs_disney_brdf_notes_v3.pdf
// Section 5.3
float mx_burley_diffuse(float NdotV, float NdotL, float LdotH, float roughness)
Expand Down
25 changes: 15 additions & 10 deletions libraries/pbrlib/genglsl/mx_oren_nayar_diffuse_bsdf.glsl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "lib/mx_microfacet_diffuse.glsl"

void mx_oren_nayar_diffuse_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color, float roughness, vec3 normal, inout BSDF bsdf)
void mx_oren_nayar_diffuse_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color, float roughness, vec3 normal, bool energy_compensation, inout BSDF bsdf)
{
bsdf.throughput = vec3(0.0);

Expand All @@ -15,14 +15,15 @@ void mx_oren_nayar_diffuse_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusi
float NdotL = clamp(dot(normal, L), M_FLOAT_EPS, 1.0);
float LdotV = clamp(dot(L, V), M_FLOAT_EPS, 1.0);

bsdf.response = color * occlusion * weight * NdotL * M_PI_INV;
if (roughness > 0.0)
{
bsdf.response *= mx_oren_nayar_diffuse(NdotV, NdotL, LdotV, roughness);
}
vec3 compColor = energy_compensation ?
mx_oren_nayar_diffuse_energy_compensation(NdotV, NdotL, roughness, color) :
vec3(0.0);

bsdf.response = color * mx_oren_nayar_diffuse(NdotV, NdotL, LdotV, roughness) + compColor;
bsdf.response *= occlusion * weight * NdotL * M_PI_INV;
}

void mx_oren_nayar_diffuse_bsdf_indirect(vec3 V, float weight, vec3 color, float roughness, vec3 normal, inout BSDF bsdf)
void mx_oren_nayar_diffuse_bsdf_indirect(vec3 V, float weight, vec3 color, float roughness, vec3 normal, bool energy_compensation, inout BSDF bsdf)
{
bsdf.throughput = vec3(0.0);

Expand All @@ -35,7 +36,11 @@ void mx_oren_nayar_diffuse_bsdf_indirect(vec3 V, float weight, vec3 color, float

float NdotV = clamp(dot(normal, V), M_FLOAT_EPS, 1.0);

vec3 Li = mx_environment_irradiance(normal) *
mx_oren_nayar_diffuse_dir_albedo(NdotV, roughness);
bsdf.response = Li * color * weight;
vec3 compColor = energy_compensation ?
mx_oren_nayar_diffuse_energy_compensation(NdotV, 1.0, roughness, color) :
vec3(0.0);

vec3 Li = mx_environment_irradiance(normal);
bsdf.response = color * mx_oren_nayar_diffuse_dir_albedo(NdotV, roughness) + compColor;
bsdf.response *= Li * weight;
}
1 change: 1 addition & 0 deletions libraries/pbrlib/pbrlib_defs.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<input name="color" type="color3" value="0.18, 0.18, 0.18" />
<input name="roughness" type="float" value="0.0" />
<input name="normal" type="vector3" defaultgeomprop="Nworld" />
<input name="energy_compensation" type="boolean" value="false" uniform="true" />
<output name="out" type="BSDF" />
</nodedef>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<oren_nayar_diffuse_bsdf name="diffuse1" type="BSDF">
<input name="color" type="color3" value="0.6, 0.6, 0.6" />
<input name="roughness" type="float" value="0.0" />
<input name="energy_compensation" type="boolean" value="true" />
</oren_nayar_diffuse_bsdf>
<surface name="surface1" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="diffuse1" />
Expand All @@ -14,6 +15,7 @@
<oren_nayar_diffuse_bsdf name="diffuse2" type="BSDF">
<input name="color" type="color3" value="0.6, 0.6, 0.6" />
<input name="roughness" type="float" value="0.25" />
<input name="energy_compensation" type="boolean" value="true" />
</oren_nayar_diffuse_bsdf>
<surface name="surface2" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="diffuse2" />
Expand All @@ -23,6 +25,7 @@
<oren_nayar_diffuse_bsdf name="diffuse3" type="BSDF">
<input name="color" type="color3" value="0.6, 0.6, 0.6" />
<input name="roughness" type="float" value="0.5" />
<input name="energy_compensation" type="boolean" value="true" />
</oren_nayar_diffuse_bsdf>
<surface name="surface3" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="diffuse3" />
Expand All @@ -32,6 +35,7 @@
<oren_nayar_diffuse_bsdf name="diffuse4" type="BSDF">
<input name="color" type="color3" value="0.6, 0.6, 0.6" />
<input name="roughness" type="float" value="0.75" />
<input name="energy_compensation" type="boolean" value="true" />
</oren_nayar_diffuse_bsdf>
<surface name="surface4" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="diffuse4" />
Expand All @@ -41,6 +45,7 @@
<oren_nayar_diffuse_bsdf name="diffuse5" type="BSDF">
<input name="color" type="color3" value="0.6, 0.6, 0.6" />
<input name="roughness" type="float" value="1.0" />
<input name="energy_compensation" type="boolean" value="true" />
</oren_nayar_diffuse_bsdf>
<surface name="surface5" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="diffuse5" />
Expand Down