diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl index 8044e1f40bec3a67ef79a4c7f8fb28e76a635ba5..22534c3a19c367d94e3755d7c9301cfc0091c114 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl @@ -14,6 +14,13 @@ struct PhysicalMaterial { #define MAXIMUM_SPECULAR_COEFFICIENT 0.16 #define DEFAULT_SPECULAR_COEFFICIENT 0.04 +// Clear coat directional hemishperical reflectance (this approximation should be improved) +float clearCoatDHRApprox( const in float roughness, const in float dotNL ) { + + return DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) ); + +} + void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); @@ -26,8 +33,14 @@ void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricC #endif - reflectedLight.directSpecular += irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); - reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); + #ifndef STANDARD + float clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL ); + #else + float clearCoatDHR = 0.0; + #endif + + reflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); + reflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); #ifndef STANDARD @@ -45,7 +58,15 @@ void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricCo void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { - reflectedLight.indirectSpecular += radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness ); + #ifndef STANDARD + float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); + float dotNL = dotNV; + float clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL ); + #else + float clearCoatDHR = 0.0; + #endif + + reflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness ); #ifndef STANDARD