提交 54fa9416 编写于 作者: M Mr.doob

Merge pull request #7523 from WestLangley/dev-pi

Restored factor of PI to BRDFs
......@@ -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 ) );
......
......@@ -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
......
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
......
......@@ -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 );
}
......
......@@ -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 );
}
......
......@@ -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 );
}
......
......@@ -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",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册