Browse Source

better organization of physical lights in glsl.

Ben Houston 9 years ago
parent
commit
7557c591b8

+ 20 - 0
src/lights/PointLight.js

@@ -19,6 +19,26 @@ THREE.PointLight = function ( color, intensity, distance, decay ) {
 THREE.PointLight.prototype = Object.create( THREE.Light.prototype );
 THREE.PointLight.prototype = Object.create( THREE.Light.prototype );
 THREE.PointLight.prototype.constructor = THREE.PointLight;
 THREE.PointLight.prototype.constructor = THREE.PointLight;
 
 
+Object.defineProperty(THREE.PointLight.prototype, "power", {
+
+  get: function() {
+
+		// intensity = power per solid angle.
+		// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+		return this.intensity * 4 * Math.PI;
+
+  },
+	set: function( power ) {
+
+		// intensity = power per solid angle.
+		// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+		this.intensity = power / ( 4 * Math.PI );
+
+	}
+
+});
+
+
 THREE.PointLight.prototype.copy = function ( source ) {
 THREE.PointLight.prototype.copy = function ( source ) {
 
 
 	THREE.Light.prototype.copy.call( this, source );
 	THREE.Light.prototype.copy.call( this, source );

+ 19 - 0
src/lights/SpotLight.js

@@ -25,6 +25,25 @@ THREE.SpotLight = function ( color, intensity, distance, angle, penumbra, decay
 THREE.SpotLight.prototype = Object.create( THREE.Light.prototype );
 THREE.SpotLight.prototype = Object.create( THREE.Light.prototype );
 THREE.SpotLight.prototype.constructor = THREE.SpotLight;
 THREE.SpotLight.prototype.constructor = THREE.SpotLight;
 
 
+Object.defineProperty(THREE.SpotLight.prototype, "power", {
+
+  get: function() {
+
+		// intensity = power per solid angle.
+		// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+		return this.intensity * 4 * Math.PI;
+
+  },
+	set: function( power ) {
+
+		// intensity = power per solid angle.
+		// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+		this.intensity = power / ( 4 * Math.PI );
+
+	}
+
+});
+
 THREE.SpotLight.prototype.copy = function ( source ) {
 THREE.SpotLight.prototype.copy = function ( source ) {
 
 
 	THREE.Light.prototype.copy.call( this, source );
 	THREE.Light.prototype.copy.call( this, source );

+ 12 - 14
src/renderers/shaders/ShaderChunk/bsdfs.glsl

@@ -4,26 +4,24 @@ bool testLightInRange( const in float lightDistance, const in float cutoffDistan
 
 
 }
 }
 
 
-float calcLightAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
-
-	if ( decayExponent > 0.0 ) {
+float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
 
 
-	  return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );
+		if( decayExponent > 0.0 ) {
 
 
-	}
+#if defined ( PHYSICAL_LIGHTS )
 
 
-	return 1.0;
+			// based upon Frostbite 3 Moving to Physically-based Rendering
+			// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+			// this is intended to be used on spot and point lights who are represented as luminous intensity
+			// but who must be converted to luminous irradiance for surface lighting calculation
+			return pow( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ), decayExponent ) /
+				max( pow( lightDistance, decayExponent ), 0.01 );
 
 
-}
+#else
 
 
-// based upon Frostbite 3 Moving to Physically-based Rendering
-// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
-// this is intended to be used on spot and point lights.
-float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
-
-		if( decayExponent > 0.0 ) {
+			return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );
 
 
-			return pow( saturate( 1.0 - pow4( lightDistance / maxDistance ), decayExponent ) / max( pow( lightDistance, decayExponent ), 0.01 );
+#endif
 
 
 		}
 		}
 
 

+ 1 - 20
src/renderers/shaders/ShaderChunk/lights_pars.glsl

@@ -55,17 +55,8 @@
 		if ( testLightInRange( lightDistance, pointLight.distance ) ) {
 		if ( testLightInRange( lightDistance, pointLight.distance ) ) {
 
 
 			directLight.color = pointLight.color;
 			directLight.color = pointLight.color;
-
-#if defined( PHYSICAL_LIGHTS )
-
 			directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );
 			directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );
 
 
-#else
-
-			directLight.color *= calcLightAttenuation( lightDistance, pointLight.distance, pointLight.decay );
-
-#endif
-
 			directLight.visible = true;
 			directLight.visible = true;
 
 
 		} else {
 		} else {
@@ -116,17 +107,7 @@
 			float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );
 			float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );
 
 
 			directLight.color = spotLight.color;
 			directLight.color = spotLight.color;
-			directLight.color *= spotEffect;
-
-			#if defined( PHYSICAL_LIGHTS )
-
-						directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );
-
-			#else
-
-						directLight.color *= calcLightAttenuation( lightDistance, pointLight.distance, pointLight.decay );
-
-			#endif
+			directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );
 
 
 			directLight.visible = true;
 			directLight.visible = true;