Browse Source

Moved MeshPhongMaterial onto common shader builder machinery, ubershader is no more.

Code is still rough around edges (it can be made nicer), though it should already produce one-to-one results with ubershader.

Side-effect is that scene is no longer required as WebGLRenderer constructor parameter. Shader programs are now constructed upon first frame render and only then scene lights are examined.
alteredq 14 years ago
parent
commit
ecad27eb11

File diff suppressed because it is too large
+ 30 - 88
build/Three.js


File diff suppressed because it is too large
+ 30 - 89
build/ThreeDebug.js


File diff suppressed because it is too large
+ 36 - 94
build/ThreeExtras.js


+ 1 - 1
examples/geometry_large_mesh.html

@@ -151,7 +151,7 @@
 
 				if ( render_gl ) {
 					try {
-						webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+						webglRenderer = new THREE.WebGLRenderer();
 						webglRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
 						container.appendChild( webglRenderer.domElement );
 						has_gl = 1;

+ 1 - 1
examples/geometry_minecraft.html

@@ -154,7 +154,7 @@
 				directionalLight.position.normalize();
 				scene.addLight( directionalLight );
 
-				renderer = new THREE.WebGLRenderer( { scene: scene } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				container.innerHTML = "";

+ 1 - 1
examples/geometry_minecraft_ao.html

@@ -482,7 +482,7 @@
 				directionalLight.position.normalize();
 				scene.addLight( directionalLight );
 
-				renderer = new THREE.WebGLRenderer( { scene: scene } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				container.innerHTML = "";

+ 1 - 1
examples/geometry_terrain_fog_gl.html

@@ -103,7 +103,7 @@
 				mesh.rotation.x = - 90 * Math.PI / 180;
 				scene.addObject( mesh );
 
-				renderer = new THREE.WebGLRenderer( { scene: scene, clearColor: 0xefd1b5, clearAlpha: 1 } );
+				renderer = new THREE.WebGLRenderer( { clearColor: 0xefd1b5, clearAlpha: 1 } );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				container.innerHTML = "";

+ 1 - 1
examples/geometry_terrain_gl.html

@@ -92,7 +92,7 @@
 				mesh.rotation.x = - 90 * Math.PI / 180;
 				scene.addObject( mesh );
 
-				renderer = new THREE.WebGLRenderer( { scene: scene } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				container.innerHTML = "";

+ 2 - 2
examples/geometry_terrain_gl2.html

@@ -1,7 +1,7 @@
 <!DOCTYPE HTML>
 <html lang="en">
 	<head>
-		<title>three.js - geometry - webgl terrain</title>
+		<title>three.js - geometry - webgl terrain 2</title>
 		<meta charset="utf-8">
 		<style type="text/css">
 			body {
@@ -93,7 +93,7 @@
 				mesh.rotation.x = - 90 * Math.PI / 180;
 				scene.addObject( mesh );
 
-				renderer = new THREE.WebGLRenderer( { scene: scene } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				container.innerHTML = "";

+ 2 - 2
examples/lights_pointlights_gl.html

@@ -115,7 +115,7 @@
 				light3 = new THREE.PointLight( 0x80ff80 );
 				scene.addLight( light3 );
 
-				var sphere = new Sphere( 0.5, 16, 8, 1 );
+				var sphere = new Sphere( 0.5, 16, 8 );
 				
 				var l1 = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( { color: 0xff0040 } ) );
 				l1.position = light1.position;
@@ -129,7 +129,7 @@
 				l3.position = light3.position;
 				scene.addObject( l3 );
  
-				renderer = new THREE.WebGLRenderer( { scene: scene } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );
 				

+ 1 - 1
examples/materials_cars.html

@@ -199,7 +199,7 @@
 
 				SceneUtils.addPanoramaCubeWebGL( sceneCube, 100000, textureCube );
 
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( window.innerWidth, window.innerHeight );
 				webglRenderer.setFaceCulling( 0 );
 				webglRenderer.autoClear = false;

+ 2 - 2
examples/materials_cubemap.html

@@ -84,7 +84,7 @@
 				scene.addLight( pointLight );
 
 				// light representation
-				sphere = new Sphere( 100, 16, 8, 1 );
+				sphere = new Sphere( 100, 16, 8 );
 				lightMesh = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( { color:0xffaa00 } ) );
 				lightMesh.position = pointLight.position;
 				lightMesh.scale.x = lightMesh.scale.y = lightMesh.scale.z = 0.05;
@@ -112,7 +112,7 @@
 				//SceneUtils.addPanoramaCube( sceneCube, 100000, images );
 				SceneUtils.addPanoramaCubeWebGL( sceneCube, 100000, reflectionCube );
 				
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( window.innerWidth, window.innerHeight );
 				webglRenderer.autoClear = false;
 				//webglRenderer.setFaceCulling( 0 );

+ 1 - 1
examples/materials_cubemap_balls_reflection.html

@@ -104,7 +104,7 @@
 				//SceneUtils.addPanoramaCube( sceneCube, 100000, images );
 				SceneUtils.addPanoramaCubeWebGL( sceneCube, 100000, textureCube );
 
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( window.innerWidth, window.innerHeight );
 				webglRenderer.autoClear = false;
 				container.appendChild( webglRenderer.domElement );

+ 1 - 1
examples/materials_cubemap_balls_refraction.html

@@ -102,7 +102,7 @@
 				//SceneUtils.addPanoramaCube( sceneCube, 100000, images );
 				SceneUtils.addPanoramaCubeWebGL( sceneCube, 100000, textureCube );
 
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( window.innerWidth, window.innerHeight );
 				webglRenderer.autoClear = false;
 				container.appendChild( webglRenderer.domElement );

+ 2 - 2
examples/materials_cubemap_escher.html

@@ -78,7 +78,7 @@
 
 				var textureCube = new THREE.Texture( images );
 				var material = new THREE.MeshBasicMaterial( { color: 0xffffff, env_map: textureCube } )
-				var geometry = new Sphere( 100, 96, 64, true );
+				var geometry = new Sphere( 100, 96, 64 );
 
 				var mesh = new THREE.Mesh( geometry, material );
 				mesh.scale.x = mesh.scale.y = mesh.scale.z = 16;
@@ -88,7 +88,7 @@
 				//SceneUtils.addPanoramaCube( scene, 6000, images );
 				SceneUtils.addPanoramaCubeWebGL( scene, 6000, textureCube );
 
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( webglRenderer.domElement );
 

+ 2 - 2
examples/materials_cubemap_refraction.html

@@ -85,7 +85,7 @@
 				scene.addLight( pointLight );
 
 				// light representation
-				sphere = new Sphere( 100, 16, 8, 1 );
+				sphere = new Sphere( 100, 16, 8 );
 				lightMesh = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( { color:0xffaa00 } ) );
 				lightMesh.position = pointLight.position;
 				lightMesh.scale.x = lightMesh.scale.y = lightMesh.scale.z = 0.05;
@@ -110,7 +110,7 @@
 				//SceneUtils.addPanoramaCube( sceneCube, 100000, images );
 				SceneUtils.addPanoramaCubeWebGL( sceneCube, 100000, textureCube );
 
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( window.innerWidth, window.innerHeight );
 				webglRenderer.autoClear = false;
 				container.appendChild( webglRenderer.domElement );

+ 4 - 4
examples/materials_gl.html

@@ -84,9 +84,9 @@
 
 				// Spheres geometry
 
-				var geometry_smooth = new Sphere( 70, 32, 16, true );
-				var geometry_flat = new Sphere( 70, 32, 16, false );
-				var geometry_pieces = new Sphere( 70, 32, 16, true ); // Extra geometry to be broken down for MeshFaceMaterial
+				var geometry_smooth = new Sphere( 70, 32, 16 );
+				var geometry_flat = new Sphere( 70, 32, 16 );
+				var geometry_pieces = new Sphere( 70, 32, 16 ); // Extra geometry to be broken down for MeshFaceMaterial
 				
 				for ( var i = 0, l = geometry_pieces.faces.length; i < l; i ++ ) {
 
@@ -143,7 +143,7 @@
 				pointLight = new THREE.PointLight( 0xffffff, 1 );
 				scene.addLight( pointLight );
 
-				renderer = new THREE.WebGLRenderer( { scene: scene } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				container.appendChild( renderer.domElement );

+ 1 - 1
examples/materials_grass.html

@@ -50,7 +50,7 @@
 
 				}
 
-				renderer = new THREE.WebGLRenderer( { scene: scene } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.sortObjects = false;
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );

+ 2 - 2
examples/materials_multimaterials.html

@@ -102,7 +102,7 @@
 
 				// SPHERES
 
-				sphere = new Sphere( 100, 16, 8, 1 );
+				sphere = new Sphere( 100, 16, 8 );
 				for (var i=0; i<10; i++) {
 					//mesh = new THREE.Mesh( sphere, new THREE.MeshLambertMaterial( ) );
 					mesh = new THREE.Mesh( sphere, [ new THREE.MeshLambertMaterial( { color: 0xffffff } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true,  wireframe_linewidth: 1.5 } ) ] );
@@ -146,7 +146,7 @@
 
 				if ( render_gl ) {
 					try {
-						webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+						webglRenderer = new THREE.WebGLRenderer();
 						webglRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
 						container.appendChild( webglRenderer.domElement );
 						has_gl = 1;

+ 2 - 2
examples/materials_normalmap.html

@@ -141,7 +141,7 @@
 
 				// light representation
 				
-				var sphere = new Sphere( 100, 16, 8, 1 );
+				var sphere = new Sphere( 100, 16, 8 );
 				lightMesh = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( { color:0xffaa00 } ) );
 				lightMesh.position = pointLight.position;
 				lightMesh.scale.x = lightMesh.scale.y = lightMesh.scale.z = 0.05;
@@ -190,7 +190,7 @@
 				
 				loader.loadBinary( "obj/ninja/NinjaLo_bin.js", function( geometry ) { createScene( geometry, scale, material1, material2 ) }, "obj/ninja" );
 
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( webglRenderer.domElement );
 

+ 1 - 1
examples/materials_normalmap2.html

@@ -174,7 +174,7 @@
 
 				loader.loadAscii( "obj/leeperrysmith/LeePerrySmith.js", function( geometry ) { createScene( geometry, 100, material ) }, "obj/leeperrysmith" );
 
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( webglRenderer.domElement );
 

+ 1 - 1
examples/materials_shaders.html

@@ -171,7 +171,7 @@
 
 				if ( render_gl ) {
 					try {
-						webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+						webglRenderer = new THREE.WebGLRenderer();
 						webglRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
 						container.appendChild( webglRenderer.domElement );
 						has_gl = 1;

+ 1 - 1
examples/materials_shaders_fresnel.html

@@ -113,7 +113,7 @@
 
 				SceneUtils.addPanoramaCubeWebGL( sceneCube, 100000, textureCube );
 
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( window.innerWidth, window.innerHeight );
 				webglRenderer.autoClear = false;
 				container.appendChild( webglRenderer.domElement );

+ 1 - 1
examples/obj_convert_test.html

@@ -167,7 +167,7 @@
 
 				if ( render_gl ) {
 					try {
-						webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+						webglRenderer = new THREE.WebGLRenderer();
 						webglRenderer.setFaceCulling(0);
 						webglRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
 						container.appendChild( webglRenderer.domElement );

+ 1 - 1
examples/shader.html

@@ -124,7 +124,7 @@
 				mesh = new THREE.Mesh( new Plane( 2, 2 ), material );
 				scene.addObject( mesh );
 
-				renderer = new THREE.WebGLRenderer( { scene: scene } );
+				renderer = new THREE.WebGLRenderer();
 				container.appendChild( renderer.domElement );
 
 				stats = new Stats();

+ 1 - 1
examples/uqbiquity_test.html

@@ -223,7 +223,7 @@
 				svgRenderer.setQuality( 'low' );
 				container.appendChild( svgRenderer.domElement );
 
-				webglRenderer = new THREE.WebGLRenderer( { scene: scene } );
+				webglRenderer = new THREE.WebGLRenderer();
 				webglRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
 				// webglRenderer.setFaceCulling( 0 );
 				container.appendChild( webglRenderer.domElement );

+ 271 - 494
src/renderers/WebGLRenderer.js

@@ -20,7 +20,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 	// See http://code.google.com/p/chromium/issues/detail?id=63491
 
 	var _canvas = document.createElement( 'canvas' ), _gl,
-	_oldProgram, _uberProgram,
+	_oldProgram = null,
 	_modelViewMatrix = new THREE.Matrix4(), _normalMatrix,
 
 	_viewMatrixArray = new Float32Array(16),
@@ -29,29 +29,25 @@ THREE.WebGLRenderer = function ( parameters ) {
 	_normalMatrixArray = new Float32Array(9),
 	_objectMatrixArray = new Float32Array(16),
 
-	// ubershader material constants
-
-	PHONG = 2,
-
-	// heuristics to create shader parameters according to lights in the scene
-	// (not to blow over maxLights budget)
-
-	maxLightCount = allocateLights( parameters.scene, 4 ),
-	fog = parameters.scene ? parameters.scene.fog : null,
-
-	antialias = parameters.antialias != undefined ? parameters.antialias : true,
-
-	clearColor = parameters.clearColor ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ),
-	clearAlpha = parameters.clearAlpha ? parameters.clearAlpha : 0;
+	// parameters defaults
+	
+	antialias = true,
+	clearColor = new THREE.Color( 0x000000 ),
+	clearAlpha = 0;
 
+	if ( parameters ) {
+		
+		if ( parameters.antialias !== undefined ) antialias = parameters.antialias;
+		if ( parameters.clearColor !== undefined ) clearColor.setHex( parameters.clearColor );
+		if ( parameters.clearAlpha !== undefined ) clearAlpha = parameters.clearAlpha;
+		
+	}
+		
 	this.domElement = _canvas;
 	this.autoClear = true;
 
 	initGL( antialias, clearColor, clearAlpha );
 
-	_uberProgram = initUbershader( maxLightCount.directional, maxLightCount.point, fog );
-	_oldProgram = _uberProgram;
-
 	//alert( dumpObject( getGLParams() ) );
 
 	this.setSize = function ( width, height ) {
@@ -330,7 +326,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	function refreshUniforms( material, fog ) {
+	function refreshUniformsCommon( material, fog ) {
 		
 		// premultiply alpha
 		material.uniforms.color.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
@@ -366,6 +362,17 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 	
+	function refreshUniformsPhong( material ) {
+		
+		//material.uniforms.ambient.value.setHex( material.ambient.hex );
+		//material.uniforms.specular.value.setHex( material.specular.hex );
+		material.uniforms.ambient.value.setRGB( material.ambient.r, material.ambient.g, material.ambient.b );
+		material.uniforms.specular.value.setRGB( material.specular.r, material.specular.g, material.specular.b );
+		material.uniforms.shininess.value = material.shininess;
+		
+	};
+	
+	
 	function refreshLights( material, lights ) {
 		
 		material.uniforms.enableLighting.value = lights.directional.positions.length + lights.point.positions.length;
@@ -379,71 +386,63 @@ THREE.WebGLRenderer = function ( parameters ) {
 	
 	this.renderBuffer = function ( camera, lights, fog, material, geometryChunk ) {
 
-		var mColor, mOpacity, mReflectivity,
-			mWireframe, mLineWidth, mBlending,
-			mAmbient, mSpecular, mShininess,
-			mMap, envMap, mixEnvMap,
-			mRefractionRatio, useRefract,
-			program, u, identifiers, attributes, parameters,
-			vector_lights;
-
-
-		if ( material instanceof THREE.MeshShaderMaterial ||
-			 material instanceof THREE.MeshDepthMaterial ||
-			 material instanceof THREE.MeshNormalMaterial || 
-			 material instanceof THREE.MeshBasicMaterial ||
-			 material instanceof THREE.MeshLambertMaterial ) {
+		var program, u, identifiers, attributes, parameters, vector_lights, maxLightCount;
 
-			if ( !material.program ) {
+		if ( !material.program ) {
 
-				if ( material instanceof THREE.MeshDepthMaterial ) {
+			if ( material instanceof THREE.MeshDepthMaterial ) {
 
-					setMaterialShaders( material, THREE.ShaderLib[ 'depth' ] );
+				setMaterialShaders( material, THREE.ShaderLib[ 'depth' ] );
 
-					material.uniforms.mNear.value = camera.near;
-					material.uniforms.mFar.value = camera.far;
+				material.uniforms.mNear.value = camera.near;
+				material.uniforms.mFar.value = camera.far;
 
-				} else if ( material instanceof THREE.MeshNormalMaterial ) {
+			} else if ( material instanceof THREE.MeshNormalMaterial ) {
 
-					setMaterialShaders( material, THREE.ShaderLib[ 'normal' ] );
+				setMaterialShaders( material, THREE.ShaderLib[ 'normal' ] );
 
-				} else if ( material instanceof THREE.MeshBasicMaterial ) {
+			} else if ( material instanceof THREE.MeshBasicMaterial ) {
 
-					setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
+				setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
 
-					refreshUniforms( material, fog );
-					
-				} else if ( material instanceof THREE.MeshLambertMaterial ) {
-					
-					setMaterialShaders( material, THREE.ShaderLib[ 'lambert' ] );
-					
-					refreshUniforms( material, fog );
-					
-				}
+				refreshUniformsCommon( material, fog );
+				
+			} else if ( material instanceof THREE.MeshLambertMaterial ) {
+				
+				setMaterialShaders( material, THREE.ShaderLib[ 'lambert' ] );
+				
+				refreshUniformsCommon( material, fog );
+				
+			} else if ( material instanceof THREE.MeshPhongMaterial ) {
+				
+				setMaterialShaders( material, THREE.ShaderLib[ 'phong' ] );
+				
+				refreshUniformsCommon( material, fog );
+				
+			}
 
-				parameters = { fog: fog, map: material.map, env_map: material.env_map, maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point };
-				material.program = buildProgram( material.fragment_shader, material.vertex_shader, parameters );
+			// heuristics to create shader parameters according to lights in the scene
+			// (not to blow over maxLights budget)
 
-				identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition' ];
-				for( u in material.uniforms ) {
+			maxLightCount = allocateLights( lights, 4 );
 
-					identifiers.push(u);
+			parameters = { fog: fog, map: material.map, env_map: material.env_map, maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point };
+			material.program = buildProgram( material.fragment_shader, material.vertex_shader, parameters );
 
-				}
+			identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition' ];
+			for( u in material.uniforms ) {
 
-				cacheUniformLocations( material.program, identifiers );
-				cacheAttributeLocations( material.program, [ "position", "normal", "uv", "tangent" ] );
+				identifiers.push(u);
 
 			}
 
-			program = material.program;
-
-		} else {
-
-			program = _uberProgram;
+			cacheUniformLocations( material.program, identifiers );
+			cacheAttributeLocations( material.program, [ "position", "normal", "uv", "tangent" ] );
 
 		}
 
+		program = material.program;
+
 		if( program != _oldProgram ) {
 
 			_gl.useProgram( program );
@@ -451,149 +450,32 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		if ( program == _uberProgram || 
-			 material instanceof THREE.MeshLambertMaterial ) {
-
-			vector_lights = this.setupLights( program, lights );
-			
-			if ( program == _uberProgram ) {
-			
-				_gl.uniform1i( program.uniforms.enableLighting, vector_lights.directional.positions.length + vector_lights.point.positions.length || 
-																vector_lights.ambient[0] || vector_lights.ambient[1] || vector_lights.ambient[2] );
-				_gl.uniform3fv( program.uniforms.ambientLightColor, vector_lights.ambient );
-				
-				if ( vector_lights.directional.positions.length ) {
-
-					_gl.uniform3fv( program.uniforms.directionalLightDirection, vector_lights.directional.positions );
-					_gl.uniform3fv( program.uniforms.directionalLightColor, vector_lights.directional.colors );
-
-				}
-				
-				if ( vector_lights.point.positions.length ) {
-
-					_gl.uniform3fv( program.uniforms.pointLightPosition, vector_lights.point.positions );
-					_gl.uniform3fv( program.uniforms.pointLightColor, vector_lights.point.colors );
-
-				}
-				
-			} else {
-				
-				refreshLights( material, vector_lights );
-				
-			}
-
-		}
-
 		this.loadCamera( program, camera );
 		this.loadMatrices( program );
 
-		if ( material instanceof THREE.MeshBasicMaterial ||
+		if ( material instanceof THREE.MeshPhongMaterial || 
 			 material instanceof THREE.MeshLambertMaterial ) {
-			
-			refreshUniforms( material, fog );
 
-		}
-
-		if ( material instanceof THREE.MeshShaderMaterial ||
-		     material instanceof THREE.MeshDepthMaterial ||
-			 material instanceof THREE.MeshNormalMaterial ||
-			 material instanceof THREE.MeshBasicMaterial ||
-			 material instanceof THREE.MeshLambertMaterial ) {
-
-			mWireframe = material.wireframe;
-			mLineWidth = material.wireframe_linewidth;
-
-			mBlending = material.blending;
-
-			setUniforms( program, material.uniforms );
+			vector_lights = this.setupLights( program, lights );
+			refreshLights( material, vector_lights );
 
 		}
 
-		if ( material instanceof THREE.MeshPhongMaterial ) {
-
-			mColor = material.color;
-			mOpacity = material.opacity;
-
-			mWireframe = material.wireframe;
-			mLineWidth = material.wireframe_linewidth;
-
-			mBlending = material.blending;
-
-			mMap = material.map;
-			envMap = material.env_map;
-
-			mixEnvMap = material.combine == THREE.MixOperation;
-			mReflectivity = material.reflectivity;
-
-			useRefract = material.env_map && material.env_map.mapping instanceof THREE.CubeRefractionMapping;
-			mRefractionRatio = material.refraction_ratio;
-
-			_gl.uniform4f( program.uniforms.mColor,  mColor.r * mOpacity, mColor.g * mOpacity, mColor.b * mOpacity, mOpacity );
-
-			_gl.uniform1i( program.uniforms.mixEnvMap, mixEnvMap );
-			_gl.uniform1f( program.uniforms.mReflectivity, mReflectivity );
-
-			_gl.uniform1i( program.uniforms.useRefract, useRefract );
-			_gl.uniform1f( program.uniforms.mRefractionRatio, mRefractionRatio );
-
-			if ( fog ) {
-
-				_gl.uniform3f( program.uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );
-
-				if ( fog instanceof THREE.Fog ) {
-
-					_gl.uniform1f( program.uniforms.fogNear, fog.near );
-					_gl.uniform1f( program.uniforms.fogFar, fog.far );
-
-				} else if ( fog instanceof THREE.FogExp2 ) {
-
-					_gl.uniform1f( program.uniforms.fogDensity, fog.density );
-
-				}
-
-			}
+		if ( material instanceof THREE.MeshBasicMaterial ||
+			 material instanceof THREE.MeshLambertMaterial ||
+			 material instanceof THREE.MeshPhongMaterial ) {
+			
+			refreshUniformsCommon( material, fog );
 
 		}
-
+		
 		if ( material instanceof THREE.MeshPhongMaterial ) {
-
-			mAmbient  = material.ambient;
-			mSpecular = material.specular;
-			mShininess = material.shininess;
-
-			_gl.uniform4f( program.uniforms.mAmbient,  mAmbient.r,  mAmbient.g,  mAmbient.b,  mOpacity );
-			_gl.uniform4f( program.uniforms.mSpecular, mSpecular.r, mSpecular.g, mSpecular.b, mOpacity );
-			_gl.uniform1f( program.uniforms.mShininess, mShininess );
-
-			_gl.uniform1i( program.uniforms.material, PHONG );
 			
-		}
-
-		if ( mMap ) {
-
-			setTexture( mMap, 0 );
-
-			_gl.uniform1i( program.uniforms.tMap,  0 );
-			_gl.uniform1i( program.uniforms.enableMap, 1 );
-
-		} else {
-
-			_gl.uniform1i( program.uniforms.enableMap, 0 );
+			refreshUniformsPhong( material );
 
 		}
 
-		if ( envMap ) {
-
-			setCubeTexture( envMap, 1 );
-
-			_gl.uniform1i( program.uniforms.tCube, 1 );
-			_gl.uniform1i( program.uniforms.enableCubeMap, 1 );
-
-		} else {
-
-			_gl.uniform1i( program.uniforms.enableCubeMap, 0 );
-
-		}
+		setUniforms( program, material.uniforms );
 
 		attributes = program.attributes;
 
@@ -644,7 +526,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		// render triangles
 
-		if ( ! mWireframe ) {
+		if ( ! material.wireframe ) {
 
 			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
 			_gl.drawElements( _gl.TRIANGLES, geometryChunk.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
@@ -653,7 +535,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		} else {
 
-			_gl.lineWidth( mLineWidth );
+			_gl.lineWidth( material.wireframe_linewidth );
 			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLLineBuffer );
 			_gl.drawElements( _gl.LINES, geometryChunk.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
 
@@ -958,7 +840,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-
 	function initGL( antialias, clearColor, clearAlpha ) {
 
 		try {
@@ -989,236 +870,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
 
 	};
-		
-	function generateFragmentShader() {
-
-		var chunks = [
-
-			"uniform int material;", // 2 - Phong
-
-			"uniform bool enableMap;",
-			"uniform bool enableCubeMap;",
-			"uniform bool mixEnvMap;",
-
-			"uniform samplerCube tCube;",
-			"uniform float mReflectivity;",
-
-			"uniform sampler2D tMap;",
-			"uniform vec4 mColor;",
-			"uniform float mOpacity;",
-
-			"uniform vec4 mAmbient;",
-			"uniform vec4 mSpecular;",
-			"uniform float mShininess;",
-
-			THREE.Snippets[ "fog_pars_fragment" ],
-			
-			"#if MAX_DIR_LIGHTS > 0",
-				"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
-			"#endif",
-
-			"varying vec3 vNormal;",
-			"varying vec2 vUv;",
-
-			"varying vec3 vLightWeighting;",
-
-			"#if MAX_POINT_LIGHTS > 0",
-				"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
-			"#endif",
-
-			"varying vec3 vViewPosition;",
-
-			"varying vec3 vReflect;",
-
-			"void main() {",
-
-				"vec4 mapColor = vec4( 1.0 );",
-				"vec4 cubeColor = vec4( 1.0 );",
-
-				// diffuse map
-
-				"if ( enableMap ) {",
-
-					"mapColor = texture2D( tMap, vUv );",
-
-				"}",
-
-				// cube map
-
-				"if ( enableCubeMap ) {",
-
-					"cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );",
-					// "cubeColor.r = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) ).r;",
-					// "cubeColor.g = textureCube( tCube, vec3( -vReflect.x + 0.005, vReflect.yz ) ).g;",
-					// "cubeColor.b = textureCube( tCube, vec3( -vReflect.x + 0.01, vReflect.yz ) ).b;",
-
-				"}",
-
-				// Blinn-Phong
-				// based on o3d example
-
-				"if ( material == 2 ) { ",
-
-					"vec3 normal = normalize( vNormal );",
-					"vec3 viewPosition = normalize( vViewPosition );",
-
-					// point lights
-
-					"#if MAX_POINT_LIGHTS > 0",
-						
-						"vec4 pointDiffuse  = vec4( 0.0 );",
-						"vec4 pointSpecular = vec4( 0.0 );",
-
-						"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
-
-							"vec3 pointVector = normalize( vPointLightVector[ i ] );",
-							"vec3 pointHalfVector = normalize( vPointLightVector[ i ] + vViewPosition );",
-
-							"float pointDotNormalHalf = dot( normal, pointHalfVector );",
-							"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
-
-							// Ternary conditional is from the original o3d shader. Here it produces abrupt dark cutoff artefacts.
-							// Using just pow works ok in Chrome, but makes different artefact in Firefox 4.
-							// Zeroing on negative pointDotNormalHalf seems to work in both.
-
-							//"float specularCompPoint = dot( normal, pointVector ) < 0.0 || pointDotNormalHalf < 0.0 ? 0.0 : pow( pointDotNormalHalf, mShininess );",
-							//"float specularCompPoint = pow( pointDotNormalHalf, mShininess );",
-							//"float pointSpecularWeight = pointDotNormalHalf < 0.0 ? 0.0 : pow( pointDotNormalHalf, mShininess );",
-
-							// Ternary conditional inside for loop breaks Chrome shader linking.
-							// Must do it with if.
-
-							"float pointSpecularWeight = 0.0;",
-							"if ( pointDotNormalHalf >= 0.0 )",
-								"pointSpecularWeight = pow( pointDotNormalHalf, mShininess );",
-
-							"pointDiffuse  += mColor * pointDiffuseWeight;",
-							"pointSpecular += mSpecular * pointSpecularWeight;",
-
-							"}",
-
-					"#endif",
-					
-					"#if MAX_DIR_LIGHTS > 0",
-					
-						"vec4 dirDiffuse  = vec4( 0.0 );",
-						"vec4 dirSpecular = vec4( 0.0 );" ,
-
-						"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
-
-							"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
-
-							"vec3 dirVector = normalize( lDirection.xyz );",
-							"vec3 dirHalfVector = normalize( lDirection.xyz + vViewPosition );",
-
-							"float dirDotNormalHalf = dot( normal, dirHalfVector );",
-
-							"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
-
-							"float dirSpecularWeight = 0.0;",
-							"if ( dirDotNormalHalf >= 0.0 )",
-								"dirSpecularWeight = pow( dirDotNormalHalf, mShininess );",
-
-								"dirDiffuse  += mColor * dirDiffuseWeight;",
-								"dirSpecular += mSpecular * dirSpecularWeight;",
-
-						"}",
-					
-					"#endif",
-
-					// all lights contribution summation
-
-					"vec4 totalLight = mAmbient;",
-					
-					"#if MAX_DIR_LIGHTS > 0",
-						"totalLight += dirDiffuse + dirSpecular;",
-					"#endif",
-					
-					"#if MAX_POINT_LIGHTS > 0",
-						"totalLight += pointDiffuse + pointSpecular;",
-					"#endif",
-
-					// looks nicer with weighting
-
-					"if ( mixEnvMap ) {",
-
-						"gl_FragColor = vec4( mix( mapColor.rgb * totalLight.xyz * vLightWeighting, cubeColor.rgb, mReflectivity ), mapColor.a );",
-
-					"} else {",
-
-						"gl_FragColor = vec4( mapColor.rgb * cubeColor.rgb * totalLight.xyz * vLightWeighting, mapColor.a );",
-
-					"}",
-
-				"}",
-
-				THREE.Snippets[ "fog_fragment" ],
-
-			"}" ];
-
-		return chunks.join("\n");
-
-	};
-
-	function generateVertexShader( ) {
-
-		var chunks = [
-
-			"#define PHONG",
-		
-			"uniform bool useRefract;",
-
-			THREE.Snippets[ "lights_pars_vertex" ],
-		
-			"varying vec3 vNormal;",
-			"varying vec2 vUv;",
-
-			"varying vec3 vLightWeighting;",
-
-			"varying vec3 vViewPosition;",
-
-			"varying vec3 vReflect;",
-			"uniform float mRefractionRatio;",
-
-			"void main(void) {",
-
-				// world space
-
-				"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
-				"vViewPosition = cameraPosition - mPosition.xyz;",
-
-				// this doesn't work on Mac
-				//"vec3 nWorld = mat3(objectMatrix) * normal;",
-				"vec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;",
-
-				// eye space
-
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-				"vec3 transformedNormal = normalize( normalMatrix * normal );",
-
-				THREE.Snippets[ "lights_vertex" ],
-
-				"vNormal = transformedNormal;",
-				"vUv = uv;",
-
-				"if ( useRefract ) {",
-
-					"vReflect = refract( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz), mRefractionRatio );",
-
-				"} else {",
-
-					"vReflect = reflect( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz) );",
-
-				"}",
-
-				"gl_Position = projectionMatrix * mvPosition;",
-
-			"}" ];
-
-		return chunks.join("\n");
-
-	};
-
+	
 	function buildProgram( fragment_shader, vertex_shader, parameters ) {
 
 		var program = _gl.createProgram(),
@@ -1272,6 +924,9 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			alert( "Could not initialise shaders\n"+
 					"VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
+			
+			//console.log( prefix_fragment + fragment_shader );
+			//console.log( prefix_vertex + vertex_shader );
 
 		}
 
@@ -1427,72 +1082,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	function initUbershader( maxDirLights, maxPointLights, fog ) {
-		
-		var vertex_shader = generateVertexShader(),
-			fragment_shader = generateFragmentShader(),
-			program;
-
-		//console.log ( vertex_shader );
-		//console.log ( fragment_shader );
-
-		program = buildProgram( fragment_shader, vertex_shader, { fog: fog, maxDirLights: maxDirLights, maxPointLights: maxPointLights } );
-
-		_gl.useProgram( program );
-
-		// matrices
-		// lights
-		// material properties (Basic / Lambert / Blinn-Phong shader)
-
-		cacheUniformLocations( program, [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
-										   'enableLighting', 'ambientLightColor',
-										   'material', 'mColor', 'mAmbient', 'mSpecular', 'mShininess', 'mOpacity',
-										   'enableMap', 'tMap',
-										   'enableCubeMap', 'tCube', 'mixEnvMap', 'mReflectivity',
-										   'mRefractionRatio', 'useRefract'
-		] );
-
-		if ( fog ) {
-
-			cacheUniformLocations( program, [ 'fogColor', 'fogNear', 'fogFar', 'fogDensity' ] );
-
-		}
-
-		if ( maxDirLights ) {
-
-			cacheUniformLocations( program, [ 'directionalLightColor', 'directionalLightDirection' ] );
-
-		}
-
-		if ( maxPointLights ) {
-
-			cacheUniformLocations( program, [ 'pointLightColor', 'pointLightPosition' ] );
-
-		}
-
-		// texture (diffuse map)
-
-		_gl.uniform1i( program.uniforms.enableMap, 0 );
-		_gl.uniform1i( program.uniforms.tMap, 0 );
-
-		// cube texture
-
-		_gl.uniform1i( program.uniforms.enableCubeMap, 0 );
-		_gl.uniform1i( program.uniforms.tCube, 1 ); // it's important to use non-zero texture unit, otherwise it doesn't work
-		_gl.uniform1i( program.uniforms.mixEnvMap, 0 );
-
-		// refraction
-
-		_gl.uniform1i( program.uniforms.useRefract, 0 );
-
-		// attribute arrays
-
-		cacheAttributeLocations( program, [ "position", "normal", "uv" ] );
-
-		return program;
-
-	};
-
 	function getShader( type, string ) {
 
 		var shader;
@@ -1589,16 +1178,16 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	function allocateLights( scene, maxLights ) {
+	function allocateLights( lights, maxLights ) {
 
 		if ( scene ) {
 
 			var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
 			dirLights = pointLights = maxDirLights = maxPointLights = 0;
 
-			for ( l = 0, ll = scene.lights.length; l < ll; l++ ) {
+			for ( l = 0, ll = lights.length; l < ll; l++ ) {
 
-				light = scene.lights[ l ];
+				light = lights[ l ];
 
 				if ( light instanceof THREE.DirectionalLight ) dirLights++;
 				if ( light instanceof THREE.PointLight ) pointLights++;
@@ -1870,6 +1459,91 @@ THREE.Snippets = {
 		"#endif",
 		
 	"}"
+	
+	].join("\n"),
+	
+	lights_pars_fragment: [
+	
+	"#if MAX_DIR_LIGHTS > 0",
+		"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
+	"#endif",
+	
+	"#if MAX_POINT_LIGHTS > 0",
+		"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
+	"#endif",
+	
+	"varying vec3 vViewPosition;",
+	"varying vec3 vNormal;"
+	
+	].join("\n"),
+	
+	lights_fragment: [
+	
+	"vec3 normal = normalize( vNormal );",
+	"vec3 viewPosition = normalize( vViewPosition );",
+	
+	"vec4 mSpecular = vec4( specular, opacity );",
+
+	"#if MAX_POINT_LIGHTS > 0",
+		
+		"vec4 pointDiffuse  = vec4( 0.0 );",
+		"vec4 pointSpecular = vec4( 0.0 );",
+
+		"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
+
+			"vec3 pointVector = normalize( vPointLightVector[ i ] );",
+			"vec3 pointHalfVector = normalize( vPointLightVector[ i ] + vViewPosition );",
+
+			"float pointDotNormalHalf = dot( normal, pointHalfVector );",
+			"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
+
+			"float pointSpecularWeight = 0.0;",
+			"if ( pointDotNormalHalf >= 0.0 )",
+				"pointSpecularWeight = pow( pointDotNormalHalf, shininess );",
+
+			"pointDiffuse  += mColor * pointDiffuseWeight;",
+			"pointSpecular += mSpecular * pointSpecularWeight;",
+
+			"}",
+
+	"#endif",
+	
+	"#if MAX_DIR_LIGHTS > 0",
+	
+		"vec4 dirDiffuse  = vec4( 0.0 );",
+		"vec4 dirSpecular = vec4( 0.0 );" ,
+
+		"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
+
+			"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
+
+			"vec3 dirVector = normalize( lDirection.xyz );",
+			"vec3 dirHalfVector = normalize( lDirection.xyz + vViewPosition );",
+
+			"float dirDotNormalHalf = dot( normal, dirHalfVector );",
+
+			"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
+
+			"float dirSpecularWeight = 0.0;",
+			"if ( dirDotNormalHalf >= 0.0 )",
+				"dirSpecularWeight = pow( dirDotNormalHalf, shininess );",
+
+			"dirDiffuse  += mColor * dirDiffuseWeight;",
+			"dirSpecular += mSpecular * dirSpecularWeight;",
+
+		"}",
+	
+	"#endif",
+
+	"vec4 totalLight = vec4( ambient, opacity );",
+
+	"#if MAX_DIR_LIGHTS > 0",
+		"totalLight += dirDiffuse + dirSpecular;",
+	"#endif",
+	
+	"#if MAX_POINT_LIGHTS > 0",
+		"totalLight += pointDiffuse + pointSpecular;",
+	"#endif"
 
 	].join("\n")
 
@@ -1947,11 +1621,13 @@ THREE.ShaderLib = {
 		uniforms: { "color"   : { type: "c", value: new THREE.Color( 0xeeeeee ) },
 					"opacity" : { type: "f", value: 1 },
 					"map"     : { type: "t", value: 0, texture: null },
+					
 					"env_map" 		  : { type: "t", value: 1, texture: null },
 					"useRefract"	  : { type: "i", value: 0 },
 					"reflectivity"    : { type: "f", value: 1 },
 					"refraction_ratio": { type: "f", value: 0.98 },
 					"combine"		  : { type: "i", value: 0 },
+					
 					"fogDensity": { type: "f", value: 0.00025 },
 					"fogNear"	: { type: "f", value: 1 },
 					"fogFar"	: { type: "f", value: 2000 },
@@ -2073,6 +1749,107 @@ THREE.ShaderLib = {
 				THREE.Snippets[ "envmap_vertex" ],
 				
 				"vec3 transformedNormal = normalize( normalMatrix * normal );",
+				
+				THREE.Snippets[ "lights_vertex" ],
+				
+				"gl_Position = projectionMatrix * mvPosition;",
+
+			"}"
+
+		].join("\n")
+		
+	},
+	
+	'phong': {
+		
+		uniforms: { "color"   : { type: "c", value: new THREE.Color( 0xeeeeee ) },
+					"opacity" : { type: "f", value: 1 },
+					"map"     : { type: "t", value: 0, texture: null },
+					
+					"ambient" : { type: "c", value: new THREE.Color( 0x050505 ) },
+					"specular": { type: "c", value: new THREE.Color( 0x111111 ) },
+					"shininess": { type: "f", value: 30 },
+					
+					"env_map" 		  : { type: "t", value: 1, texture: null },
+					"useRefract"	  : { type: "i", value: 0 },
+					"reflectivity"    : { type: "f", value: 1 },
+					"refraction_ratio": { type: "f", value: 0.98 },
+					"combine"		  : { type: "i", value: 0 },
+					
+					"fogDensity": { type: "f", value: 0.00025 },
+					"fogNear"	: { type: "f", value: 1 },
+					"fogFar"	: { type: "f", value: 2000 },
+					"fogColor"	: { type: "c", value: new THREE.Color( 0xffffff ) },
+					
+					"enableLighting" 			: { type: "i", value: 1 },
+					"ambientLightColor" 		: { type: "fv", value: [] },
+					"directionalLightDirection" : { type: "fv", value: [] },
+					"directionalLightColor" 	: { type: "fv", value: [] },
+					"pointLightPosition"		: { type: "fv", value: [] },
+					"pointLightColor"			: { type: "fv", value: [] }
+				},
+		
+		fragment_shader: [
+			
+			"uniform vec3 color;",
+			"uniform float opacity;",
+			
+			"uniform vec3 ambient;",
+			"uniform vec3 specular;",
+			"uniform float shininess;",
+				
+			"varying vec3 vLightWeighting;",
+				
+			THREE.Snippets[ "map_pars_fragment" ],
+			THREE.Snippets[ "envmap_pars_fragment" ],
+			THREE.Snippets[ "fog_pars_fragment" ],
+			THREE.Snippets[ "lights_pars_fragment" ],
+				
+			"void main() {",
+					
+				"vec4 mColor = vec4( color, opacity );",
+				"vec4 mapColor = vec4( 1.0 );",
+				"vec4 cubeColor = vec4( 1.0 );",
+
+				THREE.Snippets[ "map_fragment" ],
+				THREE.Snippets[ "lights_fragment" ],
+
+				"gl_FragColor =  mapColor * totalLight * vec4( vLightWeighting, 1.0 );",
+				
+				THREE.Snippets[ "envmap_fragment" ],
+				THREE.Snippets[ "fog_fragment" ],
+
+			"}"
+
+		].join("\n"),
+
+		vertex_shader: [
+		
+			"#define PHONG",
+			
+			"varying vec3 vLightWeighting;",
+			"varying vec3 vViewPosition;",
+			"varying vec3 vNormal;",
+			
+			THREE.Snippets[ "map_pars_vertex" ],
+			THREE.Snippets[ "envmap_pars_vertex" ],
+			THREE.Snippets[ "lights_pars_vertex" ],
+			
+			"void main() {",
+		
+				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
+				
+				THREE.Snippets[ "map_vertex" ],
+				THREE.Snippets[ "envmap_vertex" ],
+				
+				"#ifndef USE_ENVMAP",
+					"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
+				"#endif",
+				
+				"vViewPosition = cameraPosition - mPosition.xyz;",
+				
+				"vec3 transformedNormal = normalize( normalMatrix * normal );",
+				"vNormal = transformedNormal;",
 
 				THREE.Snippets[ "lights_vertex" ],
 				

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