Skip to content

Commit bfb6384

Browse files
committed
Attempt to fix specular dimming and roughness on smooth materials
1 parent 8670786 commit bfb6384

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

crates/bevy_pbr/src/render/pbr_lighting.wgsl

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -644,10 +644,16 @@ fn point_light(
644644
let normalizationFactor = a / a_prime;
645645
let specular_intensity = normalizationFactor * normalizationFactor;
646646

647+
// This is a modification to Karis 2013 for area lights to fix an issue where the specular reflection on smooth materials
648+
// looks too rough and dim. We lerp between the base roughness and Karis2013 roughness with a lerp factor tuned by looking at reference renders.
649+
// The goal is to preserve sharp specular highlights on smooth materials, without blowing out specular highlights on rough materials.
650+
let lerp = 1.0 - (1.0 - a) * (1.0 - a) * (1.0 - a) * (1.0 - a);
651+
let brdf_roughness = mix(a, a_prime, lerp);
652+
647653
#ifdef STANDARD_MATERIAL_ANISOTROPY
648-
let specular_light = specular_anisotropy(input, &specular_derived_input, L, a_prime, specular_intensity);
654+
let specular_light = specular_anisotropy(input, &specular_derived_input, L, brdf_roughness, specular_intensity);
649655
#else // STANDARD_MATERIAL_ANISOTROPY
650-
let specular_light = specular(input, &specular_derived_input, a_prime, specular_intensity);
656+
let specular_light = specular(input, &specular_derived_input, brdf_roughness, specular_intensity);
651657
#endif // STANDARD_MATERIAL_ANISOTROPY
652658

653659
// Clearcoat
@@ -676,12 +682,20 @@ fn point_light(
676682

677683
// Calculate the specular light.
678684
let clearcoat_normalizationFactor = clearcoat_a / clearcoat_a_prime;
685+
679686
let clearcoat_specular_intensity = clearcoat_normalizationFactor * clearcoat_normalizationFactor;
687+
688+
// This is a modification to Karis 2013 for area lights to fix an issue where the specular reflection on smooth materials
689+
// looks too rough and dim. We lerp between the base roughness and Karis2013 roughness with a lerp factor tuned by looking at reference renders.
690+
// The goal is to preserve sharp specular highlights on smooth materials, without blowing out specular highlights on rough materials.
691+
let cc_lerp = 1.0 - (1.0 - clearcoat_a) * (1.0 - clearcoat_a) * (1.0 - clearcoat_a) * (1.0 - clearcoat_a);
692+
let clearcoat_brdf_roughness = mix(clearcoat_a, clearcoat_a_prime, cc_lerp);
693+
680694
let Fc_Frc = specular_clearcoat(
681695
input,
682696
&clearcoat_specular_derived_input,
683697
clearcoat_strength,
684-
clearcoat_a_prime,
698+
clearcoat_brdf_roughness,
685699
clearcoat_specular_intensity
686700
);
687701
let inv_Fc = 1.0 - Fc_Frc.r; // Inverse Fresnel term.

0 commit comments

Comments
 (0)