|
@@ -48,6 +48,43 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
+float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
|
|
|
+
|
|
|
+ #if defined ( PHYSICALLY_CORRECT_LIGHTS )
|
|
|
+
|
|
|
+ // based upon Frostbite 3 Moving to Physically-based Rendering
|
|
|
+ // page 32, equation 26: E[window1]
|
|
|
+ // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
|
|
|
+ float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );
|
|
|
+
|
|
|
+ if ( cutoffDistance > 0.0 ) {
|
|
|
+
|
|
|
+ distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return distanceFalloff;
|
|
|
+
|
|
|
+ #else
|
|
|
+
|
|
|
+ if ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {
|
|
|
+
|
|
|
+ return pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return 1.0;
|
|
|
+
|
|
|
+ #endif
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {
|
|
|
+
|
|
|
+ return smoothstep( coneCosine, penumbraCosine, angleCosine );
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
#if NUM_DIR_LIGHTS > 0
|
|
|
|
|
|
struct DirectionalLight {
|
|
@@ -57,11 +94,11 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
|
|
|
|
|
|
uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
|
|
|
|
|
|
- void getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {
|
|
|
+ void getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {
|
|
|
|
|
|
- directLight.color = directionalLight.color;
|
|
|
- directLight.direction = directionalLight.direction;
|
|
|
- directLight.visible = true;
|
|
|
+ light.color = directionalLight.color;
|
|
|
+ light.direction = directionalLight.direction;
|
|
|
+ light.visible = true;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -79,17 +116,18 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
|
|
|
|
|
|
uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
|
|
|
|
|
|
- // directLight is an out parameter as having it as a return value caused compiler errors on some devices
|
|
|
- void getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {
|
|
|
+ // light is an out parameter as having it as a return value caused compiler errors on some devices
|
|
|
+ void getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {
|
|
|
|
|
|
vec3 lVector = pointLight.position - geometry.position;
|
|
|
- directLight.direction = normalize( lVector );
|
|
|
+
|
|
|
+ light.direction = normalize( lVector );
|
|
|
|
|
|
float lightDistance = length( lVector );
|
|
|
|
|
|
- directLight.color = pointLight.color;
|
|
|
- directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );
|
|
|
- directLight.visible = ( directLight.color != vec3( 0.0 ) );
|
|
|
+ light.color = pointLight.color;
|
|
|
+ light.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );
|
|
|
+ light.visible = ( light.color != vec3( 0.0 ) );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -110,29 +148,32 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
|
|
|
|
|
|
uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];
|
|
|
|
|
|
- // directLight is an out parameter as having it as a return value caused compiler errors on some devices
|
|
|
- void getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {
|
|
|
+ // light is an out parameter as having it as a return value caused compiler errors on some devices
|
|
|
+ void getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {
|
|
|
|
|
|
vec3 lVector = spotLight.position - geometry.position;
|
|
|
- directLight.direction = normalize( lVector );
|
|
|
|
|
|
- float lightDistance = length( lVector );
|
|
|
- float angleCos = dot( directLight.direction, spotLight.direction );
|
|
|
+ light.direction = normalize( lVector );
|
|
|
|
|
|
- if ( angleCos > spotLight.coneCos ) {
|
|
|
+ float angleCos = dot( light.direction, spotLight.direction );
|
|
|
|
|
|
- float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );
|
|
|
+ float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );
|
|
|
|
|
|
- directLight.color = spotLight.color;
|
|
|
- directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );
|
|
|
- directLight.visible = true;
|
|
|
+ if ( spotAttenuation > 0.0 ) {
|
|
|
+
|
|
|
+ float lightDistance = length( lVector );
|
|
|
+
|
|
|
+ light.color = spotLight.color * spotAttenuation;
|
|
|
+ light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );
|
|
|
+ light.visible = ( light.color != vec3( 0.0 ) );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- directLight.color = vec3( 0.0 );
|
|
|
- directLight.visible = false;
|
|
|
+ light.color = vec3( 0.0 );
|
|
|
+ light.visible = false;
|
|
|
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
#endif
|