Sfoglia il codice sorgente

Removed no longer needed closures. See #9395.

Mr.doob 9 anni fa
parent
commit
193f62a8f1

+ 401 - 404
src/renderers/webgl/WebGLProgram.js

@@ -1,664 +1,661 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
 import { WebGLUniforms } from './WebGLUniforms';
 import { WebGLShader } from './WebGLShader';
 import { ShaderChunk } from '../shaders/ShaderChunk';
 import { NoToneMapping, AddOperation, MixOperation, MultiplyOperation, EquirectangularRefractionMapping, CubeRefractionMapping, SphericalReflectionMapping, EquirectangularReflectionMapping, CubeUVRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, CineonToneMapping, Uncharted2ToneMapping, ReinhardToneMapping, LinearToneMapping, GammaEncoding, RGBDEncoding, RGBM16Encoding, RGBM7Encoding, RGBEEncoding, sRGBEncoding, LinearEncoding } from '../../constants';
 
-var WebGLProgram;
-
-WebGLProgram = ( function () {
-
-	var programIdCount = 0;
-
-	function getEncodingComponents( encoding ) {
-
-		switch ( encoding ) {
-
-			case LinearEncoding:
-				return [ 'Linear','( value )' ];
-			case sRGBEncoding:
-				return [ 'sRGB','( value )' ];
-			case RGBEEncoding:
-				return [ 'RGBE','( value )' ];
-			case RGBM7Encoding:
-				return [ 'RGBM','( value, 7.0 )' ];
-			case RGBM16Encoding:
-				return [ 'RGBM','( value, 16.0 )' ];
-			case RGBDEncoding:
-				return [ 'RGBD','( value, 256.0 )' ];
-			case GammaEncoding:
-				return [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];
-			default:
-				throw new Error( 'unsupported encoding: ' + encoding );
-
-		}
+var programIdCount = 0;
+
+function getEncodingComponents( encoding ) {
+
+	switch ( encoding ) {
+
+		case LinearEncoding:
+			return [ 'Linear','( value )' ];
+		case sRGBEncoding:
+			return [ 'sRGB','( value )' ];
+		case RGBEEncoding:
+			return [ 'RGBE','( value )' ];
+		case RGBM7Encoding:
+			return [ 'RGBM','( value, 7.0 )' ];
+		case RGBM16Encoding:
+			return [ 'RGBM','( value, 16.0 )' ];
+		case RGBDEncoding:
+			return [ 'RGBD','( value, 256.0 )' ];
+		case GammaEncoding:
+			return [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];
+		default:
+			throw new Error( 'unsupported encoding: ' + encoding );
 
 	}
 
-	function getTexelDecodingFunction( functionName, encoding ) {
-
-		var components = getEncodingComponents( encoding );
-		return "vec4 " + functionName + "( vec4 value ) { return " + components[ 0 ] + "ToLinear" + components[ 1 ] + "; }";
+}
 
-	}
+function getTexelDecodingFunction( functionName, encoding ) {
 
-	function getTexelEncodingFunction( functionName, encoding ) {
+	var components = getEncodingComponents( encoding );
+	return "vec4 " + functionName + "( vec4 value ) { return " + components[ 0 ] + "ToLinear" + components[ 1 ] + "; }";
 
-		var components = getEncodingComponents( encoding );
-		return "vec4 " + functionName + "( vec4 value ) { return LinearTo" + components[ 0 ] + components[ 1 ] + "; }";
+}
 
-	}
+function getTexelEncodingFunction( functionName, encoding ) {
 
-	function getToneMappingFunction( functionName, toneMapping ) {
+	var components = getEncodingComponents( encoding );
+	return "vec4 " + functionName + "( vec4 value ) { return LinearTo" + components[ 0 ] + components[ 1 ] + "; }";
 
-		var toneMappingName;
+}
 
-		switch ( toneMapping ) {
+function getToneMappingFunction( functionName, toneMapping ) {
 
-			case LinearToneMapping:
-				toneMappingName = "Linear";
-				break;
+	var toneMappingName;
 
-			case ReinhardToneMapping:
-				toneMappingName = "Reinhard";
-				break;
+	switch ( toneMapping ) {
 
-			case Uncharted2ToneMapping:
-				toneMappingName = "Uncharted2";
-				break;
+		case LinearToneMapping:
+			toneMappingName = "Linear";
+			break;
 
-			case CineonToneMapping:
-				toneMappingName = "OptimizedCineon";
-				break;
+		case ReinhardToneMapping:
+			toneMappingName = "Reinhard";
+			break;
 
-			default:
-				throw new Error( 'unsupported toneMapping: ' + toneMapping );
+		case Uncharted2ToneMapping:
+			toneMappingName = "Uncharted2";
+			break;
 
-		}
+		case CineonToneMapping:
+			toneMappingName = "OptimizedCineon";
+			break;
 
-		return "vec3 " + functionName + "( vec3 color ) { return " + toneMappingName + "ToneMapping( color ); }";
+		default:
+			throw new Error( 'unsupported toneMapping: ' + toneMapping );
 
 	}
 
-	function generateExtensions( extensions, parameters, rendererExtensions ) {
+	return "vec3 " + functionName + "( vec3 color ) { return " + toneMappingName + "ToneMapping( color ); }";
 
-		extensions = extensions || {};
+}
 
-		var chunks = [
-			( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',
-			( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',
-			( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',
-			( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '',
-		];
+function generateExtensions( extensions, parameters, rendererExtensions ) {
 
-		return chunks.filter( filterEmptyLine ).join( '\n' );
+	extensions = extensions || {};
 
-	}
+	var chunks = [
+		( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',
+		( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',
+		( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',
+		( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '',
+	];
 
-	function generateDefines( defines ) {
+	return chunks.filter( filterEmptyLine ).join( '\n' );
 
-		var chunks = [];
+}
 
-		for ( var name in defines ) {
+function generateDefines( defines ) {
 
-			var value = defines[ name ];
+	var chunks = [];
 
-			if ( value === false ) continue;
+	for ( var name in defines ) {
 
-			chunks.push( '#define ' + name + ' ' + value );
+		var value = defines[ name ];
 
-		}
+		if ( value === false ) continue;
 
-		return chunks.join( '\n' );
+		chunks.push( '#define ' + name + ' ' + value );
 
 	}
 
-	function fetchAttributeLocations( gl, program, identifiers ) {
+	return chunks.join( '\n' );
 
-		var attributes = {};
+}
 
-		var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );
+function fetchAttributeLocations( gl, program, identifiers ) {
 
-		for ( var i = 0; i < n; i ++ ) {
+	var attributes = {};
 
-			var info = gl.getActiveAttrib( program, i );
-			var name = info.name;
+	var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );
 
-			// console.log("THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:", name, i );
+	for ( var i = 0; i < n; i ++ ) {
 
-			attributes[ name ] = gl.getAttribLocation( program, name );
+		var info = gl.getActiveAttrib( program, i );
+		var name = info.name;
 
-		}
+		// console.log("THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:", name, i );
 
-		return attributes;
+		attributes[ name ] = gl.getAttribLocation( program, name );
 
 	}
 
-	function filterEmptyLine( string ) {
+	return attributes;
 
-		return string !== '';
+}
 
-	}
+function filterEmptyLine( string ) {
 
-	function replaceLightNums( string, parameters ) {
+	return string !== '';
 
-		return string
-			.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
-			.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
-			.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
-			.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );
+}
 
-	}
+function replaceLightNums( string, parameters ) {
 
-	function parseIncludes( string ) {
+	return string
+		.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
+		.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
+		.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
+		.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );
 
-		var pattern = /#include +<([\w\d.]+)>/g;
+}
 
-		function replace( match, include ) {
+function parseIncludes( string ) {
 
-			var replace = ShaderChunk[ include ];
+	var pattern = /#include +<([\w\d.]+)>/g;
 
-			if ( replace === undefined ) {
+	function replace( match, include ) {
 
-				throw new Error( 'Can not resolve #include <' + include + '>' );
+		var replace = ShaderChunk[ include ];
 
-			}
+		if ( replace === undefined ) {
 
-			return parseIncludes( replace );
+			throw new Error( 'Can not resolve #include <' + include + '>' );
 
 		}
 
-		return string.replace( pattern, replace );
+		return parseIncludes( replace );
 
 	}
 
-	function unrollLoops( string ) {
+	return string.replace( pattern, replace );
 
-		var pattern = /for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
+}
 
-		function replace( match, start, end, snippet ) {
+function unrollLoops( string ) {
 
-			var unroll = '';
+	var pattern = /for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
 
-			for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {
+	function replace( match, start, end, snippet ) {
 
-				unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' );
+		var unroll = '';
 
-			}
+		for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {
 
-			return unroll;
+			unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' );
 
 		}
 
-		return string.replace( pattern, replace );
+		return unroll;
 
 	}
 
-	return function WebGLProgram( renderer, code, material, parameters ) {
+	return string.replace( pattern, replace );
 
-		var gl = renderer.context;
+}
 
-		var extensions = material.extensions;
-		var defines = material.defines;
+function WebGLProgram( renderer, code, material, parameters ) {
 
-		var vertexShader = material.__webglShader.vertexShader;
-		var fragmentShader = material.__webglShader.fragmentShader;
+	var gl = renderer.context;
 
-		var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
+	var extensions = material.extensions;
+	var defines = material.defines;
 
-		if ( parameters.shadowMapType === PCFShadowMap ) {
+	var vertexShader = material.__webglShader.vertexShader;
+	var fragmentShader = material.__webglShader.fragmentShader;
 
-			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
+	var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
 
-		} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
+	if ( parameters.shadowMapType === PCFShadowMap ) {
 
-			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
+		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
 
-		}
-
-		var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
-		var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
-		var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
+	} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
 
-		if ( parameters.envMap ) {
+		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
 
-			switch ( material.envMap.mapping ) {
+	}
 
-				case CubeReflectionMapping:
-				case CubeRefractionMapping:
-					envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
-					break;
+	var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
+	var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
+	var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
 
-				case CubeUVReflectionMapping:
-				case CubeUVRefractionMapping:
-					envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
-					break;
+	if ( parameters.envMap ) {
 
-				case EquirectangularReflectionMapping:
-				case EquirectangularRefractionMapping:
-					envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
-					break;
+		switch ( material.envMap.mapping ) {
 
-				case SphericalReflectionMapping:
-					envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
-					break;
+			case CubeReflectionMapping:
+			case CubeRefractionMapping:
+				envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
+				break;
 
-			}
+			case CubeUVReflectionMapping:
+			case CubeUVRefractionMapping:
+				envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
+				break;
 
-			switch ( material.envMap.mapping ) {
+			case EquirectangularReflectionMapping:
+			case EquirectangularRefractionMapping:
+				envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
+				break;
 
-				case CubeRefractionMapping:
-				case EquirectangularRefractionMapping:
-					envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
-					break;
+			case SphericalReflectionMapping:
+				envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
+				break;
 
-			}
+		}
 
-			switch ( material.combine ) {
+		switch ( material.envMap.mapping ) {
 
-				case MultiplyOperation:
-					envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
-					break;
+			case CubeRefractionMapping:
+			case EquirectangularRefractionMapping:
+				envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
+				break;
 
-				case MixOperation:
-					envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
-					break;
+		}
 
-				case AddOperation:
-					envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
-					break;
+		switch ( material.combine ) {
 
-			}
+			case MultiplyOperation:
+				envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
+				break;
 
-		}
+			case MixOperation:
+				envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
+				break;
 
-		var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
+			case AddOperation:
+				envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
+				break;
 
-		// console.log( 'building new program ' );
+		}
 
-		//
+	}
 
-		var customExtensions = generateExtensions( extensions, parameters, renderer.extensions );
+	var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
 
-		var customDefines = generateDefines( defines );
+	// console.log( 'building new program ' );
 
-		//
+	//
 
-		var program = gl.createProgram();
+	var customExtensions = generateExtensions( extensions, parameters, renderer.extensions );
 
-		var prefixVertex, prefixFragment;
+	var customDefines = generateDefines( defines );
 
-		if ( (material && material.isRawShaderMaterial) ) {
+	//
 
-			prefixVertex = [
+	var program = gl.createProgram();
 
-				customDefines
+	var prefixVertex, prefixFragment;
 
-			].filter( filterEmptyLine ).join( '\n' );
+	if ( (material && material.isRawShaderMaterial) ) {
 
-			prefixFragment = [
+		prefixVertex = [
 
-				customDefines
+			customDefines
 
-			].filter( filterEmptyLine ).join( '\n' );
+		].filter( filterEmptyLine ).join( '\n' );
 
-		} else {
+		prefixFragment = [
 
-			prefixVertex = [
+			customDefines
 
-				'precision ' + parameters.precision + ' float;',
-				'precision ' + parameters.precision + ' int;',
+		].filter( filterEmptyLine ).join( '\n' );
 
-				'#define SHADER_NAME ' + material.__webglShader.name,
+	} else {
 
-				customDefines,
+		prefixVertex = [
 
-				parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
+			'precision ' + parameters.precision + ' float;',
+			'precision ' + parameters.precision + ' int;',
 
-				'#define GAMMA_FACTOR ' + gammaFactorDefine,
+			'#define SHADER_NAME ' + material.__webglShader.name,
 
-				'#define MAX_BONES ' + parameters.maxBones,
+			customDefines,
 
-				parameters.map ? '#define USE_MAP' : '',
-				parameters.envMap ? '#define USE_ENVMAP' : '',
-				parameters.envMap ? '#define ' + envMapModeDefine : '',
-				parameters.lightMap ? '#define USE_LIGHTMAP' : '',
-				parameters.aoMap ? '#define USE_AOMAP' : '',
-				parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
-				parameters.bumpMap ? '#define USE_BUMPMAP' : '',
-				parameters.normalMap ? '#define USE_NORMALMAP' : '',
-				parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
-				parameters.specularMap ? '#define USE_SPECULARMAP' : '',
-				parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
-				parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
-				parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
-				parameters.vertexColors ? '#define USE_COLOR' : '',
+			parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
 
-				parameters.flatShading ? '#define FLAT_SHADED' : '',
+			'#define GAMMA_FACTOR ' + gammaFactorDefine,
 
-				parameters.skinning ? '#define USE_SKINNING' : '',
-				parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
+			'#define MAX_BONES ' + parameters.maxBones,
 
-				parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
-				parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
-				parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
-				parameters.flipSided ? '#define FLIP_SIDED' : '',
+			parameters.map ? '#define USE_MAP' : '',
+			parameters.envMap ? '#define USE_ENVMAP' : '',
+			parameters.envMap ? '#define ' + envMapModeDefine : '',
+			parameters.lightMap ? '#define USE_LIGHTMAP' : '',
+			parameters.aoMap ? '#define USE_AOMAP' : '',
+			parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
+			parameters.bumpMap ? '#define USE_BUMPMAP' : '',
+			parameters.normalMap ? '#define USE_NORMALMAP' : '',
+			parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
+			parameters.specularMap ? '#define USE_SPECULARMAP' : '',
+			parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
+			parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
+			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
+			parameters.vertexColors ? '#define USE_COLOR' : '',
 
-				'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
+			parameters.flatShading ? '#define FLAT_SHADED' : '',
 
-				parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
-				parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
+			parameters.skinning ? '#define USE_SKINNING' : '',
+			parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
 
-				parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
+			parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
+			parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
+			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
+			parameters.flipSided ? '#define FLIP_SIDED' : '',
 
-				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
-				parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
+			'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
 
-				'uniform mat4 modelMatrix;',
-				'uniform mat4 modelViewMatrix;',
-				'uniform mat4 projectionMatrix;',
-				'uniform mat4 viewMatrix;',
-				'uniform mat3 normalMatrix;',
-				'uniform vec3 cameraPosition;',
+			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
+			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
 
-				'attribute vec3 position;',
-				'attribute vec3 normal;',
-				'attribute vec2 uv;',
+			parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
 
-				'#ifdef USE_COLOR',
+			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
+			parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
 
-				'	attribute vec3 color;',
+			'uniform mat4 modelMatrix;',
+			'uniform mat4 modelViewMatrix;',
+			'uniform mat4 projectionMatrix;',
+			'uniform mat4 viewMatrix;',
+			'uniform mat3 normalMatrix;',
+			'uniform vec3 cameraPosition;',
 
-				'#endif',
+			'attribute vec3 position;',
+			'attribute vec3 normal;',
+			'attribute vec2 uv;',
 
-				'#ifdef USE_MORPHTARGETS',
+			'#ifdef USE_COLOR',
 
-				'	attribute vec3 morphTarget0;',
-				'	attribute vec3 morphTarget1;',
-				'	attribute vec3 morphTarget2;',
-				'	attribute vec3 morphTarget3;',
+			'	attribute vec3 color;',
 
-				'	#ifdef USE_MORPHNORMALS',
+			'#endif',
 
-				'		attribute vec3 morphNormal0;',
-				'		attribute vec3 morphNormal1;',
-				'		attribute vec3 morphNormal2;',
-				'		attribute vec3 morphNormal3;',
+			'#ifdef USE_MORPHTARGETS',
 
-				'	#else',
+			'	attribute vec3 morphTarget0;',
+			'	attribute vec3 morphTarget1;',
+			'	attribute vec3 morphTarget2;',
+			'	attribute vec3 morphTarget3;',
 
-				'		attribute vec3 morphTarget4;',
-				'		attribute vec3 morphTarget5;',
-				'		attribute vec3 morphTarget6;',
-				'		attribute vec3 morphTarget7;',
+			'	#ifdef USE_MORPHNORMALS',
 
-				'	#endif',
+			'		attribute vec3 morphNormal0;',
+			'		attribute vec3 morphNormal1;',
+			'		attribute vec3 morphNormal2;',
+			'		attribute vec3 morphNormal3;',
 
-				'#endif',
+			'	#else',
 
-				'#ifdef USE_SKINNING',
+			'		attribute vec3 morphTarget4;',
+			'		attribute vec3 morphTarget5;',
+			'		attribute vec3 morphTarget6;',
+			'		attribute vec3 morphTarget7;',
 
-				'	attribute vec4 skinIndex;',
-				'	attribute vec4 skinWeight;',
+			'	#endif',
 
-				'#endif',
+			'#endif',
 
-				'\n'
+			'#ifdef USE_SKINNING',
 
-			].filter( filterEmptyLine ).join( '\n' );
+			'	attribute vec4 skinIndex;',
+			'	attribute vec4 skinWeight;',
 
-			prefixFragment = [
+			'#endif',
 
-				customExtensions,
+			'\n'
 
-				'precision ' + parameters.precision + ' float;',
-				'precision ' + parameters.precision + ' int;',
+		].filter( filterEmptyLine ).join( '\n' );
 
-				'#define SHADER_NAME ' + material.__webglShader.name,
+		prefixFragment = [
 
-				customDefines,
+			customExtensions,
 
-				parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',
+			'precision ' + parameters.precision + ' float;',
+			'precision ' + parameters.precision + ' int;',
 
-				'#define GAMMA_FACTOR ' + gammaFactorDefine,
+			'#define SHADER_NAME ' + material.__webglShader.name,
 
-				( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
-				( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
+			customDefines,
 
-				parameters.map ? '#define USE_MAP' : '',
-				parameters.envMap ? '#define USE_ENVMAP' : '',
-				parameters.envMap ? '#define ' + envMapTypeDefine : '',
-				parameters.envMap ? '#define ' + envMapModeDefine : '',
-				parameters.envMap ? '#define ' + envMapBlendingDefine : '',
-				parameters.lightMap ? '#define USE_LIGHTMAP' : '',
-				parameters.aoMap ? '#define USE_AOMAP' : '',
-				parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
-				parameters.bumpMap ? '#define USE_BUMPMAP' : '',
-				parameters.normalMap ? '#define USE_NORMALMAP' : '',
-				parameters.specularMap ? '#define USE_SPECULARMAP' : '',
-				parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
-				parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
-				parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
-				parameters.vertexColors ? '#define USE_COLOR' : '',
+			parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',
 
-				parameters.flatShading ? '#define FLAT_SHADED' : '',
+			'#define GAMMA_FACTOR ' + gammaFactorDefine,
 
-				parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
-				parameters.flipSided ? '#define FLIP_SIDED' : '',
+			( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
+			( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
 
-				'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
+			parameters.map ? '#define USE_MAP' : '',
+			parameters.envMap ? '#define USE_ENVMAP' : '',
+			parameters.envMap ? '#define ' + envMapTypeDefine : '',
+			parameters.envMap ? '#define ' + envMapModeDefine : '',
+			parameters.envMap ? '#define ' + envMapBlendingDefine : '',
+			parameters.lightMap ? '#define USE_LIGHTMAP' : '',
+			parameters.aoMap ? '#define USE_AOMAP' : '',
+			parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
+			parameters.bumpMap ? '#define USE_BUMPMAP' : '',
+			parameters.normalMap ? '#define USE_NORMALMAP' : '',
+			parameters.specularMap ? '#define USE_SPECULARMAP' : '',
+			parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
+			parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
+			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
+			parameters.vertexColors ? '#define USE_COLOR' : '',
 
-				parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
-				parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
+			parameters.flatShading ? '#define FLAT_SHADED' : '',
 
-				parameters.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : '',
+			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
+			parameters.flipSided ? '#define FLIP_SIDED' : '',
 
-				parameters.physicallyCorrectLights ? "#define PHYSICALLY_CORRECT_LIGHTS" : '',
+			'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
 
-				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
-				parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
+			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
+			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
 
-				parameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',
+			parameters.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : '',
 
-				'uniform mat4 viewMatrix;',
-				'uniform vec3 cameraPosition;',
+			parameters.physicallyCorrectLights ? "#define PHYSICALLY_CORRECT_LIGHTS" : '',
 
-				( parameters.toneMapping !== NoToneMapping ) ? "#define TONE_MAPPING" : '',
-				( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '',  // this code is required here because it is used by the toneMapping() function defined below
-				( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( "toneMapping", parameters.toneMapping ) : '',
+			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
+			parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
 
-				( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below
-				parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
-				parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
-				parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
-				parameters.outputEncoding ? getTexelEncodingFunction( "linearToOutputTexel", parameters.outputEncoding ) : '',
+			parameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',
 
-				parameters.depthPacking ? "#define DEPTH_PACKING " + material.depthPacking : '',
+			'uniform mat4 viewMatrix;',
+			'uniform vec3 cameraPosition;',
 
-				'\n'
+			( parameters.toneMapping !== NoToneMapping ) ? "#define TONE_MAPPING" : '',
+			( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '',  // this code is required here because it is used by the toneMapping() function defined below
+			( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( "toneMapping", parameters.toneMapping ) : '',
 
-			].filter( filterEmptyLine ).join( '\n' );
+			( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below
+			parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
+			parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
+			parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
+			parameters.outputEncoding ? getTexelEncodingFunction( "linearToOutputTexel", parameters.outputEncoding ) : '',
 
-		}
+			parameters.depthPacking ? "#define DEPTH_PACKING " + material.depthPacking : '',
 
-		vertexShader = parseIncludes( vertexShader, parameters );
-		vertexShader = replaceLightNums( vertexShader, parameters );
+			'\n'
 
-		fragmentShader = parseIncludes( fragmentShader, parameters );
-		fragmentShader = replaceLightNums( fragmentShader, parameters );
+		].filter( filterEmptyLine ).join( '\n' );
 
-		if ( (material && material.isShaderMaterial) === false ) {
+	}
 
-			vertexShader = unrollLoops( vertexShader );
-			fragmentShader = unrollLoops( fragmentShader );
+	vertexShader = parseIncludes( vertexShader, parameters );
+	vertexShader = replaceLightNums( vertexShader, parameters );
 
-		}
+	fragmentShader = parseIncludes( fragmentShader, parameters );
+	fragmentShader = replaceLightNums( fragmentShader, parameters );
 
-		var vertexGlsl = prefixVertex + vertexShader;
-		var fragmentGlsl = prefixFragment + fragmentShader;
+	if ( (material && material.isShaderMaterial) === false ) {
 
-		// console.log( '*VERTEX*', vertexGlsl );
-		// console.log( '*FRAGMENT*', fragmentGlsl );
+		vertexShader = unrollLoops( vertexShader );
+		fragmentShader = unrollLoops( fragmentShader );
 
-		var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
-		var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
+	}
 
-		gl.attachShader( program, glVertexShader );
-		gl.attachShader( program, glFragmentShader );
+	var vertexGlsl = prefixVertex + vertexShader;
+	var fragmentGlsl = prefixFragment + fragmentShader;
 
-		// Force a particular attribute to index 0.
+	// console.log( '*VERTEX*', vertexGlsl );
+	// console.log( '*FRAGMENT*', fragmentGlsl );
 
-		if ( material.index0AttributeName !== undefined ) {
+	var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
+	var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
 
-			gl.bindAttribLocation( program, 0, material.index0AttributeName );
+	gl.attachShader( program, glVertexShader );
+	gl.attachShader( program, glFragmentShader );
 
-		} else if ( parameters.morphTargets === true ) {
+	// Force a particular attribute to index 0.
 
-			// programs with morphTargets displace position out of attribute 0
-			gl.bindAttribLocation( program, 0, 'position' );
+	if ( material.index0AttributeName !== undefined ) {
 
-		}
+		gl.bindAttribLocation( program, 0, material.index0AttributeName );
 
-		gl.linkProgram( program );
+	} else if ( parameters.morphTargets === true ) {
 
-		var programLog = gl.getProgramInfoLog( program );
-		var vertexLog = gl.getShaderInfoLog( glVertexShader );
-		var fragmentLog = gl.getShaderInfoLog( glFragmentShader );
+		// programs with morphTargets displace position out of attribute 0
+		gl.bindAttribLocation( program, 0, 'position' );
 
-		var runnable = true;
-		var haveDiagnostics = true;
+	}
 
-		// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );
-		// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );
+	gl.linkProgram( program );
 
-		if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
+	var programLog = gl.getProgramInfoLog( program );
+	var vertexLog = gl.getShaderInfoLog( glVertexShader );
+	var fragmentLog = gl.getShaderInfoLog( glFragmentShader );
 
-			runnable = false;
+	var runnable = true;
+	var haveDiagnostics = true;
 
-			console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );
+	// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );
+	// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );
 
-		} else if ( programLog !== '' ) {
+	if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
 
-			console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
+		runnable = false;
 
-		} else if ( vertexLog === '' || fragmentLog === '' ) {
+		console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );
 
-			haveDiagnostics = false;
+	} else if ( programLog !== '' ) {
 
-		}
+		console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
 
-		if ( haveDiagnostics ) {
+	} else if ( vertexLog === '' || fragmentLog === '' ) {
 
-			this.diagnostics = {
+		haveDiagnostics = false;
 
-				runnable: runnable,
-				material: material,
+	}
 
-				programLog: programLog,
+	if ( haveDiagnostics ) {
 
-				vertexShader: {
+		this.diagnostics = {
 
-					log: vertexLog,
-					prefix: prefixVertex
+			runnable: runnable,
+			material: material,
 
-				},
+			programLog: programLog,
 
-				fragmentShader: {
+			vertexShader: {
 
-					log: fragmentLog,
-					prefix: prefixFragment
+				log: vertexLog,
+				prefix: prefixVertex
 
-				}
+			},
 
-			};
+			fragmentShader: {
 
-		}
+				log: fragmentLog,
+				prefix: prefixFragment
 
-		// clean up
+			}
 
-		gl.deleteShader( glVertexShader );
-		gl.deleteShader( glFragmentShader );
+		};
 
-		// set up caching for uniform locations
+	}
 
-		var cachedUniforms;
+	// clean up
 
-		this.getUniforms = function() {
+	gl.deleteShader( glVertexShader );
+	gl.deleteShader( glFragmentShader );
 
-			if ( cachedUniforms === undefined ) {
+	// set up caching for uniform locations
 
-				cachedUniforms =
-						new WebGLUniforms( gl, program, renderer );
+	var cachedUniforms;
 
-			}
+	this.getUniforms = function() {
 
-			return cachedUniforms;
+		if ( cachedUniforms === undefined ) {
 
-		};
+			cachedUniforms =
+					new WebGLUniforms( gl, program, renderer );
 
-		// set up caching for attribute locations
+		}
 
-		var cachedAttributes;
+		return cachedUniforms;
 
-		this.getAttributes = function() {
+	};
 
-			if ( cachedAttributes === undefined ) {
+	// set up caching for attribute locations
 
-				cachedAttributes = fetchAttributeLocations( gl, program );
+	var cachedAttributes;
 
-			}
+	this.getAttributes = function() {
 
-			return cachedAttributes;
+		if ( cachedAttributes === undefined ) {
 
-		};
+			cachedAttributes = fetchAttributeLocations( gl, program );
 
-		// free resource
+		}
 
-		this.destroy = function() {
+		return cachedAttributes;
 
-			gl.deleteProgram( program );
-			this.program = undefined;
+	};
 
-		};
+	// free resource
 
-		// DEPRECATED
+	this.destroy = function() {
 
-		Object.defineProperties( this, {
+		gl.deleteProgram( program );
+		this.program = undefined;
 
-			uniforms: {
-				get: function() {
+	};
 
-					console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );
-					return this.getUniforms();
+	// DEPRECATED
 
-				}
-			},
+	Object.defineProperties( this, {
 
-			attributes: {
-				get: function() {
+		uniforms: {
+			get: function() {
 
-					console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );
-					return this.getAttributes();
+				console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );
+				return this.getUniforms();
 
-				}
 			}
+		},
 
-		} );
+		attributes: {
+			get: function() {
 
+				console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );
+				return this.getAttributes();
 
-		//
+			}
+		}
 
-		this.id = programIdCount ++;
-		this.code = code;
-		this.usedTimes = 1;
-		this.program = program;
-		this.vertexShader = glVertexShader;
-		this.fragmentShader = glFragmentShader;
+	} );
 
-		return this;
 
-	};
+	//
+
+	this.id = programIdCount ++;
+	this.code = code;
+	this.usedTimes = 1;
+	this.program = program;
+	this.vertexShader = glVertexShader;
+	this.fragmentShader = glFragmentShader;
 
-} )();
+	return this;
 
+}
 
-export { WebGLProgram };
+export { WebGLProgram };

+ 24 - 27
src/renderers/webgl/WebGLShader.js

@@ -1,48 +1,45 @@
-var WebGLShader;
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
 
-WebGLShader = ( function () {
+function addLineNumbers( string ) {
 
-	function addLineNumbers( string ) {
+	var lines = string.split( '\n' );
 
-		var lines = string.split( '\n' );
+	for ( var i = 0; i < lines.length; i ++ ) {
 
-		for ( var i = 0; i < lines.length; i ++ ) {
-
-			lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];
-
-		}
-
-		return lines.join( '\n' );
+		lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];
 
 	}
 
-	return function WebGLShader( gl, type, string ) {
+	return lines.join( '\n' );
 
-		var shader = gl.createShader( type );
+}
 
-		gl.shaderSource( shader, string );
-		gl.compileShader( shader );
+function WebGLShader( gl, type, string ) {
 
-		if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {
+	var shader = gl.createShader( type );
 
-			console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' );
+	gl.shaderSource( shader, string );
+	gl.compileShader( shader );
 
-		}
+	if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {
 
-		if ( gl.getShaderInfoLog( shader ) !== '' ) {
+		console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' );
 
-			console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );
+	}
 
-		}
+	if ( gl.getShaderInfoLog( shader ) !== '' ) {
 
-		// --enable-privileged-webgl-extension
-		// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
+		console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );
 
-		return shader;
+	}
 
-	};
+	// --enable-privileged-webgl-extension
+	// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
 
-} )();
+	return shader;
 
+}
 
-export { WebGLShader };
+export { WebGLShader };

+ 311 - 323
src/renderers/webgl/WebGLUniforms.js

@@ -1,9 +1,5 @@
-import { CubeTexture } from '../../textures/CubeTexture';
-import { Texture } from '../../textures/Texture';
-
-var WebGLUniforms;
-
 /**
+ * @author tschw
  *
  * Uniforms of a program.
  * Those form a tree structure with a special top-level container for the root,
@@ -53,551 +49,543 @@ var WebGLUniforms;
  *
  * 		like .set for an optional property of the object
  *
- *
- * @author tschw
- *
  */
 
-WebGLUniforms = ( function() { // scope
+import { CubeTexture } from '../../textures/CubeTexture';
+import { Texture } from '../../textures/Texture';
 
-	var emptyTexture = new Texture();
-	var emptyCubeTexture = new CubeTexture();
+var emptyTexture = new Texture();
+var emptyCubeTexture = new CubeTexture();
 
-	// --- Base for inner nodes (including the root) ---
+// --- Base for inner nodes (including the root) ---
 
-	var UniformContainer = function() {
+function UniformContainer() {
 
-			this.seq = [];
-			this.map = {};
+	this.seq = [];
+	this.map = {};
 
-		},
+}
 
-	// --- Utilities ---
+// --- Utilities ---
 
-	// Array Caches (provide typed arrays for temporary by size)
+// Array Caches (provide typed arrays for temporary by size)
 
-		arrayCacheF32 = [],
-		arrayCacheI32 = [],
+var arrayCacheF32 = [];
+var arrayCacheI32 = [];
 
-	// Flattening for arrays of vectors and matrices
+// Flattening for arrays of vectors and matrices
 
-		flatten = function( array, nBlocks, blockSize ) {
+function flatten( array, nBlocks, blockSize ) {
 
-			var firstElem = array[ 0 ];
+	var firstElem = array[ 0 ];
 
-			if ( firstElem <= 0 || firstElem > 0 ) return array;
-			// unoptimized: ! isNaN( firstElem )
-			// see http://jacksondunstan.com/articles/983
+	if ( firstElem <= 0 || firstElem > 0 ) return array;
+	// unoptimized: ! isNaN( firstElem )
+	// see http://jacksondunstan.com/articles/983
 
-			var n = nBlocks * blockSize,
-				r = arrayCacheF32[ n ];
+	var n = nBlocks * blockSize,
+		r = arrayCacheF32[ n ];
 
-			if ( r === undefined ) {
+	if ( r === undefined ) {
 
-				r = new Float32Array( n );
-				arrayCacheF32[ n ] = r;
+		r = new Float32Array( n );
+		arrayCacheF32[ n ] = r;
 
-			}
+	}
 
-			if ( nBlocks !== 0 ) {
+	if ( nBlocks !== 0 ) {
 
-				firstElem.toArray( r, 0 );
+		firstElem.toArray( r, 0 );
 
-				for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {
+		for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {
 
-					offset += blockSize;
-					array[ i ].toArray( r, offset );
+			offset += blockSize;
+			array[ i ].toArray( r, offset );
 
-				}
+		}
 
-			}
+	}
 
-			return r;
+	return r;
 
-		},
+}
 
-	// Texture unit allocation
+// Texture unit allocation
 
-		allocTexUnits = function( renderer, n ) {
+function allocTexUnits( renderer, n ) {
 
-			var r = arrayCacheI32[ n ];
+	var r = arrayCacheI32[ n ];
 
-			if ( r === undefined ) {
+	if ( r === undefined ) {
 
-				r = new Int32Array( n );
-				arrayCacheI32[ n ] = r;
+		r = new Int32Array( n );
+		arrayCacheI32[ n ] = r;
 
-			}
+	}
 
-			for ( var i = 0; i !== n; ++ i )
-				r[ i ] = renderer.allocTextureUnit();
+	for ( var i = 0; i !== n; ++ i )
+		r[ i ] = renderer.allocTextureUnit();
 
-			return r;
+	return r;
 
-		},
+}
 
-	// --- Setters ---
+// --- Setters ---
 
-	// Note: Defining these methods externally, because they come in a bunch
-	// and this way their names minify.
+// Note: Defining these methods externally, because they come in a bunch
+// and this way their names minify.
 
-		// Single scalar
+// Single scalar
 
-		setValue1f = function( gl, v ) { gl.uniform1f( this.addr, v ); },
-		setValue1i = function( gl, v ) { gl.uniform1i( this.addr, v ); },
+function setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }
+function setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }
 
-		// Single float vector (from flat array or THREE.VectorN)
+// Single float vector (from flat array or THREE.VectorN)
 
-		setValue2fv = function( gl, v ) {
+function setValue2fv( gl, v ) {
 
-			if ( v.x === undefined ) gl.uniform2fv( this.addr, v );
-			else gl.uniform2f( this.addr, v.x, v.y );
+	if ( v.x === undefined ) gl.uniform2fv( this.addr, v );
+	else gl.uniform2f( this.addr, v.x, v.y );
 
-		},
+}
 
-		setValue3fv = function( gl, v ) {
+function setValue3fv( gl, v ) {
 
-			if ( v.x !== undefined )
-				gl.uniform3f( this.addr, v.x, v.y, v.z );
-			else if ( v.r !== undefined )
-				gl.uniform3f( this.addr, v.r, v.g, v.b );
-			else
-				gl.uniform3fv( this.addr, v );
+	if ( v.x !== undefined )
+		gl.uniform3f( this.addr, v.x, v.y, v.z );
+	else if ( v.r !== undefined )
+		gl.uniform3f( this.addr, v.r, v.g, v.b );
+	else
+		gl.uniform3fv( this.addr, v );
 
-		},
+}
 
-		setValue4fv = function( gl, v ) {
+function setValue4fv( gl, v ) {
 
-			if ( v.x === undefined ) gl.uniform4fv( this.addr, v );
-			else gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );
+	if ( v.x === undefined ) gl.uniform4fv( this.addr, v );
+	else gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );
 
-		},
+}
 
-		// Single matrix (from flat array or MatrixN)
+// Single matrix (from flat array or MatrixN)
 
-		setValue2fm = function( gl, v ) {
+function setValue2fm( gl, v ) {
 
-			gl.uniformMatrix2fv( this.addr, false, v.elements || v );
+	gl.uniformMatrix2fv( this.addr, false, v.elements || v );
 
-		},
+}
 
-		setValue3fm = function( gl, v ) {
+function setValue3fm( gl, v ) {
 
-			gl.uniformMatrix3fv( this.addr, false, v.elements || v );
+	gl.uniformMatrix3fv( this.addr, false, v.elements || v );
 
-		},
+}
 
-		setValue4fm = function( gl, v ) {
+function setValue4fm( gl, v ) {
 
-			gl.uniformMatrix4fv( this.addr, false, v.elements || v );
+	gl.uniformMatrix4fv( this.addr, false, v.elements || v );
 
-		},
+}
 
-		// Single texture (2D / Cube)
+// Single texture (2D / Cube)
 
-		setValueT1 = function( gl, v, renderer ) {
+function setValueT1( gl, v, renderer ) {
 
-			var unit = renderer.allocTextureUnit();
-			gl.uniform1i( this.addr, unit );
-			renderer.setTexture2D( v || emptyTexture, unit );
+	var unit = renderer.allocTextureUnit();
+	gl.uniform1i( this.addr, unit );
+	renderer.setTexture2D( v || emptyTexture, unit );
 
-		},
+}
 
-		setValueT6 = function( gl, v, renderer ) {
+function setValueT6( gl, v, renderer ) {
 
-			var unit = renderer.allocTextureUnit();
-			gl.uniform1i( this.addr, unit );
-			renderer.setTextureCube( v || emptyCubeTexture, unit );
+	var unit = renderer.allocTextureUnit();
+	gl.uniform1i( this.addr, unit );
+	renderer.setTextureCube( v || emptyCubeTexture, unit );
 
-		},
+}
 
-		// Integer / Boolean vectors or arrays thereof (always flat arrays)
+// Integer / Boolean vectors or arrays thereof (always flat arrays)
 
-		setValue2iv = function( gl, v ) { gl.uniform2iv( this.addr, v ); },
-		setValue3iv = function( gl, v ) { gl.uniform3iv( this.addr, v ); },
-		setValue4iv = function( gl, v ) { gl.uniform4iv( this.addr, v ); },
+function setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }
+function setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }
+function setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }
 
-		// Helper to pick the right setter for the singular case
+// Helper to pick the right setter for the singular case
 
-		getSingularSetter = function( type ) {
+function getSingularSetter( type ) {
 
-			switch ( type ) {
+	switch ( type ) {
 
-				case 0x1406: return setValue1f; // FLOAT
-				case 0x8b50: return setValue2fv; // _VEC2
-				case 0x8b51: return setValue3fv; // _VEC3
-				case 0x8b52: return setValue4fv; // _VEC4
+		case 0x1406: return setValue1f; // FLOAT
+		case 0x8b50: return setValue2fv; // _VEC2
+		case 0x8b51: return setValue3fv; // _VEC3
+		case 0x8b52: return setValue4fv; // _VEC4
 
-				case 0x8b5a: return setValue2fm; // _MAT2
-				case 0x8b5b: return setValue3fm; // _MAT3
-				case 0x8b5c: return setValue4fm; // _MAT4
+		case 0x8b5a: return setValue2fm; // _MAT2
+		case 0x8b5b: return setValue3fm; // _MAT3
+		case 0x8b5c: return setValue4fm; // _MAT4
 
-				case 0x8b5e: return setValueT1; // SAMPLER_2D
-				case 0x8b60: return setValueT6; // SAMPLER_CUBE
+		case 0x8b5e: return setValueT1; // SAMPLER_2D
+		case 0x8b60: return setValueT6; // SAMPLER_CUBE
 
-				case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL
-				case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
-				case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
-				case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
+		case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL
+		case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
+		case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
+		case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
 
-			}
+	}
 
-		},
+}
 
-		// Array of scalars
+// Array of scalars
 
-		setValue1fv = function( gl, v ) { gl.uniform1fv( this.addr, v ); },
-		setValue1iv = function( gl, v ) { gl.uniform1iv( this.addr, v ); },
+function setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }
+function setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }
 
-		// Array of vectors (flat or from THREE classes)
+// Array of vectors (flat or from THREE classes)
 
-		setValueV2a = function( gl, v ) {
+function setValueV2a( gl, v ) {
 
-			gl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );
+	gl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );
 
-		},
+}
 
-		setValueV3a = function( gl, v ) {
+function setValueV3a( gl, v ) {
 
-			gl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );
+	gl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );
 
-		},
+}
 
-		setValueV4a = function( gl, v ) {
+function setValueV4a( gl, v ) {
 
-			gl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );
+	gl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );
 
-		},
+}
 
-		// Array of matrices (flat or from THREE clases)
+// Array of matrices (flat or from THREE clases)
 
-		setValueM2a = function( gl, v ) {
+function setValueM2a( gl, v ) {
 
-			gl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );
+	gl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );
 
-		},
+}
 
-		setValueM3a = function( gl, v ) {
+function setValueM3a( gl, v ) {
 
-			gl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );
+	gl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );
 
-		},
+}
 
-		setValueM4a = function( gl, v ) {
+function setValueM4a( gl, v ) {
 
-			gl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );
+	gl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );
 
-		},
+}
 
-		// Array of textures (2D / Cube)
+// Array of textures (2D / Cube)
 
-		setValueT1a = function( gl, v, renderer ) {
+function setValueT1a( gl, v, renderer ) {
 
-			var n = v.length,
-				units = allocTexUnits( renderer, n );
+	var n = v.length,
+		units = allocTexUnits( renderer, n );
 
-			gl.uniform1iv( this.addr, units );
+	gl.uniform1iv( this.addr, units );
 
-			for ( var i = 0; i !== n; ++ i ) {
+	for ( var i = 0; i !== n; ++ i ) {
 
-				renderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );
+		renderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );
 
-			}
+	}
 
-		},
+}
 
-		setValueT6a = function( gl, v, renderer ) {
+function setValueT6a( gl, v, renderer ) {
 
-			var n = v.length,
-				units = allocTexUnits( renderer, n );
+	var n = v.length,
+		units = allocTexUnits( renderer, n );
 
-			gl.uniform1iv( this.addr, units );
+	gl.uniform1iv( this.addr, units );
 
-			for ( var i = 0; i !== n; ++ i ) {
+	for ( var i = 0; i !== n; ++ i ) {
 
-				renderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );
+		renderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );
 
-			}
-
-		},
-
-
-		// Helper to pick the right setter for a pure (bottom-level) array
+	}
 
-		getPureArraySetter = function( type ) {
+}
 
-			switch ( type ) {
+// Helper to pick the right setter for a pure (bottom-level) array
 
-				case 0x1406: return setValue1fv; // FLOAT
-				case 0x8b50: return setValueV2a; // _VEC2
-				case 0x8b51: return setValueV3a; // _VEC3
-				case 0x8b52: return setValueV4a; // _VEC4
+function getPureArraySetter( type ) {
 
-				case 0x8b5a: return setValueM2a; // _MAT2
-				case 0x8b5b: return setValueM3a; // _MAT3
-				case 0x8b5c: return setValueM4a; // _MAT4
+	switch ( type ) {
 
-				case 0x8b5e: return setValueT1a; // SAMPLER_2D
-				case 0x8b60: return setValueT6a; // SAMPLER_CUBE
+		case 0x1406: return setValue1fv; // FLOAT
+		case 0x8b50: return setValueV2a; // _VEC2
+		case 0x8b51: return setValueV3a; // _VEC3
+		case 0x8b52: return setValueV4a; // _VEC4
 
-				case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL
-				case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
-				case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
-				case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
+		case 0x8b5a: return setValueM2a; // _MAT2
+		case 0x8b5b: return setValueM3a; // _MAT3
+		case 0x8b5c: return setValueM4a; // _MAT4
 
-			}
+		case 0x8b5e: return setValueT1a; // SAMPLER_2D
+		case 0x8b60: return setValueT6a; // SAMPLER_CUBE
 
-		},
+		case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL
+		case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
+		case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
+		case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
 
-	// --- Uniform Classes ---
+	}
 
-		SingleUniform = function SingleUniform( id, activeInfo, addr ) {
+}
 
-			this.id = id;
-			this.addr = addr;
-			this.setValue = getSingularSetter( activeInfo.type );
+// --- Uniform Classes ---
 
-			// this.path = activeInfo.name; // DEBUG
+function SingleUniform( id, activeInfo, addr ) {
 
-		},
+	this.id = id;
+	this.addr = addr;
+	this.setValue = getSingularSetter( activeInfo.type );
 
-		PureArrayUniform = function( id, activeInfo, addr ) {
+	// this.path = activeInfo.name; // DEBUG
 
-			this.id = id;
-			this.addr = addr;
-			this.size = activeInfo.size;
-			this.setValue = getPureArraySetter( activeInfo.type );
+}
 
-			// this.path = activeInfo.name; // DEBUG
+function PureArrayUniform( id, activeInfo, addr ) {
 
-		},
+	this.id = id;
+	this.addr = addr;
+	this.size = activeInfo.size;
+	this.setValue = getPureArraySetter( activeInfo.type );
 
-		StructuredUniform = function( id ) {
+	// this.path = activeInfo.name; // DEBUG
 
-			this.id = id;
+}
 
-			UniformContainer.call( this ); // mix-in
+function StructuredUniform( id ) {
 
-		};
+	this.id = id;
 
-	StructuredUniform.prototype.setValue = function( gl, value ) {
+	UniformContainer.call( this ); // mix-in
 
-		// Note: Don't need an extra 'renderer' parameter, since samplers
-		// are not allowed in structured uniforms.
+}
 
-		var seq = this.seq;
+StructuredUniform.prototype.setValue = function( gl, value ) {
 
-		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
+	// Note: Don't need an extra 'renderer' parameter, since samplers
+	// are not allowed in structured uniforms.
 
-			var u = seq[ i ];
-			u.setValue( gl, value[ u.id ] );
+	var seq = this.seq;
 
-		}
+	for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 
-	};
+		var u = seq[ i ];
+		u.setValue( gl, value[ u.id ] );
 
-	// --- Top-level ---
+	}
 
-	// Parser - builds up the property tree from the path strings
+};
 
-	var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g,
-		// extracts
-		// 	- the identifier (member name or array index)
-		//  - followed by an optional right bracket (found when array index)
-		//  - followed by an optional left bracket or dot (type of subscript)
-		//
-		// Note: These portions can be read in a non-overlapping fashion and
-		// allow straightforward parsing of the hierarchy that WebGL encodes
-		// in the uniform names.
+// --- Top-level ---
 
-		addUniform = function( container, uniformObject ) {
+// Parser - builds up the property tree from the path strings
 
-			container.seq.push( uniformObject );
-			container.map[ uniformObject.id ] = uniformObject;
+var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g;
 
-		},
+// extracts
+// 	- the identifier (member name or array index)
+//  - followed by an optional right bracket (found when array index)
+//  - followed by an optional left bracket or dot (type of subscript)
+//
+// Note: These portions can be read in a non-overlapping fashion and
+// allow straightforward parsing of the hierarchy that WebGL encodes
+// in the uniform names.
 
-		parseUniform = function( activeInfo, addr, container ) {
+function addUniform( container, uniformObject ) {
 
-			var path = activeInfo.name,
-				pathLength = path.length;
+	container.seq.push( uniformObject );
+	container.map[ uniformObject.id ] = uniformObject;
 
-			// reset RegExp object, because of the early exit of a previous run
-			RePathPart.lastIndex = 0;
+}
 
-			for (; ;) {
+function parseUniform( activeInfo, addr, container ) {
 
-				var match = RePathPart.exec( path ),
-					matchEnd = RePathPart.lastIndex,
+	var path = activeInfo.name,
+		pathLength = path.length;
 
-					id = match[ 1 ],
-					idIsIndex = match[ 2 ] === ']',
-					subscript = match[ 3 ];
+	// reset RegExp object, because of the early exit of a previous run
+	RePathPart.lastIndex = 0;
 
-				if ( idIsIndex ) id = id | 0; // convert to integer
+	for (; ;) {
 
-				if ( subscript === undefined ||
-						subscript === '[' && matchEnd + 2 === pathLength ) {
-					// bare name or "pure" bottom-level array "[0]" suffix
+		var match = RePathPart.exec( path ),
+			matchEnd = RePathPart.lastIndex,
 
-					addUniform( container, subscript === undefined ?
-							new SingleUniform( id, activeInfo, addr ) :
-							new PureArrayUniform( id, activeInfo, addr ) );
+			id = match[ 1 ],
+			idIsIndex = match[ 2 ] === ']',
+			subscript = match[ 3 ];
 
-					break;
+		if ( idIsIndex ) id = id | 0; // convert to integer
 
-				} else {
-					// step into inner node / create it in case it doesn't exist
+		if ( subscript === undefined ||
+				subscript === '[' && matchEnd + 2 === pathLength ) {
+			// bare name or "pure" bottom-level array "[0]" suffix
 
-					var map = container.map,
-						next = map[ id ];
+			addUniform( container, subscript === undefined ?
+					new SingleUniform( id, activeInfo, addr ) :
+					new PureArrayUniform( id, activeInfo, addr ) );
 
-					if ( next === undefined ) {
+			break;
 
-						next = new StructuredUniform( id );
-						addUniform( container, next );
+		} else {
+			// step into inner node / create it in case it doesn't exist
 
-					}
+			var map = container.map,
+				next = map[ id ];
 
-					container = next;
+			if ( next === undefined ) {
 
-				}
+				next = new StructuredUniform( id );
+				addUniform( container, next );
 
 			}
 
-		},
+			container = next;
 
-	// Root Container
+		}
 
-		WebGLUniforms = function WebGLUniforms( gl, program, renderer ) {
+	}
 
-			UniformContainer.call( this );
+}
 
-			this.renderer = renderer;
+// Root Container
 
-			var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
+function WebGLUniforms( gl, program, renderer ) {
 
-			for ( var i = 0; i !== n; ++ i ) {
+	UniformContainer.call( this );
 
-				var info = gl.getActiveUniform( program, i ),
-					path = info.name,
-					addr = gl.getUniformLocation( program, path );
+	this.renderer = renderer;
 
-				parseUniform( info, addr, this );
+	var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
 
-			}
+	for ( var i = 0; i !== n; ++ i ) {
 
-		};
+		var info = gl.getActiveUniform( program, i ),
+			path = info.name,
+			addr = gl.getUniformLocation( program, path );
 
+		parseUniform( info, addr, this );
 
-	WebGLUniforms.prototype.setValue = function( gl, name, value ) {
+	}
 
-		var u = this.map[ name ];
+}
 
-		if ( u !== undefined ) u.setValue( gl, value, this.renderer );
+WebGLUniforms.prototype.setValue = function( gl, name, value ) {
 
-	};
+	var u = this.map[ name ];
 
-	WebGLUniforms.prototype.set = function( gl, object, name ) {
+	if ( u !== undefined ) u.setValue( gl, value, this.renderer );
 
-		var u = this.map[ name ];
+};
 
-		if ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );
+WebGLUniforms.prototype.set = function( gl, object, name ) {
 
-	};
+	var u = this.map[ name ];
 
-	WebGLUniforms.prototype.setOptional = function( gl, object, name ) {
+	if ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );
 
-		var v = object[ name ];
+};
 
-		if ( v !== undefined ) this.setValue( gl, name, v );
+WebGLUniforms.prototype.setOptional = function( gl, object, name ) {
 
-	};
+	var v = object[ name ];
 
+	if ( v !== undefined ) this.setValue( gl, name, v );
 
-	// Static interface
+};
 
-	WebGLUniforms.upload = function( gl, seq, values, renderer ) {
 
-		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
+// Static interface
 
-			var u = seq[ i ],
-				v = values[ u.id ];
+WebGLUniforms.upload = function( gl, seq, values, renderer ) {
 
-			if ( v.needsUpdate !== false ) {
-				// note: always updating when .needsUpdate is undefined
+	for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 
-				u.setValue( gl, v.value, renderer );
+		var u = seq[ i ],
+			v = values[ u.id ];
 
-			}
+		if ( v.needsUpdate !== false ) {
+			// note: always updating when .needsUpdate is undefined
+
+			u.setValue( gl, v.value, renderer );
 
 		}
 
-	};
+	}
 
-	WebGLUniforms.seqWithValue = function( seq, values ) {
+};
 
-		var r = [];
+WebGLUniforms.seqWithValue = function( seq, values ) {
 
-		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
+	var r = [];
 
-			var u = seq[ i ];
-			if ( u.id in values ) r.push( u );
+	for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 
-		}
+		var u = seq[ i ];
+		if ( u.id in values ) r.push( u );
 
-		return r;
+	}
 
-	};
+	return r;
 
-	WebGLUniforms.splitDynamic = function( seq, values ) {
+};
 
-		var r = null,
-			n = seq.length,
-			w = 0;
+WebGLUniforms.splitDynamic = function( seq, values ) {
 
-		for ( var i = 0; i !== n; ++ i ) {
+	var r = null,
+		n = seq.length,
+		w = 0;
 
-			var u = seq[ i ],
-				v = values[ u.id ];
+	for ( var i = 0; i !== n; ++ i ) {
 
-			if ( v && v.dynamic === true ) {
+		var u = seq[ i ],
+			v = values[ u.id ];
 
-				if ( r === null ) r = [];
-				r.push( u );
+		if ( v && v.dynamic === true ) {
 
-			} else {
+			if ( r === null ) r = [];
+			r.push( u );
 
-				// in-place compact 'seq', removing the matches
-				if ( w < i ) seq[ w ] = u;
-				++ w;
+		} else {
 
-			}
+			// in-place compact 'seq', removing the matches
+			if ( w < i ) seq[ w ] = u;
+			++ w;
 
 		}
 
-		if ( w < n ) seq.length = w;
+	}
 
-		return r;
+	if ( w < n ) seq.length = w;
 
-	};
+	return r;
 
-	WebGLUniforms.evalDynamic = function( seq, values, object, camera ) {
+};
 
-		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
+WebGLUniforms.evalDynamic = function( seq, values, object, camera ) {
 
-			var v = values[ seq[ i ].id ],
-				f = v.onUpdateCallback;
-
-			if ( f !== undefined ) f.call( v, object, camera );
-
-		}
+	for ( var i = 0, n = seq.length; i !== n; ++ i ) {
 
-	};
+		var v = values[ seq[ i ].id ],
+			f = v.onUpdateCallback;
 
-	return WebGLUniforms;
+		if ( f !== undefined ) f.call( v, object, camera );
 
-} )();
+	}
 
+};
 
-export { WebGLUniforms };
+export { WebGLUniforms };