Pārlūkot izejas kodu

add decay exponent to Point and Spot lights and applicable shaders.

Ben Houston 10 gadi atpakaļ
vecāks
revīzija
3909dc68c8

+ 4 - 2
src/lights/PointLight.js

@@ -2,7 +2,7 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-THREE.PointLight = function ( color, intensity, distance ) {
+THREE.PointLight = function ( color, intensity, distance, decayExponent ) {
 
 	THREE.Light.call( this, color );
 
@@ -10,6 +10,7 @@ THREE.PointLight = function ( color, intensity, distance ) {
 
 	this.intensity = ( intensity !== undefined ) ? intensity : 1;
 	this.distance = ( distance !== undefined ) ? distance : 0;
+	this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 0;;	// for physically correct lights, should be 2.
 
 };
 
@@ -24,7 +25,8 @@ THREE.PointLight.prototype.clone = function () {
 
 	light.intensity = this.intensity;
 	light.distance = this.distance;
-
+	light.decayExponent = this.decayExponent;
+	
 	return light;
 
 };

+ 4 - 2
src/lights/SpotLight.js

@@ -2,7 +2,7 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.SpotLight = function ( color, intensity, distance, angle, exponent ) {
+THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decayExponent ) {
 
 	THREE.Light.call( this, color );
 
@@ -15,6 +15,7 @@ THREE.SpotLight = function ( color, intensity, distance, angle, exponent ) {
 	this.distance = ( distance !== undefined ) ? distance : 0;
 	this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
 	this.exponent = ( exponent !== undefined ) ? exponent : 10;
+	this.decayExponent = ( decayExponent !== undefined ) ? decayExponent : 0;;	// for physically correct lights, should be 2.
 
 	this.castShadow = false;
 	this.onlyShadow = false;
@@ -57,7 +58,8 @@ THREE.SpotLight.prototype.clone = function () {
 	light.distance = this.distance;
 	light.angle = this.angle;
 	light.exponent = this.exponent;
-
+	light.decayExponent = this.decayExponent;
+	
 	light.castShadow = this.castShadow;
 	light.onlyShadow = this.onlyShadow;
 

+ 10 - 2
src/renderers/WebGLRenderer.js

@@ -168,8 +168,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		ambient: [ 0, 0, 0 ],
 		directional: { length: 0, colors:[], positions: [] },
-		point: { length: 0, colors: [], positions: [], distances: [] },
-		spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [] },
+		point: { length: 0, colors: [], positions: [], distances: [], decayExponents: [] },
+		spot: { length: 0, colors: [], positions: [], distances: [], directions: [], anglesCos: [], exponents: [], decayExponents: [] },
 		hemi: { length: 0, skyColors: [], groundColors: [], positions: [] }
 
 	};
@@ -4710,6 +4710,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		uniforms.pointLightColor.value = lights.point.colors;
 		uniforms.pointLightPosition.value = lights.point.positions;
 		uniforms.pointLightDistance.value = lights.point.distances;
+		uniforms.pointLightDecayExponent.value = lights.point.decayExponents;
 
 		uniforms.spotLightColor.value = lights.spot.colors;
 		uniforms.spotLightPosition.value = lights.spot.positions;
@@ -4717,6 +4718,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		uniforms.spotLightDirection.value = lights.spot.directions;
 		uniforms.spotLightAngleCos.value = lights.spot.anglesCos;
 		uniforms.spotLightExponent.value = lights.spot.exponents;
+		uniforms.spotLightDecayExponent.value = lights.spot.decayExponents;
 
 		uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
 		uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
@@ -4736,6 +4738,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		uniforms.pointLightColor.needsUpdate = boolean;
 		uniforms.pointLightPosition.needsUpdate = boolean;
 		uniforms.pointLightDistance.needsUpdate = boolean;
+		uniforms.pointLightDecayExponent.needsUpdate = boolean;
 
 		uniforms.spotLightColor.needsUpdate = boolean;
 		uniforms.spotLightPosition.needsUpdate = boolean;
@@ -4743,6 +4746,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		uniforms.spotLightDirection.needsUpdate = boolean;
 		uniforms.spotLightAngleCos.needsUpdate = boolean;
 		uniforms.spotLightExponent.needsUpdate = boolean;
+		uniforms.spotLightDecayExponent.needsUpdate = boolean;
 
 		uniforms.hemisphereLightSkyColor.needsUpdate = boolean;
 		uniforms.hemisphereLightGroundColor.needsUpdate = boolean;
@@ -5190,6 +5194,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		pointColors = zlights.point.colors,
 		pointPositions = zlights.point.positions,
 		pointDistances = zlights.point.distances,
+		pointDecayExponents = zlights.point.decayExponents,
 
 		spotColors = zlights.spot.colors,
 		spotPositions = zlights.spot.positions,
@@ -5197,6 +5202,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		spotDirections = zlights.spot.directions,
 		spotAnglesCos = zlights.spot.anglesCos,
 		spotExponents = zlights.spot.exponents,
+		spotDecayExponents = zlights.spot.decayExponents,
 
 		hemiSkyColors = zlights.hemi.skyColors,
 		hemiGroundColors = zlights.hemi.groundColors,
@@ -5299,6 +5305,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 				pointPositions[ pointOffset + 2 ] = _vector3.z;
 
 				pointDistances[ pointLength ] = distance;
+				pointDecayExponents[ pointLength ] = light.decayExponent;
 
 				pointLength += 1;
 
@@ -5338,6 +5345,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 				spotAnglesCos[ spotLength ] = Math.cos( light.angle );
 				spotExponents[ spotLength ] = light.exponent;
+				spotDecayExponents[ pointLength ] = light.decayExponent;
 
 				spotLength += 1;
 

+ 8 - 0
src/renderers/shaders/ShaderChunk/common.glsl

@@ -32,4 +32,12 @@ float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
 }
 vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
 	return pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) );
+}
+// standard exponential distance attenuation multiplied by a linear distance cutoff, if cutoffDistance > 0.
+float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {
+	float distanceAttenuation = 1.0 / pow( lightDistance, decayExponent );
+	if ( cutoffDistance > 0.0 ) {
+		distanceAttenuation *= 1.0 - min( lightDistance / cutoffDistance, 1.0 );
+	}
+	return distanceAttenuation;
 }

+ 2 - 0
src/renderers/shaders/ShaderChunk/lights_lambert_pars_vertex.glsl

@@ -24,6 +24,7 @@ uniform vec3 ambientLightColor;
 	uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];
 	uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];
 	uniform float pointLightDistance[ MAX_POINT_LIGHTS ];
+	uniform float pointLightDistance[ MAX_POINT_LIGHTS ];
 
 #endif
 
@@ -35,6 +36,7 @@ uniform vec3 ambientLightColor;
 	uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];
 	uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];
 	uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];
+	uniform float spotLightDecayExponent[ MAX_SPOT_LIGHTS ];
 
 #endif
 

+ 2 - 6
src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl

@@ -61,9 +61,7 @@ for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
 		vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );
 		vec3 lVector = lPosition.xyz - mvPosition.xyz;
 
-		float lDistance = 1.0;
-		if ( pointLightDistance[ i ] > 0.0 )
-			lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );
+		float lDistance = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] );
 
 		lVector = normalize( lVector );
 		float dotProduct = dot( transformedNormal, lVector );
@@ -120,9 +118,7 @@ for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
 
 			spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );
 
-			float lDistance = 1.0;
-			if ( spotLightDistance[ i ] > 0.0 )
-				lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );
+			float lDistance = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecayExponent[i] );
 
 			lVector = normalize( lVector );
 

+ 2 - 6
src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl

@@ -27,9 +27,7 @@ vec3 viewPosition = normalize( vViewPosition );
 		vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );
 		vec3 lVector = lPosition.xyz + vViewPosition.xyz;
 
-		float lDistance = 1.0;
-		if ( pointLightDistance[ i ] > 0.0 )
-			lDistance = saturate( 1.0 - ( length( lVector ) / pointLightDistance[ i ] ) );
+		float lDistance = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecayExponent[i] );
 
 		lVector = normalize( lVector );
 
@@ -77,9 +75,7 @@ vec3 viewPosition = normalize( vViewPosition );
 		vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );
 		vec3 lVector = lPosition.xyz + vViewPosition.xyz;
 
-		float lDistance = 1.0;
-		if ( spotLightDistance[ i ] > 0.0 )
-			lDistance = saturate( 1.0 - ( length( lVector ) / spotLightDistance[ i ] );
+		float lDistance = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecayExponent[i] );
 
 		lVector = normalize( lVector );
 

+ 2 - 1
src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl

@@ -21,6 +21,7 @@ uniform vec3 ambientLightColor;
 
 	uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];
 	uniform float pointLightDistance[ MAX_POINT_LIGHTS ];
+	uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ];
 
 #endif
 
@@ -31,8 +32,8 @@ uniform vec3 ambientLightColor;
 	uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];
 	uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];
 	uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];
-
 	uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];
+	uniform float spotLightDecayExponent[ MAX_SPOT_LIGHTS ];
 
 #endif
 

+ 4 - 6
src/renderers/shaders/ShaderLib.js

@@ -709,6 +709,7 @@ THREE.ShaderLib = {
 			"	uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
 			"	uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
 			"	uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
+			"	uniform float pointLightDecayExponent[ MAX_POINT_LIGHTS ];",
 
 			"#endif",
 
@@ -720,6 +721,7 @@ THREE.ShaderLib = {
 			"	uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];",
 			"	uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
 			"	uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
+			"	uniform float spotLightDecayExponent[ MAX_SPOT_LIGHTS ];",
 
 			"#endif",
 
@@ -810,9 +812,7 @@ THREE.ShaderLib = {
 			"			vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
 			"			vec3 pointVector = lPosition.xyz + vViewPosition.xyz;",
 
-			"			float pointDistance = 1.0;",
-			"			if ( pointLightDistance[ i ] > 0.0 )",
-			"				pointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );",
+			"			float pointDistance = calcLightAttenuation( length( pointVector ), pointLightDistance[ i ], pointLightDecayExponent[i] );",
 
 			"			pointVector = normalize( pointVector );",
 
@@ -860,9 +860,7 @@ THREE.ShaderLib = {
 			"			vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
 			"			vec3 spotVector = lPosition.xyz + vViewPosition.xyz;",
 
-			"			float spotDistance = 1.0;",
-			"			if ( spotLightDistance[ i ] > 0.0 )",
-			"				spotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );",
+			"			float spotDistance = calcLightAttenuation( length( spotVector ), spotLightDistance[ i ], spotLightDecayExponent[i] );",
 
 			"			spotVector = normalize( spotVector );",
 

+ 3 - 1
src/renderers/shaders/UniformsLib.js

@@ -61,13 +61,15 @@ THREE.UniformsLib = {
 		"pointLightColor" : { type: "fv", value: [] },
 		"pointLightPosition" : { type: "fv", value: [] },
 		"pointLightDistance" : { type: "fv1", value: [] },
+		"pointLightDecayExponent" : { type: "fv1", value: [] },
 
 		"spotLightColor" : { type: "fv", value: [] },
 		"spotLightPosition" : { type: "fv", value: [] },
 		"spotLightDirection" : { type: "fv", value: [] },
 		"spotLightDistance" : { type: "fv1", value: [] },
 		"spotLightAngleCos" : { type: "fv1", value: [] },
-		"spotLightExponent" : { type: "fv1", value: [] }
+		"spotLightExponent" : { type: "fv1", value: [] },
+		"spotLightDecayExponent" : { type: "fv1", value: [] }
 
 	},