Browse Source

Editor: added handling of SpotLights. Added SpotLightHelper.

Also fixed spotlights shading in Lambert material and light helpers init colors for light intensities > 1.

Please disregard init scene lighting weirdness, this is just temporary, to be able to test light helpers.
alteredq 12 years ago
parent
commit
136faefe20

+ 166 - 8
build/three.js

@@ -14163,8 +14163,6 @@ THREE.ShaderChunk = {
 				"vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
 				"vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
 				"vec3 lVector = lPosition.xyz - mvPosition.xyz;",
 				"vec3 lVector = lPosition.xyz - mvPosition.xyz;",
 
 
-				"lVector = normalize( lVector );",
-
 				"float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - mPosition.xyz ) );",
 				"float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - mPosition.xyz ) );",
 
 
 				"if ( spotEffect > spotLightAngle[ i ] ) {",
 				"if ( spotEffect > spotLightAngle[ i ] ) {",
@@ -14175,6 +14173,8 @@ THREE.ShaderChunk = {
 					"if ( spotLightDistance[ i ] > 0.0 )",
 					"if ( spotLightDistance[ i ] > 0.0 )",
 						"lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
 						"lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
 
 
+					"lVector = normalize( lVector );",
+
 					"float dotProduct = dot( transformedNormal, lVector );",
 					"float dotProduct = dot( transformedNormal, lVector );",
 					"vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );",
 					"vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );",
 
 
@@ -32643,9 +32643,11 @@ THREE.DirectionalLightHelper = function ( light, sphereSize, arrowLength ) {
 
 
 	this.color = light.color.clone();
 	this.color = light.color.clone();
 
 
-	this.color.r *= light.intensity;
-	this.color.g *= light.intensity;
-	this.color.b *= light.intensity;
+	var intensity = THREE.Math.clamp( light.intensity, 0, 1 );
+
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
 
 
 	var hexColor = this.color.getHex();
 	var hexColor = this.color.getHex();
 
 
@@ -32762,9 +32764,11 @@ THREE.PointLightHelper = function ( light, sphereSize ) {
 
 
 	this.color = light.color.clone();
 	this.color = light.color.clone();
 
 
-	this.color.r *= light.intensity;
-	this.color.g *= light.intensity;
-	this.color.b *= light.intensity;
+	var intensity = THREE.Math.clamp( light.intensity, 0, 1 );
+
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
 
 
 	var hexColor = this.color.getHex();
 	var hexColor = this.color.getHex();
 
 
@@ -32844,6 +32848,160 @@ THREE.PointLightHelper.prototype.update = function () {
 
 
 }
 }
 
 
+/**
+ * @author alteredq / http://alteredqualia.com/
+ *
+ *	- shows spot light color, intensity, position, orientation, light cone and target
+ */
+
+THREE.SpotLightHelper = function ( light, sphereSize, arrowLength ) {
+
+	THREE.Object3D.call( this );
+
+	this.light = light;
+
+	// position
+
+	this.position = light.position;
+
+	// direction
+
+	this.direction = new THREE.Vector3();
+	this.direction.sub( light.target.position, light.position );
+
+	// color
+
+	this.color = light.color.clone();
+
+	var intensity = THREE.Math.clamp( light.intensity, 0, 1 );
+
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
+
+	var hexColor = this.color.getHex();
+
+	// light helper
+
+	var bulbGeometry = new THREE.SphereGeometry( sphereSize, 16, 8 );
+	var raysGeometry = new THREE.AsteriskGeometry( sphereSize * 1.25, sphereSize * 2.25 );
+	var coneGeometry = new THREE.CylinderGeometry( 0.0001, 1, 1, 32, 1, true );
+
+	var coneMatrix = new THREE.Matrix4();
+	coneMatrix.rotateX( -Math.PI/2 );
+	coneMatrix.translate( new THREE.Vector3( 0, -0.5, 0 ) );
+	coneGeometry.applyMatrix( coneMatrix );
+
+	var bulbMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false } );
+	var raysMaterial = new THREE.LineBasicMaterial( { color: hexColor, fog: false } );
+	var coneMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.3, transparent: true } );
+
+	this.lightArrow = new THREE.ArrowHelper( this.direction, null, arrowLength, hexColor );
+	this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );
+	this.lightCone = new THREE.Mesh( coneGeometry, coneMaterial );
+
+	var coneLength = light.distance ? light.distance : 10000;
+	var coneWidth = coneLength * Math.tan( light.angle * 0.5 ) * 2;
+	this.lightCone.scale.set( coneWidth, coneWidth, coneLength );
+
+	this.lightArrow.cone.material.fog = false;
+	this.lightArrow.line.material.fog = false;
+
+	this.lightRays = new THREE.Line( raysGeometry, raysMaterial, THREE.LinePieces );
+
+	this.gyroscope = new THREE.Gyroscope();
+
+	this.gyroscope.add( this.lightArrow );
+	this.gyroscope.add( this.lightSphere );
+	this.gyroscope.add( this.lightRays );
+
+	this.add( this.gyroscope );
+	this.add( this.lightCone );
+
+	this.lookAt( light.target.position );
+
+	this.lightSphere.properties.isGizmo = true;
+	this.lightSphere.properties.gizmoSubject = light;
+	this.lightSphere.properties.gizmoRoot = this;
+
+	// light target helper
+
+	this.targetSphere = null;
+
+	if ( light.target.properties.targetInverse ) {
+
+		var targetGeo = new THREE.SphereGeometry( sphereSize, 8, 4 );
+		var targetMaterial = new THREE.MeshBasicMaterial( { color: hexColor, wireframe: true, fog: false } );
+
+		this.targetSphere = new THREE.Mesh( targetGeo, targetMaterial );
+		this.targetSphere.position = light.target.position;
+
+		this.targetSphere.properties.isGizmo = true;
+		this.targetSphere.properties.gizmoSubject = light.target;
+		this.targetSphere.properties.gizmoRoot = this.targetSphere;
+
+		var lineMaterial = new THREE.LineDashedMaterial( { color: hexColor, dashSize: 4, gapSize: 4, opacity: 0.75, transparent: true, fog: false } );
+		var lineGeometry = new THREE.Geometry();
+		lineGeometry.vertices.push( this.position.clone() );
+		lineGeometry.vertices.push( this.targetSphere.position.clone() );
+		lineGeometry.computeLineDistances();
+
+		this.targetLine = new THREE.Line( lineGeometry, lineMaterial );
+		this.targetLine.properties.isGizmo = true;
+
+	}
+
+	//
+
+	this.properties.isGizmo = true;
+
+}
+
+THREE.SpotLightHelper.prototype = Object.create( THREE.Object3D.prototype );
+
+THREE.SpotLightHelper.prototype.update = function () {
+
+	// update arrow orientation
+	// pointing from light to target
+
+	this.direction.sub( this.light.target.position, this.light.position );
+	this.lightArrow.setDirection( this.direction );
+
+	// update light cone orientation and size
+
+	this.lookAt( this.light.target.position );
+
+	var coneLength = this.light.distance ? this.light.distance : 10000;
+	var coneWidth = coneLength * Math.tan( this.light.angle * 0.5 ) * 2;
+	this.lightCone.scale.set( coneWidth, coneWidth, coneLength );
+
+	// update arrow, spheres, rays and line colors to light color * light intensity
+
+	this.color.copy( this.light.color );
+
+	var intensity = THREE.Math.clamp( this.light.intensity, 0, 1 );
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
+
+	this.lightArrow.setColor( this.color.getHex() );
+	this.lightSphere.material.color.copy( this.color );
+	this.lightRays.material.color.copy( this.color );
+	this.lightCone.material.color.copy( this.color );
+
+	this.targetSphere.material.color.copy( this.color );
+	this.targetLine.material.color.copy( this.color );
+
+	// update target line vertices
+
+	this.targetLine.geometry.vertices[ 0 ].copy( this.light.position );
+	this.targetLine.geometry.vertices[ 1 ].copy( this.light.target.position );
+
+	this.targetLine.geometry.computeLineDistances();
+	this.targetLine.geometry.verticesNeedUpdate = true;
+
+}
+
 /*
 /*
  *	@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog 
  *	@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog 
  * 
  * 

File diff suppressed because it is too large
+ 0 - 0
build/three.min.js


+ 1 - 1
editor/index.html

@@ -352,7 +352,7 @@
 			var geometry = new THREE.SphereGeometry( 75, 25, 15 );
 			var geometry = new THREE.SphereGeometry( 75, 25, 15 );
 
 
 			var color = Math.random() * 0xffffff;
 			var color = Math.random() * 0xffffff;
-			var material = new THREE.MeshLambertMaterial( { color: color } );
+			var material = new THREE.MeshPhongMaterial( { color: color } );
 
 
 			var mesh = new THREE.Mesh( geometry, material );
 			var mesh = new THREE.Mesh( geometry, material );
 			mesh.name = "Sphere";
 			mesh.name = "Sphere";

+ 61 - 3
editor/js/ui/Sidebar.Object3D.js

@@ -4,8 +4,9 @@ Sidebar.Object3D = function ( signals ) {
 
 
 		'PerspectiveCamera': THREE.PerspectiveCamera,
 		'PerspectiveCamera': THREE.PerspectiveCamera,
 		'AmbientLight': THREE.AmbientLight,
 		'AmbientLight': THREE.AmbientLight,
-		'PointLight': THREE.PointLight,
 		'DirectionalLight': THREE.DirectionalLight,
 		'DirectionalLight': THREE.DirectionalLight,
+		'PointLight': THREE.PointLight,
+		'SpotLight': THREE.SpotLight,
 		'Mesh': THREE.Mesh,
 		'Mesh': THREE.Mesh,
 		'Object3D': THREE.Object3D
 		'Object3D': THREE.Object3D
 
 
@@ -126,7 +127,6 @@ Sidebar.Object3D = function ( signals ) {
 
 
 	container.add( objectIntensityRow );
 	container.add( objectIntensityRow );
 
 
-
 	// color
 	// color
 
 
 	var objectColorRow = new UI.Panel();
 	var objectColorRow = new UI.Panel();
@@ -147,6 +147,26 @@ Sidebar.Object3D = function ( signals ) {
 
 
 	container.add( objectDistanceRow );
 	container.add( objectDistanceRow );
 
 
+	// angle
+
+	var objectAngleRow = new UI.Panel();
+	var objectAngle = new UI.Number( 'absolute' ).setPrecision( 3 ).setRange( 0, Math.PI * 2 ).setLeft( '100px' ).onChange( update );
+
+	objectAngleRow.add( new UI.Text().setValue( 'Angle' ).setColor( '#666' ) );
+	objectAngleRow.add( objectAngle );
+
+	container.add( objectAngleRow );
+
+	// exponent
+
+	var objectExponentRow = new UI.Panel();
+	var objectExponent = new UI.Number( 'absolute' ).setRange( 0, Infinity ).setLeft( '100px' ).onChange( update );
+
+	objectExponentRow.add( new UI.Text().setValue( 'Exponent' ).setColor( '#666' ) );
+	objectExponentRow.add( objectExponent );
+
+	container.add( objectExponentRow );
+
 	//
 	//
 
 
 	var selected = null;
 	var selected = null;
@@ -258,6 +278,18 @@ Sidebar.Object3D = function ( signals ) {
 
 
 			}
 			}
 
 
+			if ( selected.angle !== undefined ) {
+
+				selected.angle = objectAngle.getValue();
+
+			}
+
+			if ( selected.exponent !== undefined ) {
+
+				selected.exponent = objectExponent.getValue();
+
+			}
+
 			signals.objectChanged.dispatch( selected );
 			signals.objectChanged.dispatch( selected );
 
 
 		}
 		}
@@ -272,7 +304,9 @@ Sidebar.Object3D = function ( signals ) {
 			'far': objectFarRow,
 			'far': objectFarRow,
 			'intensity': objectIntensityRow,
 			'intensity': objectIntensityRow,
 			'color': objectColorRow,
 			'color': objectColorRow,
-			'distance' : objectDistanceRow
+			'distance' : objectDistanceRow,
+			'angle' : objectAngleRow,
+			'exponent' : objectExponentRow
 		};
 		};
 
 
 		for ( var property in properties ) {
 		for ( var property in properties ) {
@@ -373,6 +407,18 @@ Sidebar.Object3D = function ( signals ) {
 
 
 			}
 			}
 
 
+			if ( object.angle !== undefined ) {
+
+				objectAngle.setValue( object.angle );
+
+			}
+
+			if ( object.exponent !== undefined ) {
+
+				objectExponent.setValue( object.exponent );
+
+			}
+
 			objectVisible.setValue( object.visible );
 			objectVisible.setValue( object.visible );
 
 
 			updateRows();
 			updateRows();
@@ -463,6 +509,18 @@ Sidebar.Object3D = function ( signals ) {
 
 
 		}
 		}
 
 
+		if ( object.angle !== undefined ) {
+
+			objectAngle.setValue( object.angle );
+
+		}
+
+		if ( object.exponent !== undefined ) {
+
+			objectExponent.setValue( object.exponent );
+
+		}
+
 		objectVisible.setValue( object.visible );
 		objectVisible.setValue( object.visible );
 
 
 	}
 	}

+ 2 - 1
editor/js/ui/Sidebar.Scene.js

@@ -4,8 +4,9 @@ Sidebar.Scene = function ( signals ) {
 
 
 		'PerspectiveCamera': THREE.PerspectiveCamera,
 		'PerspectiveCamera': THREE.PerspectiveCamera,
 		'AmbientLight': THREE.AmbientLight,
 		'AmbientLight': THREE.AmbientLight,
-		'PointLight': THREE.PointLight,
 		'DirectionalLight': THREE.DirectionalLight,
 		'DirectionalLight': THREE.DirectionalLight,
+		'PointLight': THREE.PointLight,
+		'SpotLight': THREE.SpotLight,
 		'Mesh': THREE.Mesh,
 		'Mesh': THREE.Mesh,
 		'Object3D': THREE.Object3D
 		'Object3D': THREE.Object3D
 
 

+ 20 - 10
editor/js/ui/Viewport.js

@@ -59,8 +59,8 @@ var Viewport = function ( signals ) {
 	var light1 = new THREE.DirectionalLight( 0xffffff );
 	var light1 = new THREE.DirectionalLight( 0xffffff );
 	light1.position.set( 1, 0.5, 0 ).multiplyScalar( 400 );
 	light1.position.set( 1, 0.5, 0 ).multiplyScalar( 400 );
 
 
-	var light2 = new THREE.DirectionalLight( 0xffffff, 0.5 );
-	light2.position.set( - 1, - 0.5, 0 ).multiplyScalar( 400 );
+	var light2 = new THREE.SpotLight( 0xffffff, 1.5, 500, Math.PI * 0.025 );
+	light2.position.set( - 1, 0.5, 1 ).multiplyScalar( 300 );
 
 
 	light1.target.properties.targetInverse = light1;
 	light1.target.properties.targetInverse = light1;
 	light2.target.properties.targetInverse = light2;
 	light2.target.properties.targetInverse = light2;
@@ -347,8 +347,21 @@ var Viewport = function ( signals ) {
 
 
 		} else if ( object instanceof THREE.SpotLight ) {
 		} else if ( object instanceof THREE.SpotLight ) {
 
 
-			//var lightGizmo = new THREE.SpotLightHelper( object );
-			//sceneHelpers.add( lightGizmo );
+			var sphereSize = 5;
+			var arrowLength = 30;
+
+			var lightGizmo = new THREE.SpotLightHelper( object, sphereSize, arrowLength );
+			sceneHelpers.add( lightGizmo );
+			sceneHelpers.add( lightGizmo.targetSphere );
+			sceneHelpers.add( lightGizmo.targetLine );
+
+			object.properties.helper = lightGizmo;
+			object.properties.pickingProxy = lightGizmo.lightSphere;
+			object.target.properties.pickingProxy = lightGizmo.targetSphere;
+
+			objects.push( lightGizmo.lightSphere );
+			objects.push( lightGizmo.targetSphere );
+			objects.push( lightGizmo.targetLine );
 
 
 		} else if ( object instanceof THREE.HemisphereLight ) {
 		} else if ( object instanceof THREE.HemisphereLight ) {
 
 
@@ -379,15 +392,12 @@ var Viewport = function ( signals ) {
 
 
 			object.updateProjectionMatrix();
 			object.updateProjectionMatrix();
 
 
-		} else if ( object instanceof THREE.DirectionalLight ) {
+		} else if ( object instanceof THREE.DirectionalLight ||
+					object instanceof THREE.PointLight ||
+					object instanceof THREE.SpotLight ) {
 
 
 			object.properties.helper.update();
 			object.properties.helper.update();
 
 
-		} else if ( object instanceof THREE.PointLight ) {
-
-			object.properties.helper.update();
-
-		} else if ( object instanceof THREE.SpotLight ) {
 		} else if ( object instanceof THREE.HemisphereLight ) {
 		} else if ( object instanceof THREE.HemisphereLight ) {
 		} else if ( object.properties.targetInverse ) {
 		} else if ( object.properties.targetInverse ) {
 
 

+ 5 - 3
src/extras/helpers/PointLightHelper.js

@@ -18,9 +18,11 @@ THREE.PointLightHelper = function ( light, sphereSize ) {
 
 
 	this.color = light.color.clone();
 	this.color = light.color.clone();
 
 
-	this.color.r *= light.intensity;
-	this.color.g *= light.intensity;
-	this.color.b *= light.intensity;
+	var intensity = THREE.Math.clamp( light.intensity, 0, 1 );
+
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
 
 
 	var hexColor = this.color.getHex();
 	var hexColor = this.color.getHex();
 
 

+ 154 - 0
src/extras/helpers/SpotLightHelper.js

@@ -0,0 +1,154 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ *
+ *	- shows spot light color, intensity, position, orientation, light cone and target
+ */
+
+THREE.SpotLightHelper = function ( light, sphereSize, arrowLength ) {
+
+	THREE.Object3D.call( this );
+
+	this.light = light;
+
+	// position
+
+	this.position = light.position;
+
+	// direction
+
+	this.direction = new THREE.Vector3();
+	this.direction.sub( light.target.position, light.position );
+
+	// color
+
+	this.color = light.color.clone();
+
+	var intensity = THREE.Math.clamp( light.intensity, 0, 1 );
+
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
+
+	var hexColor = this.color.getHex();
+
+	// light helper
+
+	var bulbGeometry = new THREE.SphereGeometry( sphereSize, 16, 8 );
+	var raysGeometry = new THREE.AsteriskGeometry( sphereSize * 1.25, sphereSize * 2.25 );
+	var coneGeometry = new THREE.CylinderGeometry( 0.0001, 1, 1, 32, 1, true );
+
+	var coneMatrix = new THREE.Matrix4();
+	coneMatrix.rotateX( -Math.PI/2 );
+	coneMatrix.translate( new THREE.Vector3( 0, -0.5, 0 ) );
+	coneGeometry.applyMatrix( coneMatrix );
+
+	var bulbMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false } );
+	var raysMaterial = new THREE.LineBasicMaterial( { color: hexColor, fog: false } );
+	var coneMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.3, transparent: true } );
+
+	this.lightArrow = new THREE.ArrowHelper( this.direction, null, arrowLength, hexColor );
+	this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );
+	this.lightCone = new THREE.Mesh( coneGeometry, coneMaterial );
+
+	var coneLength = light.distance ? light.distance : 10000;
+	var coneWidth = coneLength * Math.tan( light.angle * 0.5 ) * 2;
+	this.lightCone.scale.set( coneWidth, coneWidth, coneLength );
+
+	this.lightArrow.cone.material.fog = false;
+	this.lightArrow.line.material.fog = false;
+
+	this.lightRays = new THREE.Line( raysGeometry, raysMaterial, THREE.LinePieces );
+
+	this.gyroscope = new THREE.Gyroscope();
+
+	this.gyroscope.add( this.lightArrow );
+	this.gyroscope.add( this.lightSphere );
+	this.gyroscope.add( this.lightRays );
+
+	this.add( this.gyroscope );
+	this.add( this.lightCone );
+
+	this.lookAt( light.target.position );
+
+	this.lightSphere.properties.isGizmo = true;
+	this.lightSphere.properties.gizmoSubject = light;
+	this.lightSphere.properties.gizmoRoot = this;
+
+	// light target helper
+
+	this.targetSphere = null;
+
+	if ( light.target.properties.targetInverse ) {
+
+		var targetGeo = new THREE.SphereGeometry( sphereSize, 8, 4 );
+		var targetMaterial = new THREE.MeshBasicMaterial( { color: hexColor, wireframe: true, fog: false } );
+
+		this.targetSphere = new THREE.Mesh( targetGeo, targetMaterial );
+		this.targetSphere.position = light.target.position;
+
+		this.targetSphere.properties.isGizmo = true;
+		this.targetSphere.properties.gizmoSubject = light.target;
+		this.targetSphere.properties.gizmoRoot = this.targetSphere;
+
+		var lineMaterial = new THREE.LineDashedMaterial( { color: hexColor, dashSize: 4, gapSize: 4, opacity: 0.75, transparent: true, fog: false } );
+		var lineGeometry = new THREE.Geometry();
+		lineGeometry.vertices.push( this.position.clone() );
+		lineGeometry.vertices.push( this.targetSphere.position.clone() );
+		lineGeometry.computeLineDistances();
+
+		this.targetLine = new THREE.Line( lineGeometry, lineMaterial );
+		this.targetLine.properties.isGizmo = true;
+
+	}
+
+	//
+
+	this.properties.isGizmo = true;
+
+}
+
+THREE.SpotLightHelper.prototype = Object.create( THREE.Object3D.prototype );
+
+THREE.SpotLightHelper.prototype.update = function () {
+
+	// update arrow orientation
+	// pointing from light to target
+
+	this.direction.sub( this.light.target.position, this.light.position );
+	this.lightArrow.setDirection( this.direction );
+
+	// update light cone orientation and size
+
+	this.lookAt( this.light.target.position );
+
+	var coneLength = this.light.distance ? this.light.distance : 10000;
+	var coneWidth = coneLength * Math.tan( this.light.angle * 0.5 ) * 2;
+	this.lightCone.scale.set( coneWidth, coneWidth, coneLength );
+
+	// update arrow, spheres, rays and line colors to light color * light intensity
+
+	this.color.copy( this.light.color );
+
+	var intensity = THREE.Math.clamp( this.light.intensity, 0, 1 );
+	this.color.r *= intensity;
+	this.color.g *= intensity;
+	this.color.b *= intensity;
+
+	this.lightArrow.setColor( this.color.getHex() );
+	this.lightSphere.material.color.copy( this.color );
+	this.lightRays.material.color.copy( this.color );
+	this.lightCone.material.color.copy( this.color );
+
+	this.targetSphere.material.color.copy( this.color );
+	this.targetLine.material.color.copy( this.color );
+
+	// update target line vertices
+
+	this.targetLine.geometry.vertices[ 0 ].copy( this.light.position );
+	this.targetLine.geometry.vertices[ 1 ].copy( this.light.target.position );
+
+	this.targetLine.geometry.computeLineDistances();
+	this.targetLine.geometry.verticesNeedUpdate = true;
+
+}
+

+ 2 - 2
src/renderers/WebGLShaders.js

@@ -606,8 +606,6 @@ THREE.ShaderChunk = {
 				"vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
 				"vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
 				"vec3 lVector = lPosition.xyz - mvPosition.xyz;",
 				"vec3 lVector = lPosition.xyz - mvPosition.xyz;",
 
 
-				"lVector = normalize( lVector );",
-
 				"float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - mPosition.xyz ) );",
 				"float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - mPosition.xyz ) );",
 
 
 				"if ( spotEffect > spotLightAngle[ i ] ) {",
 				"if ( spotEffect > spotLightAngle[ i ] ) {",
@@ -618,6 +616,8 @@ THREE.ShaderChunk = {
 					"if ( spotLightDistance[ i ] > 0.0 )",
 					"if ( spotLightDistance[ i ] > 0.0 )",
 						"lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
 						"lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
 
 
+					"lVector = normalize( lVector );",
+
 					"float dotProduct = dot( transformedNormal, lVector );",
 					"float dotProduct = dot( transformedNormal, lVector );",
 					"vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );",
 					"vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );",
 
 

+ 1 - 0
utils/includes/extras.json

@@ -39,6 +39,7 @@
 	"../src/extras/helpers/CameraHelper.js",
 	"../src/extras/helpers/CameraHelper.js",
 	"../src/extras/helpers/DirectionalLightHelper.js",
 	"../src/extras/helpers/DirectionalLightHelper.js",
 	"../src/extras/helpers/PointLightHelper.js",
 	"../src/extras/helpers/PointLightHelper.js",
+	"../src/extras/helpers/SpotLightHelper.js",
 	"../src/extras/modifiers/SubdivisionModifier.js",
 	"../src/extras/modifiers/SubdivisionModifier.js",
 	"../src/extras/objects/ImmediateRenderObject.js",
 	"../src/extras/objects/ImmediateRenderObject.js",
 	"../src/extras/objects/LensFlare.js",
 	"../src/extras/objects/LensFlare.js",

+ 1 - 0
utils/includes/webgl.json

@@ -79,6 +79,7 @@
 	"../src/extras/helpers/CameraHelper.js",
 	"../src/extras/helpers/CameraHelper.js",
 	"../src/extras/helpers/DirectionalLightHelper.js",
 	"../src/extras/helpers/DirectionalLightHelper.js",
 	"../src/extras/helpers/PointLightHelper.js",
 	"../src/extras/helpers/PointLightHelper.js",
+	"../src/extras/helpers/SpotLightHelper.js",
 	"../src/extras/objects/LensFlare.js",
 	"../src/extras/objects/LensFlare.js",
 	"../src/extras/objects/ImmediateRenderObject.js",
 	"../src/extras/objects/ImmediateRenderObject.js",
 	"../src/extras/renderers/plugins/LensFlarePlugin.js",
 	"../src/extras/renderers/plugins/LensFlarePlugin.js",

Some files were not shown because too many files changed in this diff