diff --git a/src/renderers/shaders/ShaderChunk/bsdfs.glsl b/src/renderers/shaders/ShaderChunk/bsdfs.glsl index 57d397761f72774a1aaee5e9e3936dced260ae88..66560e34f8d0265e32a5676bd0869b7f97755aef 100644 --- a/src/renderers/shaders/ShaderChunk/bsdfs.glsl +++ b/src/renderers/shaders/ShaderChunk/bsdfs.glsl @@ -13,9 +13,7 @@ float calcLightAttenuation( const in float lightDistance, const in float cutoffD vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) { - // factor of 1/PI in BRDF omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source - - return diffuseColor; + return RECIPROCAL_PI * diffuseColor; } // validated @@ -56,21 +54,17 @@ float G_GGX_Smith( const in float alpha, const in float dotNL, const in float do // alpha is "roughness squared" in Disney’s reparameterization float D_GGX( const in float alpha, const in float dotNH ) { - // factor of 1/PI in distribution term omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source - float a2 = alpha * alpha; float denom = dotNH * dotNH * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1 - return a2 / ( denom * denom ); + return RECIPROCAL_PI * a2 / ( denom * denom ); } // GGX Distribution, Schlick Fresnel, GGX-Smith Visibility vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) { - - // factor of 1/PI in BRDF omitted (normally it is in D_GGX) as incoming light intensity is scaled up by PI because it is considered a punctual light source float alpha = roughness * roughness; // UE4's roughness @@ -121,16 +115,12 @@ float G_BlinnPhong_Implicit( /* const in float dotNL, const in float dotNV */ ) float D_BlinnPhong( const in float shininess, const in float dotNH ) { - // factor of 1/PI in distribution term omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source - - return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); + return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); } vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) { - // factor of 1/PI in BRDF omitted (normally it is in D_BlinnPhong) as incoming light intensity is scaled up by PI because it is considered a punctual light source - vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); //float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl index 7b20a751cd9c84e4103eee553f6e0386ac3f93d5..11e62af413fbb420d1d12c0b2d61ec3217d683e8 100644 --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl @@ -16,7 +16,7 @@ vLightFront = vec3( 0.0 ); IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry ); float dotNL = dot( geometry.normal, directLight.direction ); - vec3 directLightColor_Diffuse = directLight.color * BRDF_Diffuse_Lambert( diffuse ); + vec3 directLightColor_Diffuse = PI * directLight.color; vLightFront += saturate( dotNL ) * directLightColor_Diffuse; @@ -37,7 +37,7 @@ vLightFront = vec3( 0.0 ); IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry ); float dotNL = dot( geometry.normal, directLight.direction ); - vec3 directLightColor_Diffuse = directLight.color * BRDF_Diffuse_Lambert( diffuse ); + vec3 directLightColor_Diffuse = PI * directLight.color; vLightFront += saturate( dotNL ) * directLightColor_Diffuse; @@ -57,7 +57,7 @@ vLightFront = vec3( 0.0 ); IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry ); float dotNL = dot( geometry.normal, directLight.direction ); - vec3 directLightColor_Diffuse = directLight.color * BRDF_Diffuse_Lambert( diffuse ); + vec3 directLightColor_Diffuse = PI * directLight.color; vLightFront += saturate( dotNL ) * directLightColor_Diffuse; @@ -72,15 +72,12 @@ vLightFront = vec3( 0.0 ); #endif { - // dotNL is always one, and diffuseColor is vec3(1.0), thus the result is equivalent to summing indirectDiffuse lights - //float frontDotNL = saturate( dot( geometry.normal, frontIndirectLight.direction ) ); - //vLightFront += frontDotNL * frontIndirectLight.color * BRDF_Diffuse_Lambert( diffuse ); - vLightFront += ambientLightColor; + vLightFront += PI * ambientLightColor; #ifdef DOUBLE_SIDED - vLightBack += ambientLightColor; + vLightBack += PI * ambientLightColor; #endif @@ -88,11 +85,11 @@ vLightFront = vec3( 0.0 ); for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - vLightFront += getHemisphereIndirectLightColor( hemisphereLights[ i ], geometry ); + vLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry ); #ifdef DOUBLE_SIDED - vLightBack += getHemisphereIndirectLightColor( hemisphereLights[ i ], backGeometry ); + vLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry ); #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl index c32c1cd1774fbbf571ea4b291828f254ccf73719..0f9f548074847ef5638f3a8693df7d1c0fd71390 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl @@ -1,5 +1,11 @@ uniform vec3 ambientLightColor; +vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { + + + return PI * ambientLightColor; + +} #if MAX_DIR_LIGHTS > 0 @@ -104,12 +110,12 @@ uniform vec3 ambientLightColor; uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ]; - vec3 getHemisphereIndirectLightColor( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { + vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { float dotNL = dot( geometry.normal, hemiLight.direction ); float hemiDiffuseWeight = 0.5 * dotNL + 0.5; - return mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); + return PI * mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); } @@ -118,8 +124,7 @@ uniform vec3 ambientLightColor; #if defined( USE_ENVMAP ) && defined( PHYSICAL ) - - vec3 getDiffuseLightProbeIndirectLightColor( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in int maxMIPLevel ) { + vec3 getLightProbeIndirectIrradiance( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in int maxMIPLevel ) { #ifdef DOUBLE_SIDED @@ -158,7 +163,7 @@ uniform vec3 ambientLightColor; envMapColor.rgb = inputToLinear( envMapColor.rgb ); - return envMapColor.rgb; + return PI * envMapColor.rgb; } @@ -176,7 +181,7 @@ uniform vec3 ambientLightColor; } - vec3 getSpecularLightProbeIndirectLightColor( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) { + vec3 getLightProbeIndirectRadiance( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) { #ifdef ENVMAP_MODE_REFLECTION diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index fff4f5a98d6f4ef8bcc8aeac1621c85596ecf205..5d233782515ff8afc3ab039452a1317270f456ac 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -24,17 +24,19 @@ void BlinnPhongMaterial_RE_DirectLight( const in IncidentLight directLight, cons float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - reflectedLight.directDiffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( material.diffuseColor ); + vec3 irradiance = dotNL * PI * directLight.color; // punctual light - reflectedLight.directSpecular += dotNL * directLight.color * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength; + reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); + + reflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength; } #define Material_RE_DirectLight BlinnPhongMaterial_RE_DirectLight -void BlinnPhongMaterial_RE_IndirectDiffuseLight( const in vec3 indirectDiffuseColor, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) { +void BlinnPhongMaterial_RE_IndirectDiffuseLight( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) { - reflectedLight.indirectDiffuse += indirectDiffuseColor * BRDF_Diffuse_Lambert( material.diffuseColor ); + reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); } diff --git a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl index 39c70dbd11fd63b9cd281ac827c61fdd16f28a86..ebd4397a20f3071640265bead329d49f7ef0fba1 100644 --- a/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl @@ -10,25 +10,29 @@ void PhysicalMaterial_RE_DirectLight( const in IncidentLight directLight, const float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); - reflectedLight.directDiffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( material.diffuseColor ); - reflectedLight.directSpecular += dotNL * directLight.color * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); + vec3 irradiance = dotNL * PI * directLight.color; // punctual light + + reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); + + reflectedLight.directSpecular += irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); } + #define Material_RE_DirectLight PhysicalMaterial_RE_DirectLight -void PhysicalMaterial_RE_DiffuseIndirectLight( const in vec3 indirectDiffuseColor, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { +void PhysicalMaterial_RE_DiffuseIndirectLight( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { - reflectedLight.indirectDiffuse += indirectDiffuseColor * BRDF_Diffuse_Lambert( material.diffuseColor ); + reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); } #define Material_RE_IndirectDiffuseLight PhysicalMaterial_RE_DiffuseIndirectLight -void PhysicalMaterial_RE_SpecularIndirectLight( const in vec3 indirectSpecularColor, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { +void PhysicalMaterial_RE_SpecularIndirectLight( const in vec3 radiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { - reflectedLight.indirectSpecular += indirectSpecularColor * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness ); + reflectedLight.indirectSpecular += radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness ); } diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl index 4b4fd9c3c86c31b1e95041053d7cd08d0592d5eb..b98ab885133bd62b78452f333757d4d59f33bcf2 100644 --- a/src/renderers/shaders/ShaderChunk/lights_template.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl @@ -55,11 +55,11 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal { - vec3 indirectDiffuseColor = ambientLightColor; + vec3 indirectDiffuseIrradiance = getAmbientLightIrradiance( ambientLightColor ); #ifdef USE_LIGHTMAP - indirectDiffuseColor += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; + indirectDiffuseIrradiance += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; // factor of PI should not be present; included here to prevent breakage #endif @@ -67,7 +67,7 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { - indirectDiffuseColor += getHemisphereIndirectLightColor( hemisphereLights[ i ], geometry ); + indirectDiffuseIrradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry ); } @@ -76,11 +76,11 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal #if defined( USE_ENVMAP ) && defined( PHYSICAL ) // TODO, replace 8 with the real maxMIPLevel - indirectDiffuseColor += getDiffuseLightProbeIndirectLightColor( /*lightProbe,*/ geometry, 8 ); + indirectDiffuseIrradiance += getLightProbeIndirectIrradiance( /*lightProbe,*/ geometry, 8 ); #endif - Material_RE_IndirectDiffuseLight( indirectDiffuseColor, geometry, material, reflectedLight ); + Material_RE_IndirectDiffuseLight( indirectDiffuseIrradiance, geometry, material, reflectedLight ); } @@ -91,9 +91,9 @@ GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal { // TODO, replace 8 with the real maxMIPLevel - vec3 indirectSpecularColor = getSpecularLightProbeIndirectLightColor( /*specularLightProbe,*/ geometry, Material_BlinnShininessExponent( material ), 8 ); + vec3 indirectSpecularRadiance = getLightProbeIndirectRadiance( /*specularLightProbe,*/ geometry, Material_BlinnShininessExponent( material ), 8 ); - Material_RE_IndirectSpecularLight( indirectSpecularColor, geometry, material, reflectedLight ); + Material_RE_IndirectSpecularLight( indirectSpecularRadiance, geometry, material, reflectedLight ); } diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 5c5227cd838b660d8854abde0bcc3641ac6e0ab5..ffc2e0ad2247f5c5f24b909860962acaa044e010 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -216,7 +216,6 @@ THREE.ShaderLib = { " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does " vec4 diffuseColor = vec4( diffuse, opacity );", - " vec3 totalAmbientLight = ambientLightColor;", " vec3 shadowMask = vec3( 1.0 );", THREE.ShaderChunk[ "logdepthbuf_fragment" ], @@ -230,13 +229,13 @@ THREE.ShaderLib = { " #ifdef DOUBLE_SIDED", " if ( gl_FrontFacing )", - " outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask ) + emissive;", + " outgoingLight += RECIPROCAL_PI * diffuseColor.rgb * ( vLightFront * shadowMask ) + emissive;", " else", - " outgoingLight += diffuseColor.rgb * ( vLightBack * shadowMask ) + emissive;", + " outgoingLight += RECIPROCAL_PI * diffuseColor.rgb * ( vLightBack * shadowMask ) + emissive;", " #else", - " outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask ) + emissive;", + " outgoingLight += RECIPROCAL_PI * diffuseColor.rgb * ( vLightFront * shadowMask ) + emissive;", " #endif",