Browse Source

Moved the rest of deferred pipeline from examples into DeferredHelper.

Another step towards WebGLDeferredRenderer. It's still quite a mess but at least now code lives outside of the examples (and is reusable, to a degree).
alteredq 12 years ago
parent
commit
19df092da9

+ 252 - 12
examples/js/DeferredHelper.js

@@ -1,5 +1,6 @@
 /**
  * @author alteredq / http://alteredqualia.com/
+ * @author MPanknin / http://www.redplant.de/
  */
 
 THREE.DeferredHelper = function ( parameters ) {
@@ -7,6 +8,24 @@ THREE.DeferredHelper = function ( parameters ) {
 	var width = parameters.width;
 	var height = parameters.height;
 
+	var scene = parameters.scene;
+	var camera = parameters.camera;
+	var renderer = parameters.renderer;
+
+	// scene for light proxy geometry
+
+	var lightScene = new THREE.Scene();
+	lightNode = new THREE.Object3D();
+	lightScene.add( lightNode );
+
+	// scene for the coloured emitter spheres
+
+	var emitterScene = new THREE.Scene();
+	emitterNode = new THREE.Object3D();
+	emitterScene.add( emitterNode );
+
+	//
+
 	var black = new THREE.Color( 0x000000 );
 
 	var colorShader = THREE.ShaderDeferred[ "color" ];
@@ -14,17 +33,25 @@ THREE.DeferredHelper = function ( parameters ) {
 	var bumpShader = THREE.ShaderDeferred[ "bump" ];
 	var clipDepthShader = THREE.ShaderDeferred[ "clipDepth" ];
 
-	this.unlitShader = THREE.ShaderDeferred[ "unlit" ];
-	this.lightShader = THREE.ShaderDeferred[ "light" ];
-	this.compositeShader = THREE.ShaderDeferred[ "composite" ];
+	//
 
-	this.unlitShader.uniforms[ "viewWidth" ].value = width;
-	this.unlitShader.uniforms[ "viewHeight" ].value = height;
+	var unlitShader = THREE.ShaderDeferred[ "unlit" ];
+	var lightShader = THREE.ShaderDeferred[ "light" ];
+	var compositeShader = THREE.ShaderDeferred[ "composite" ];
 
-	this.lightShader.uniforms[ "viewWidth" ].value = width;
-	this.lightShader.uniforms[ "viewHeight" ].value = height;
+	unlitShader.uniforms[ "viewWidth" ].value = width;
+	unlitShader.uniforms[ "viewHeight" ].value = height;
 
-	var matNormal = new THREE.ShaderMaterial( {
+	lightShader.uniforms[ "viewWidth" ].value = width;
+	lightShader.uniforms[ "viewHeight" ].value = height;
+
+	//
+
+	var compColor, compNormal, compDepth, compLightBuffer, compFinal, compEmitter, compositePass;
+
+	//
+
+	var defaultNormalMaterial = new THREE.ShaderMaterial( {
 
 		uniforms:       THREE.UniformsUtils.clone( normalShader.uniforms ),
 		vertexShader:   normalShader.vertexShader,
@@ -32,7 +59,7 @@ THREE.DeferredHelper = function ( parameters ) {
 
 	} );
 
-	var matClipDepth = new THREE.ShaderMaterial( {
+	var defaultDepthMaterial = new THREE.ShaderMaterial( {
 
 		uniforms:       THREE.UniformsUtils.clone( clipDepthShader.uniforms ),
 		vertexShader:   clipDepthShader.vertexShader,
@@ -40,6 +67,19 @@ THREE.DeferredHelper = function ( parameters ) {
 
 	} );
 
+	//
+
+	var rtParamsFloatLinear = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
+								format: THREE.RGBAFormat, type: THREE.FloatType };
+
+	var rtParamsFloatNearest = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: false,
+								 format: THREE.RGBAFormat, type: THREE.FloatType };
+
+	var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
+						  format: THREE.RGBFormat, type: THREE.UnsignedByteType };
+
+	//
+
 	this.addDeferredMaterials = function ( object ) {
 
 		object.traverse( function( node ) {
@@ -144,7 +184,7 @@ THREE.DeferredHelper = function ( parameters ) {
 
 			} else {
 
-				node.properties.normalMaterial = matNormal;
+				node.properties.normalMaterial = defaultNormalMaterial;
 
 			}
 
@@ -166,12 +206,212 @@ THREE.DeferredHelper = function ( parameters ) {
 
 			} else {
 
-				node.properties.depthMaterial = matClipDepth;
+				node.properties.depthMaterial = defaultDepthMaterial;
 
 			}
 
 		} );
 
-	}
+	};
+
+	this.createRenderTargets = function ( ) {
+
+		// g-buffers
+
+		var rtColor   = new THREE.WebGLRenderTarget( width, height, rtParamsFloatNearest );
+		var rtNormal  = new THREE.WebGLRenderTarget( width, height, rtParamsFloatLinear );
+		var rtDepth   = new THREE.WebGLRenderTarget( width, height, rtParamsFloatLinear );
+		var rtLight   = new THREE.WebGLRenderTarget( width, height, rtParamsFloatLinear );
+		var rtEmitter = new THREE.WebGLRenderTarget( width, height, rtParamsUByte );
+		var rtFinal   = new THREE.WebGLRenderTarget( width, height, rtParamsUByte );
+
+		rtColor.generateMipmaps = false;
+		rtNormal.generateMipmaps = false;
+		rtDepth.generateMipmaps = false;
+		rtLight.generateMipmaps = false;
+		rtEmitter.generateMipmaps = false;
+		rtFinal.generateMipmaps = false;
+
+		// composers
+
+		var passColor = new THREE.RenderPass( scene, camera );
+		compColor = new THREE.EffectComposer( renderer, rtColor );
+		compColor.addPass( passColor );
+
+		var passNormal = new THREE.RenderPass( scene, camera );
+		compNormal = new THREE.EffectComposer( renderer, rtNormal );
+		compNormal.addPass( passNormal );
+
+		var passDepth = new THREE.RenderPass( scene, camera );
+		compDepth = new THREE.EffectComposer( renderer, rtDepth );
+		compDepth.addPass( passDepth );
+
+		var passEmitter = new THREE.RenderPass( emitterScene, camera );
+		compEmitter = new THREE.EffectComposer( renderer, rtEmitter );
+		compEmitter.addPass( passEmitter );
+
+		var passLight = new THREE.RenderPass( lightScene, camera );
+		compLightBuffer = new THREE.EffectComposer( renderer, rtLight );
+		compLightBuffer.addPass( passLight );
+
+		//
+
+		lightShader.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
+		lightShader.uniforms[ 'samplerNormals' ].value = compNormal.renderTarget2;
+		lightShader.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
+		lightShader.uniforms[ 'samplerLightBuffer' ].value = rtLight;
+
+		compositeShader.uniforms[ 'samplerLightBuffer' ].value = compLightBuffer.renderTarget2;
+		compositeShader.uniforms[ 'samplerEmitter' ].value = compEmitter.renderTarget2;
+
+		// composite
+
+		var compositePass = new THREE.ShaderPass( compositeShader );
+		compositePass.needsSwap = true;
+
+		var effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
+		effectFXAA.uniforms[ 'resolution' ].value.set( 1 / width, 1 / height );
+
+		var effectColor = new THREE.ShaderPass( THREE.ColorCorrectionShader );
+		effectColor.renderToScreen = true;
+
+		effectColor.uniforms[ 'powRGB' ].value.set( 1, 1, 1 );
+		effectColor.uniforms[ 'mulRGB' ].value.set( 2, 2, 2 );
+
+		compFinal = new THREE.EffectComposer( renderer, rtFinal );
+		compFinal.addPass( compositePass );
+		compFinal.addPass( effectFXAA );
+		compFinal.addPass( effectColor );
+
+	};
+
+	this.addDeferredLights = function ( lights, additiveSpecular ) {
+
+		var geometryEmitter = new THREE.SphereGeometry( 0.7, 7, 7 );
+
+		for ( var i = 0, il = lights.length; i < il; i ++ ) {
+
+			var light = lights[ i ];
+
+			// setup material
+
+			var materialLight = new THREE.ShaderMaterial( {
+
+				uniforms:       THREE.UniformsUtils.clone( lightShader.uniforms ),
+				vertexShader:   lightShader.vertexShader,
+				fragmentShader: lightShader.fragmentShader,
+				defines:		{ "ADDITIVE_SPECULAR": additiveSpecular },
+
+				blending:		THREE.AdditiveBlending,
+				depthWrite:		false,
+				transparent:	true
+
+			} );
+
+			materialLight.uniforms[ "lightPos" ].value = light.position;
+			materialLight.uniforms[ "lightRadius" ].value = light.distance;
+			materialLight.uniforms[ "lightIntensity" ].value = light.intensity;
+			materialLight.uniforms[ "lightColor" ].value = light.color;
+
+			// setup proxy geometry for this light
+
+			var geometryLight = new THREE.SphereGeometry( light.distance, 16, 8 );
+			var meshLight = new THREE.Mesh( geometryLight, materialLight );
+			meshLight.position = light.position;
+			lightNode.add( meshLight );
+
+			// create emitter sphere
+
+			var matEmitter = new THREE.ShaderMaterial( {
+
+				uniforms:       THREE.UniformsUtils.clone( unlitShader.uniforms ),
+				vertexShader:   unlitShader.vertexShader,
+				fragmentShader: unlitShader.fragmentShader
+
+			} );
+
+			matEmitter.uniforms[ "samplerDepth" ].value = compDepth.renderTarget2;
+			matEmitter.uniforms[ "lightColor" ].value = light.color;
+
+			var meshEmitter = new THREE.Mesh( geometryEmitter, matEmitter );
+			meshEmitter.position = light.position;
+			emitterNode.add( meshEmitter );
+
+			// add emitter to light node
+
+			meshLight.properties.emitter = meshEmitter;
+
+		}
+
+	};
+
+	this.render = function () {
+
+		// -----------------------------
+		// g-buffer color
+		// -----------------------------
+
+		scene.traverse( function( node ) {
+
+			if ( node.material ) node.material = node.properties.colorMaterial;
+
+		} );
+
+		compColor.render();
+
+		// -----------------------------
+		// g-buffer depth
+		// -----------------------------
+
+		scene.traverse( function( node ) {
+
+			if ( node.material ) node.material = node.properties.depthMaterial;
+
+		} );
+
+		compDepth.render();
+
+		// -----------------------------
+		// g-buffer normals
+		// -----------------------------
+
+		scene.traverse( function( node ) {
+
+			if ( node.material ) node.material = node.properties.normalMaterial;
+
+		} );
+
+		compNormal.render();
+
+		// -----------------------------
+		// emitter pass
+		// -----------------------------
+
+		compEmitter.render();
+
+		// -----------------------------
+		// light pass
+		// -----------------------------
+
+		camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
+
+		for ( var i = 0, il = lightNode.children.length; i < il; i ++ ) {
+
+			var uniforms = lightNode.children[ i ].material.uniforms;
+
+			uniforms[ "matProjInverse" ].value = camera.projectionMatrixInverse;
+			uniforms[ "matView" ].value = camera.matrixWorldInverse;
+
+		}
+
+		compLightBuffer.render();
+
+		// -----------------------------
+		// composite pass
+		// -----------------------------
+
+		compFinal.render( 0.1 );
+
+	};
 
 };

+ 2 - 2
examples/js/ShaderDeferred.js

@@ -267,7 +267,7 @@ THREE.ShaderDeferred = {
 			samplerDepth: { type: "t", value: null },
 			viewWidth:    { type: "f", value: 800 },
 			viewHeight:   { type: "f", value: 600 },
-			lightColor:   { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) }
+			lightColor:   { type: "c", value: new THREE.Color( 0x000000 ) }
 
 		},
 
@@ -373,7 +373,7 @@ THREE.ShaderDeferred = {
 			viewWidth: 		{ type: "f", value: 800 },
 			viewHeight: 	{ type: "f", value: 600 },
 			lightPos: 		{ type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
-			lightColor: 	{ type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
+			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
 			lightIntensity: { type: "f", value: 1.0 },
 			lightRadius: 	{ type: "f", value: 1.0 }
 

+ 116 - 383
examples/webgl_lights_deferred_morphs.html

@@ -63,9 +63,6 @@
 		<script src="js/postprocessing/ShaderPass.js"></script>
 		<script src="js/postprocessing/MaskPass.js"></script>
 
-		<script src="js/controls/TrackballControls.js"></script>
-
-
 		<script>
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
@@ -83,6 +80,8 @@
 			var VIEW_ANGLE = 45;
 			var ASPECT = WIDTH / HEIGHT;
 
+			// controls
+
 			var mouseX = 0;
 			var mouseY = 0;
 
@@ -90,39 +89,32 @@
 			var angle = 0;
 			var target = new THREE.Vector3( 0, 0, 0 );
 
-
 			var windowHalfX = window.innerWidth / 2;
 			var windowHalfY = window.innerHeight / 2;
 
 			// core
 
-			var renderer, camera, controls, stats, clock;
-
-			// scenes and scene nodes
-
-			var lightScene, lightNode, scene, sceneNode, emitterScene, emitterNode, quadScene, quadNode;
-
-			// rendertargets
-
-			var rtColor, rtNormals, rtDepth, rtLight, rtEmitter, rtFinal;
-
-			// composer
-
-			var compColor, compNormals, compDepth, compLightBuffer, compFinal, compEmitter, compositePass;
-			var effectFXAA;
+			var renderer, camera, scene, controls, stats, clock;
 
 			// lights
 
 			var numLights = 50;
-			var lights = new Array();
+			var lights = [];
 
 			// morphs
 
 			var morphs = [];
 
+			//
+
+			init();
+			animate();
+
 			// -----------------------------
 
-			function bootstrap() {
+			function init() {
+
+				// renderer
 
 				renderer = new THREE.WebGLRenderer( { alpha: false } );
 				renderer.setSize( WIDTH, HEIGHT );
@@ -135,39 +127,16 @@
 				var container = document.getElementById( 'container' );
 				container.appendChild( renderer.domElement );
 
-				// scene camera
+				// camera
 
 				camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
 				camera.position.z = 150;
 
-				controls = new THREE.TrackballControls( camera, renderer.domElement );
-
-				// scene for walt's head model
+				// scene
 
 				scene = new THREE.Scene();
-				sceneNode = new THREE.Object3D();
-				scene.add( sceneNode );
 				scene.add( camera );
 
-				// scene for light proxy geometry
-
-				lightScene = new THREE.Scene();
-				lightNode = new THREE.Object3D();
-				lightScene.add( lightNode );
-
-				// scene for the coloured emitter spheres
-
-				emitterScene = new THREE.Scene();
-				emitterNode = new THREE.Object3D();
-				emitterScene.add( emitterNode );
-
-				// full screen quad for compositing
-
-				quadScene = new THREE.Scene();
-				quadNode = new THREE.Object3D();
-				quadScene.add( quadNode );
-				quadNode.add( new THREE.Mesh( new THREE.PlaneGeometry( 1, 1 ) ) );
-
 				// stats
 
 				stats = new Stats();
@@ -182,161 +151,33 @@
 
 				// deferred helper
 
-				deferredHelper = new THREE.DeferredHelper( { width: SCALED_WIDTH, height: SCALED_HEIGHT } );
-
-			}
-
-			// -----------------------------
-
-			function createRenderTargets() {
-
-				var rtParamsFloatLinear = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
-										    format: THREE.RGBAFormat, type: THREE.FloatType };
-
-				var rtParamsFloatNearest = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: false,
-											 format: THREE.RGBAFormat, type: THREE.FloatType };
-
-				var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
-							          format: THREE.RGBFormat, type: THREE.UnsignedByteType };
+				deferredHelper = new THREE.DeferredHelper( { renderer: renderer, scene: scene, camera: camera, width: SCALED_WIDTH, height: SCALED_HEIGHT } );
+				deferredHelper.createRenderTargets();
 
-				// ----------------------------------------------------------
-				// g-buffer
-				// ----------------------------------------------------------
+				// add lights
 
-				rtNormals = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
-				rtDepth   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
-				rtColor   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatNearest );
-				rtLight   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
-				rtEmitter = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsUByte );
-				rtFinal   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsUByte );
+				initLights();
 
-				rtNormals.generateMipmaps = false;
-				rtDepth.generateMipmaps = false;
-				rtColor.generateMipmaps = false;
-				rtLight.generateMipmaps = false;
-				rtEmitter.generateMipmaps = false;
-				rtFinal.generateMipmaps = false;
-
-				var passNormals = new THREE.RenderPass( scene, camera );
-				compNormals = new THREE.EffectComposer( renderer, rtNormals );
-				compNormals.addPass( passNormals );
-
-				var passDepth = new THREE.RenderPass( scene, camera );
-				compDepth = new THREE.EffectComposer( renderer, rtDepth );
-				compDepth.addPass( passDepth );
-
-				var passColor = new THREE.RenderPass( scene, camera );
-				compColor = new THREE.EffectComposer( renderer, rtColor );
-				compColor.addPass( passColor );
-
-				// ----------------------------------------------------------
-				// light emitter spheres
-				// ----------------------------------------------------------
-
-				var emitterPass = new THREE.RenderPass( emitterScene, camera );
-
-				compEmitter = new THREE.EffectComposer( renderer, rtEmitter );
-				compEmitter.addPass( emitterPass );
-
-				// ----------------------------------------------------------
-				// lighting pass
-				// ----------------------------------------------------------
-
-				var passLight = new THREE.RenderPass( lightScene, camera );
-				compLightBuffer = new THREE.EffectComposer( renderer, rtLight );
-				compLightBuffer.addPass( passLight );
-
-				deferredHelper.lightShader.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-				deferredHelper.lightShader.uniforms[ 'samplerNormals' ].value = compNormals.renderTarget2;
-				deferredHelper.lightShader.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
-				deferredHelper.lightShader.uniforms[ 'samplerLightBuffer' ].value = rtLight;
-
-				var geomEmitter = new THREE.SphereGeometry( 0.7, 7, 7 );
-
-				for ( var x = 0; x < numLights; x ++ ) {
-
-					var light = lights[ x ];
-
-					// setup material
-
-					var matLight = new THREE.ShaderMaterial( {
-
-						uniforms:       THREE.UniformsUtils.clone( deferredHelper.lightShader.uniforms ),
-						vertexShader:   deferredHelper.lightShader.vertexShader,
-						fragmentShader: deferredHelper.lightShader.fragmentShader,
-						defines:		{ "ADDITIVE_SPECULAR": true },
-
-						blending:		THREE.AdditiveBlending,
-						depthWrite:		false,
-						transparent:	true
-
-					} );
-
-					matLight.uniforms[ "lightPos" ].value = light.position;
-					matLight.uniforms[ "lightRadius" ].value = light.distance;
-					matLight.uniforms[ "lightIntensity" ].value = light.intensity;
-					matLight.uniforms[ "lightColor" ].value = light.color;
-
-					// setup proxy geometry for this light
-
-					var geomLight = new THREE.SphereGeometry( light.distance, 16, 8 );
-					var meshLight = new THREE.Mesh( geomLight, matLight );
-					lightNode.add( meshLight );
-
-					// create emitter sphere
-
-					var matEmitter = new THREE.ShaderMaterial( {
-
-						uniforms:       THREE.UniformsUtils.clone( deferredHelper.unlitShader.uniforms ),
-						vertexShader:   deferredHelper.unlitShader.vertexShader,
-						fragmentShader: deferredHelper.unlitShader.fragmentShader
-
-					} );
-
-					var meshEmitter = new THREE.Mesh( geomEmitter, matEmitter );
-					meshEmitter.position = light.position;
-					emitterNode.add( meshEmitter );
-
-					// add emitter to light node
-
-					meshLight.emitter = meshEmitter;
-
-				}
+				// add objects
 
-				// ----------------------------------------------------------
-				// composite
-				// ----------------------------------------------------------
+				initObjects();
 
-				deferredHelper.compositeShader.uniforms[ 'samplerLightBuffer' ].value = compLightBuffer.renderTarget2;
-				deferredHelper.compositeShader.uniforms[ 'samplerEmitter' ].value = compEmitter.renderTarget2;
+				// events
 
-				compositePass = new THREE.ShaderPass( deferredHelper.compositeShader );
-				compositePass.needsSwap = true;
-
-				effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
-				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / SCALED_WIDTH, 1 / SCALED_HEIGHT );
-
-				var effectColor = new THREE.ShaderPass( THREE.ColorCorrectionShader );
-				effectColor.renderToScreen = true;
-				effectColor.uniforms[ 'powRGB' ].value.set( 1, 1, 1 );
-				effectColor.uniforms[ 'mulRGB' ].value.set( 2, 2, 2 );
-
-				compFinal = new THREE.EffectComposer( renderer, rtFinal );
-				compFinal.addPass( compositePass );
-				compFinal.addPass( effectFXAA );
-				compFinal.addPass( effectColor );
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 
 			}
 
+
 			// -----------------------------
 
-			function initScene( object, y, scale ) {
+			function addObject( object, y, scale ) {
 
 				deferredHelper.addDeferredMaterials( object );
 
 				object.position.y = y;
 				object.scale.set( scale, scale, scale );
-				sceneNode.add( object );
+				scene.add( object );
 
 			}
 
@@ -348,212 +189,66 @@
 
 				// front light
 
-				var light = new THREE.PointLight();
-
-				light.color = new THREE.Vector3( 1, 1, 1 );
-				light.intensity = 1.5;
-				light.distance = 1.5 * distance;
-
+				var light = new THREE.PointLight( 0xffffff, 1.5, 1.5 * distance );
 				lights.push( light );
 
 				// random lights
 
-				for ( var i = 1; i < numLights; i ++ ) {
-
-					var light = new THREE.PointLight();
+				var c = new THREE.Vector3();
 
-					light.color = new THREE.Vector3( Math.random(), Math.random(), Math.random() ).normalize();
+				for ( var i = 1; i < numLights; i ++ ) {
 
-					// gamma to linear
+					var light = new THREE.PointLight( 0xffffff, 2.0, distance );
 
-					light.color.x *= light.color.x;
-					light.color.y *= light.color.y;
-					light.color.z *= light.color.z;
+					c.set( Math.random(), Math.random(), Math.random() ).normalize();
 
-					light.intensity = 2.0;
-					light.distance = distance;
+					light.color.setRGB( c.x, c.y, c.z );
+					light.color.convertGammaToLinear();
 
 					lights.push( light );
 
 				}
 
-			}
-
-			// -----------------------------
-
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 1;
-				mouseY = ( event.clientY - windowHalfY ) * 1;
+				deferredHelper.addDeferredLights( lights, true );
 
 			}
 
-			// -----------------------------
+			function initObjects() {
 
-			function animate() {
+				// add animated model
 
-				var delta = clock.getDelta();
-
-				requestAnimationFrame( animate );
+				var loader = new THREE.JSONLoader();
+				loader.load( "models/animated/elderlyWalk.js", function( geometry ) {
 
-				//controls.update( delta );
+					geometry.computeMorphNormals();
 
-				targetX = mouseX * .001;
-				targetY = mouseY * .001;
+					var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x333333, shininess: 20, morphTargets: true, morphNormals: true, vertexColors: THREE.NoColors, shading: THREE.FlatShading } );
+					var meshAnim = new THREE.MorphAnimMesh( geometry, material );
 
-				angle += 0.05 * ( targetX - angle );
+					meshAnim.duration = 3000;
+					meshAnim.properties.delta = -13;
 
-				camera.position.x = -Math.sin( angle ) * 150;
-				camera.position.z = Math.cos( angle ) * 150;
+					var s = 1;
+					meshAnim.scale.set( s, s, s );
+					meshAnim.position.x = 180;
+					meshAnim.position.z = -10;
+					meshAnim.rotation.y = -Math.PI/2;
 
-				camera.lookAt( target );
+					morphs.push( meshAnim );
 
-				for ( var i = 0; i < morphs.length; i ++ ) {
+					addObject( meshAnim, -48, 50 );
 
-					morph = morphs[ i ];
-					morph.updateAnimation( 1000 * delta );
-
-					morph.position.x += morph.properties.delta * delta;
-					if ( morph.position.x < -50 ) morph.position.x = 200;
+				} );
 
-				}
+				// add box
 
-				stats.update();
-				render();
+				var object = generateBox();
+				addObject( object, 0, 8 );
 
 			}
 
 			// -----------------------------
 
-			function render() {
-
-				// -----------------------------
-				// g-buffer color
-				// -----------------------------
-
-				sceneNode.traverse( function( node ) {
-
-					if ( node.material ) {
-
-						node.material = node.properties.colorMaterial;
-
-					}
-
-				} );
-
-				compColor.render();
-
-
-				// -----------------------------
-				// g-buffer depth
-				// -----------------------------
-
-				sceneNode.traverse( function( node ) {
-
-					if ( node.material ) {
-
-						node.material = node.properties.depthMaterial;
-
-					}
-
-				} );
-
-				compDepth.render();
-
-
-				// -----------------------------
-				// g-buffer normals
-				// -----------------------------
-
-				sceneNode.traverse( function( node ) {
-
-					if ( node.material ) {
-
-						node.material = node.properties.normalMaterial;
-
-					}
-
-				} );
-
-				compNormals.render();
-
-				// -----------------------------
-				// emitter pass
-				// -----------------------------
-
-				for ( var i = 0, il = lightNode.children.length; i < il; i ++ ) {
-
-					var light = lightNode.children[ i ];
-					var color = light.material.uniforms[ "lightColor" ].value;
-
-					var emitter = light.emitter;
-					emitter.material.uniforms[ "samplerDepth" ].value = compDepth.renderTarget2;
-					emitter.material.uniforms[ "lightColor" ].value = color;
-
-				}
-
-				compEmitter.render();
-
-				// -----------------------------
-				// light pass
-				// -----------------------------
-
-				camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
-
-				for ( var i = 0, il = lightNode.children.length; i < il; i ++ ) {
-
-					var uniforms = lightNode.children[ i ].material.uniforms;
-
-					uniforms[ "matProjInverse" ].value = camera.projectionMatrixInverse;
-					uniforms[ "matView" ].value = camera.matrixWorldInverse;
-
-				}
-
-				var time = Date.now() * 0.0005;
-
-				// update lights
-
-				var x, y, z;
-
-				for ( var i = 0; i < numLights; i ++ ) {
-
-					if ( i > 0 ) {
-
-						x = Math.sin( time + i * 1.7 ) * 80;
-						y = Math.cos( time + i * 1.5 ) * 40;
-						z = Math.cos( time + i * 1.3 ) * 30;
-
-					} else {
-
-						x = Math.sin( time * 3 ) * 20;
-						y = 15;
-						z = Math.cos( time * 3 ) * 25 + 10;
-
-					}
-
-					var light = lightNode.children[ i ];
-					var lightPosition = light.material.uniforms[ "lightPos" ].value;
-
-					lightPosition.x = x;
-					lightPosition.y = y;
-					lightPosition.z = z;
-
-					light.emitter.position = lightPosition;
-					light.position = lightPosition;
-					light.frustumCulled = false;
-
-				}
-
-				compLightBuffer.render();
-
-				// -----------------------------
-				// composite pass
-				// -----------------------------
-
-				compFinal.render( 0.1 );
-
-			}
-
 			function generateBox() {
 
 				var object = new THREE.Object3D();
@@ -622,46 +317,84 @@
 			}
 
 			// -----------------------------
-			// entry point
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = ( event.clientX - windowHalfX ) * 1;
+				mouseY = ( event.clientY - windowHalfY ) * 1;
+
+			}
+
 			// -----------------------------
 
-			bootstrap();
-			initLights();
-			createRenderTargets();
+			function animate() {
 
-			// create animated model
+				requestAnimationFrame( animate );
 
-			var loader = new THREE.JSONLoader();
-			loader.load( "models/animated/elderlyWalk.js", function( geometry ) {
+				render();
+				stats.update();
 
-				geometry.computeMorphNormals();
+			}
 
-				var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x333333, shininess: 20, morphTargets: true, morphNormals: true, vertexColors: THREE.NoColors, shading: THREE.FlatShading } );
-				var meshAnim = new THREE.MorphAnimMesh( geometry, material );
+			function render() {
 
-				meshAnim.duration = 3000;
-				meshAnim.properties.delta = -13;
+				var delta = clock.getDelta();
+				var time = Date.now() * 0.0005;
 
-				var s = 1;
-				meshAnim.scale.set( s, s, s );
-				meshAnim.position.x = 180;
-				meshAnim.position.z = -10;
-				meshAnim.rotation.y = -Math.PI/2;
+				// update lights
 
-				morphs.push( meshAnim );
+				var x, y, z;
 
-				initScene( meshAnim, -48, 50 );
+				for ( var i = 0, il = lights.length; i < il; i ++ ) {
 
-			} );
+					var light = lights[ i ];
 
-			// create box
+					if ( i > 0 ) {
 
-			var object = generateBox();
-			initScene( object, 0, 8 );
+						x = Math.sin( time + i * 1.7 ) * 80;
+						y = Math.cos( time + i * 1.5 ) * 40;
+						z = Math.cos( time + i * 1.3 ) * 30;
 
-			animate();
+					} else {
+
+						x = Math.sin( time * 3 ) * 20;
+						y = 15;
+						z = Math.cos( time * 3 ) * 25 + 10;
+
+					}
 
-			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+					light.position.set( x, y, z );
+
+				}
+
+				// update morphs
+
+				for ( var i = 0; i < morphs.length; i ++ ) {
+
+					morph = morphs[ i ];
+					morph.updateAnimation( 1000 * delta );
+
+					morph.position.x += morph.properties.delta * delta;
+					if ( morph.position.x < -50 ) morph.position.x = 200;
+
+				}
+
+				// update controls
+
+				targetX = mouseX * .001;
+				targetY = mouseY * .001;
+
+				angle += 0.05 * ( targetX - angle );
+
+				camera.position.x = -Math.sin( angle ) * 150;
+				camera.position.z = Math.cos( angle ) * 150;
+
+				camera.lookAt( target );
+
+
+				deferredHelper.render();
+
+			}
 
 		</script>
 	</body>

+ 106 - 381
examples/webgl_lights_deferred_pointlights.html

@@ -62,8 +62,6 @@
 		<script src="js/postprocessing/ShaderPass.js"></script>
 		<script src="js/postprocessing/MaskPass.js"></script>
 
-		<script src="js/controls/TrackballControls.js"></script>
-
 		<!--
 		<script src="js/loaders/UTF8Loader.js"></script>
 		<script src="js/loaders/MTLLoader.js"></script>
@@ -86,6 +84,8 @@
 			var VIEW_ANGLE = 45;
 			var ASPECT = WIDTH / HEIGHT;
 
+			// controls
+
 			var mouseX = 0;
 			var mouseY = 0;
 
@@ -93,82 +93,50 @@
 			var angle = 0;
 			var target = new THREE.Vector3( 0, 0, 0 );
 
-
 			var windowHalfX = window.innerWidth / 2;
 			var windowHalfY = window.innerHeight / 2;
 
 			// core
 
-			var renderer, camera, controls, stats, clock;
-
-			// scenes and scene nodes
-
-			var lightScene, lightNode, scene, sceneNode, emitterScene, emitterNode, quadScene, quadNode;
-
-			// rendertargets
-
-			var rtColor, rtNormals, rtDepth, rtLight, rtEmitter, rtFinal;
-
-			// composer
-
-			var compColor, compNormals, compDepth, compLightBuffer, compFinal, compEmitter, compositePass;
-			var effectFXAA;
+			var renderer, camera, scene, stats, clock;
 
 			// lights
 
 			var numLights = 50;
-			var lights = new Array();
+			var lights = [];
+
+			//
+
+			init();
+			animate();
 
 			// -----------------------------
 
-			function bootstrap() {
+			function init() {
+
+				// renderer
 
 				renderer = new THREE.WebGLRenderer( { alpha: false } );
 				renderer.setSize( WIDTH, HEIGHT );
 				renderer.setClearColorHex( 0x000000, 1 );
 
-
 				renderer.domElement.style.position = "absolute";
 				renderer.domElement.style.top = MARGIN + "px";
 				renderer.domElement.style.left = "0px";
 
-
 				var container = document.getElementById( 'container' );
 				container.appendChild( renderer.domElement );
 
-				// scene camera
+				// camera
 
 				camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
 				camera.position.z = 150;
 
-				controls = new THREE.TrackballControls( camera, renderer.domElement );
-
-				// scene for walt's head model
+				// scene
 
 				scene = new THREE.Scene();
-				sceneNode = new THREE.Object3D();
-				scene.add( sceneNode );
 				scene.add( camera );
 
-				// scene for light proxy geometry
-
-				lightScene = new THREE.Scene();
-				lightNode = new THREE.Object3D();
-				lightScene.add( lightNode );
-
-				// scene for the coloured emitter spheres
-
-				emitterScene = new THREE.Scene();
-				emitterNode = new THREE.Object3D();
-				emitterScene.add( emitterNode );
-
-				// full screen quad for compositing
-
-				quadScene = new THREE.Scene();
-				quadNode = new THREE.Object3D();
-				quadScene.add( quadNode );
-				quadNode.add( new THREE.Mesh( new THREE.PlaneGeometry( 1, 1 ) ) );
-
 				// stats
 
 				stats = new Stats();
@@ -183,167 +151,33 @@
 
 				// deferred helper
 
-				deferredHelper = new THREE.DeferredHelper( { width: SCALED_WIDTH, height: SCALED_HEIGHT } );
-
-			}
-
-			// -----------------------------
-
-			function createRenderTargets() {
-
-				var rtParamsFloatLinear = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
-										    format: THREE.RGBAFormat, type: THREE.FloatType };
-
-				var rtParamsFloatNearest = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: false,
-											 format: THREE.RGBAFormat, type: THREE.FloatType };
-
-				var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
-							          format: THREE.RGBFormat, type: THREE.UnsignedByteType };
-
-				// ----------------------------------------------------------
-				// g-buffer
-				// ----------------------------------------------------------
-
-				rtNormals = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
-				rtDepth   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
-				rtColor   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatNearest );
-				rtLight   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
-				rtEmitter = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsUByte );
-				rtFinal   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsUByte );
-
-				rtNormals.generateMipmaps = false;
-				rtDepth.generateMipmaps = false;
-				rtColor.generateMipmaps = false;
-				rtLight.generateMipmaps = false;
-				rtEmitter.generateMipmaps = false;
-				rtFinal.generateMipmaps = false;
-
-				var passNormals = new THREE.RenderPass( scene, camera );
-				compNormals = new THREE.EffectComposer( renderer, rtNormals );
-				compNormals.addPass( passNormals );
-
-				var passDepth = new THREE.RenderPass( scene, camera );
-				compDepth = new THREE.EffectComposer( renderer, rtDepth );
-				compDepth.addPass( passDepth );
-
-				var passColor = new THREE.RenderPass( scene, camera );
-				compColor = new THREE.EffectComposer( renderer, rtColor );
-				compColor.addPass( passColor );
-
-				// ----------------------------------------------------------
-				// light emitter spheres
-				// ----------------------------------------------------------
-
-				var emitterPass = new THREE.RenderPass( emitterScene, camera );
-
-				compEmitter = new THREE.EffectComposer( renderer, rtEmitter );
-				compEmitter.addPass( emitterPass );
-
-				// ----------------------------------------------------------
-				// lighting pass
-				// ----------------------------------------------------------
-
-				var passLight = new THREE.RenderPass( lightScene, camera );
-				compLightBuffer = new THREE.EffectComposer( renderer, rtLight );
-				compLightBuffer.addPass( passLight );
-
-				deferredHelper.lightShader.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-				deferredHelper.lightShader.uniforms[ 'samplerNormals' ].value = compNormals.renderTarget2;
-				deferredHelper.lightShader.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
-				deferredHelper.lightShader.uniforms[ 'samplerLightBuffer' ].value = rtLight;
-
-				var geomEmitter = new THREE.SphereGeometry( 0.7, 7, 7 );
-
-				for ( var x = 0; x < numLights; x ++ ) {
-
-					var light = lights[ x ];
-
-					// setup material
-
-					var matLight = new THREE.ShaderMaterial( {
-
-						uniforms:       THREE.UniformsUtils.clone( deferredHelper.lightShader.uniforms ),
-						vertexShader:   deferredHelper.lightShader.vertexShader,
-						fragmentShader: deferredHelper.lightShader.fragmentShader,
-						defines:		{ "ADDITIVE_SPECULAR": false },
-
-						blending:		THREE.AdditiveBlending,
-						depthWrite:		false,
-						transparent:	true
-
-					} );
+				deferredHelper = new THREE.DeferredHelper( { renderer: renderer, scene: scene, camera: camera, width: SCALED_WIDTH, height: SCALED_HEIGHT } );
+				deferredHelper.createRenderTargets();
 
-					matLight.uniforms[ "lightPos" ].value = light.position;
-					matLight.uniforms[ "lightRadius" ].value = light.distance;
-					matLight.uniforms[ "lightIntensity" ].value = light.intensity;
-					matLight.uniforms[ "lightColor" ].value = light.color;
+				// add lights
 
-					// setup proxy geometry for this light
+				initLights();
 
-					var geomLight = new THREE.SphereGeometry( light.distance, 16, 8 );
-					var meshLight = new THREE.Mesh( geomLight, matLight );
-					lightNode.add( meshLight );
+				// add objects
 
-					// create emitter sphere
+				initObjects();
 
-					var matEmitter = new THREE.ShaderMaterial( {
+				// events
 
-						uniforms:       THREE.UniformsUtils.clone( deferredHelper.unlitShader.uniforms ),
-						vertexShader:   deferredHelper.unlitShader.vertexShader,
-						fragmentShader: deferredHelper.unlitShader.fragmentShader
-
-					} );
-
-					var meshEmitter = new THREE.Mesh( geomEmitter, matEmitter );
-					meshEmitter.position = light.position;
-					emitterNode.add( meshEmitter );
-
-					// add emitter to light node
-
-					meshLight.emitter = meshEmitter;
-
-				}
-
-				// ----------------------------------------------------------
-				// composite
-				// ----------------------------------------------------------
-
-				deferredHelper.compositeShader.uniforms[ 'samplerLightBuffer' ].value = compLightBuffer.renderTarget2;
-				deferredHelper.compositeShader.uniforms[ 'samplerEmitter' ].value = compEmitter.renderTarget2;
-
-				compositePass = new THREE.ShaderPass( deferredHelper.compositeShader );
-				compositePass.needsSwap = true;
-				//compositePass.renderToScreen = true;
-
-				effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
-
-				//effectFXAA.uniforms[ 'resolution' ].value.set( 1 / WIDTH, 1 / HEIGHT );
-				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / SCALED_WIDTH, 1 / SCALED_HEIGHT );
-				//effectFXAA.renderToScreen = true;
-
-				var effectColor = new THREE.ShaderPass( THREE.ColorCorrectionShader );
-				effectColor.renderToScreen = true;
-
-				effectColor.uniforms[ 'powRGB' ].value.set( 1, 1, 1 );
-				effectColor.uniforms[ 'mulRGB' ].value.set( 2, 2, 2 );
-
-				compFinal = new THREE.EffectComposer( renderer, rtFinal );
-				compFinal.addPass( compositePass );
-				compFinal.addPass( effectFXAA );
-				compFinal.addPass( effectColor );
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 
 			}
 
 			// -----------------------------
 
-			function initScene( object, y, scale ) {
+			function addObject( object, y, scale ) {
 
 				deferredHelper.addDeferredMaterials( object );
 
 				object.position.y = y;
 				object.scale.set( scale, scale, scale );
 
-				sceneNode.add( object );
+				scene.add( object );
 
 			}
 
@@ -355,200 +189,81 @@
 
 				// front light
 
-				var light = new THREE.PointLight();
-
-				light.color = new THREE.Vector3( 1, 1, 1 );
-				light.intensity = 1.5;
-				light.distance = 1.5 * distance;
-
+				var light = new THREE.PointLight( 0xffffff, 1.5, 1.5 * distance );
 				lights.push( light );
 
 				// random lights
 
-				for ( var i = 1; i < numLights; i ++ ) {
-
-					var light = new THREE.PointLight();
+				var c = new THREE.Vector3();
 
-					light.color = new THREE.Vector3( Math.random(), Math.random(), Math.random() ).normalize();
+				for ( var i = 1; i < numLights; i ++ ) {
 
-					// gamma to linear
+					var light = new THREE.PointLight( 0xffffff, 2.0, distance );
 
-					light.color.x *= light.color.x;
-					light.color.y *= light.color.y;
-					light.color.z *= light.color.z;
+					c.set( Math.random(), Math.random(), Math.random() ).normalize();
 
-					light.intensity = 2.0;
-					light.distance = distance;
+					light.color.setRGB( c.x, c.y, c.z );
+					light.color.convertGammaToLinear();
 
 					lights.push( light );
 
 				}
 
-			}
-
-			// -----------------------------
-
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 1;
-				mouseY = ( event.clientY - windowHalfY ) * 1;
+				deferredHelper.addDeferredLights( lights, false );
 
 			}
 
 			// -----------------------------
 
-			function animate() {
-
-				var delta = clock.getDelta();
-
-				requestAnimationFrame( animate );
-
-				//controls.update( delta );
+			function initObjects() {
 
-				targetX = mouseX * .001;
-				targetY = mouseY * .001;
+				/*
 
-				angle += 0.05 * ( targetX - angle );
+				var loader = new THREE.UTF8Loader();
 
-				camera.position.x = -Math.sin( angle ) * 150;
-				camera.position.z = Math.cos( angle ) * 150;
+				loader.load( "models/utf8/ben_dds.js", function ( object ) {
 
-				camera.lookAt( target );
+					addObject( object, -75, 150 );
+					animate();
 
-				stats.update();
-				render();
+				}, { normalizeRGB: true } );
 
-			}
+				loader.load( "models/utf8/WaltHi.js", function ( object ) {
 
-			// -----------------------------
+					addObject( object, -35, 1 );
+					animate();
 
-			function render() {
+				}, { normalizeRGB: true } );
 
-				// -----------------------------
-				// g-buffer color
-				// -----------------------------
+				*/
 
-				sceneNode.traverse( function( node ) {
+				var loader = new THREE.JSONLoader();
+				loader.load( "obj/leeperrysmith/LeePerrySmith.js", function( geometry, materials ) {
 
-					if ( node.material ) {
+					var mapColor = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
+					var mapHeight = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Disp_NoSmoothUV-4096.jpg" );
+					mapHeight.repeat.set( 0.998, 0.998 );
+					mapHeight.offset.set( 0.001, 0.001 )
+					mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping;
+					mapHeight.anisotropy = 4;
+					mapHeight.format = THREE.RGBFormat;
 
-						node.material = node.properties.colorMaterial;
+					var material = new THREE.MeshPhongMaterial( { map: mapColor, bumpMap: mapHeight, bumpScale: 2.5, shininess: 75, specular: 0x090909 } );
 
-					}
+					var object = new THREE.Mesh( geometry, material );
+					addObject( object, 0, 8 );
 
 				} );
 
-				compColor.render();
-
-				// -----------------------------
-				// g-buffer depth
-				// -----------------------------
-
-				sceneNode.traverse( function( node ) {
+				// create box
 
-					if ( node.material ) {
-
-						node.material = node.properties.depthMaterial;
-
-					}
-
-				} );
-
-				compDepth.render();
-
-				// -----------------------------
-				// g-buffer normals
-				// -----------------------------
-
-				sceneNode.traverse( function( node ) {
-
-					if ( node.material ) {
-
-						node.material = node.properties.normalMaterial;
-
-					}
-
-				} );
-
-				compNormals.render();
-
-				// -----------------------------
-				// emitter pass
-				// -----------------------------
-
-				for ( var i = 0, il = lightNode.children.length; i < il; i ++ ) {
-
-					var light = lightNode.children[ i ];
-					var color = light.material.uniforms[ "lightColor" ].value;
-
-					var emitter = light.emitter;
-					emitter.material.uniforms[ "samplerDepth" ].value = compDepth.renderTarget2;
-					emitter.material.uniforms[ "lightColor" ].value = color;
-
-				}
-
-				compEmitter.render();
-
-				// -----------------------------
-				// light pass
-				// -----------------------------
-
-				camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
-
-				for ( var i = 0, il = lightNode.children.length; i < il; i ++ ) {
-
-					var uniforms = lightNode.children[ i ].material.uniforms;
-
-					uniforms[ "matProjInverse" ].value = camera.projectionMatrixInverse;
-					uniforms[ "matView" ].value = camera.matrixWorldInverse;
-
-				}
-
-				var time = Date.now() * 0.0005;
-
-				// update lights
-
-				var x, y, z;
-
-				for ( var i = 0; i < numLights; i ++ ) {
-
-					if ( i > 0 ) {
-
-						x = Math.sin( time + i * 1.7 ) * 80;
-						y = Math.cos( time + i * 1.5 ) * 40;
-						z = Math.cos( time + i * 1.3 ) * 30;
-
-					} else {
-
-						x = Math.sin( time * 3 ) * 20;
-						y = 15;
-						z = Math.cos( time * 3 ) * 25 + 10;
-
-					}
-
-					var light = lightNode.children[ i ];
-					var lightPosition = light.material.uniforms[ "lightPos" ].value;
-
-					lightPosition.x = x;
-					lightPosition.y = y;
-					lightPosition.z = z;
-
-					light.emitter.position = lightPosition;
-					light.position = lightPosition;
-					light.frustumCulled = false;
-
-				}
-
-				compLightBuffer.render();
-
-				// -----------------------------
-				// composite pass
-				// -----------------------------
-
-				compFinal.render( 0.1 );
+				var object = generateBox();
+				addObject( object, 0, 8 );
 
 			}
 
+			// -----------------------------
+
 			function generateBox() {
 
 				var object = new THREE.Object3D();
@@ -618,59 +333,69 @@
 			}
 
 			// -----------------------------
-			// entry point
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = ( event.clientX - windowHalfX ) * 1;
+				mouseY = ( event.clientY - windowHalfY ) * 1;
+
+			}
+
 			// -----------------------------
 
-			bootstrap();
-			initLights();
-			createRenderTargets();
+			function animate() {
 
-			/*
-			var loader = new THREE.UTF8Loader();
+				requestAnimationFrame( animate );
 
-			loader.load( "models/utf8/ben_dds.js", function ( object ) {
+				render();
+				stats.update();
 
-				initScene( object, -75, 150 );
-				animate();
+			}
 
-			}, { normalizeRGB: true } );
-			*/
+			function render() {
 
-			/*
-			loader.load( "models/utf8/WaltHi.js", function ( object ) {
+				// update lights
 
-				initScene( object, -35, 1 );
-				animate();
+				var time = Date.now() * 0.0005;
+				var x, y, z;
 
-			}, { normalizeRGB: true } );
-			*/
+				for ( var i = 0, il = lights.length; i < il; i ++ ) {
 
-			var loader = new THREE.JSONLoader();
-			loader.load( "obj/leeperrysmith/LeePerrySmith.js", function( geometry, materials ) {
+					var light = lights[ i ];
 
-				var mapColor = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
-				var mapHeight = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Disp_NoSmoothUV-4096.jpg" );
-				mapHeight.repeat.set( 0.998, 0.998 );
-				mapHeight.offset.set( 0.001, 0.001 )
-				mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping;
-				mapHeight.anisotropy = 4;
-				mapHeight.format = THREE.RGBFormat;
+					if ( i > 0 ) {
+
+						x = Math.sin( time + i * 1.7 ) * 80;
+						y = Math.cos( time + i * 1.5 ) * 40;
+						z = Math.cos( time + i * 1.3 ) * 30;
 
-				var material = new THREE.MeshPhongMaterial( { map: mapColor, bumpMap: mapHeight, bumpScale: 2.5, shininess: 75, specular: 0x090909 } );
+					} else {
 
-				var object = new THREE.Mesh( geometry, material );
-				initScene( object, 0, 8 );
+						x = Math.sin( time * 3 ) * 20;
+						y = 15;
+						z = Math.cos( time * 3 ) * 25 + 10;
 
-			} );
+					}
 
-			// create box
+					light.position.set( x, y, z );
 
-			var object = generateBox();
-			initScene( object, 0, 8 );
+				}
 
-			animate();
+				var delta = clock.getDelta();
+
+				targetX = mouseX * .001;
+				targetY = mouseY * .001;
+
+				angle += 0.05 * ( targetX - angle );
 
-			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+				camera.position.x = -Math.sin( angle ) * 150;
+				camera.position.z =  Math.cos( angle ) * 150;
+
+				camera.lookAt( target );
+
+				deferredHelper.render();
+
+			}
 
 		</script>
 	</body>