ソースを参照

Merge branch 'dev' into dev11

Michael Herzog 5 年 前
コミット
0a6a1dc6d6

+ 11 - 2
docs/api/en/materials/MeshPhysicalMaterial.html

@@ -39,6 +39,7 @@
 		<h2>Examples</h2>
 		<p>
 			[example:webgl_materials_variations_physical materials / variations / physical]<br />
+			[example:webgl_materials_physical_clearcoat materials / physical / clearcoat]<br />
 			[example:webgl_materials_physical_reflectivity materials / physical / reflectivity]
 		</p>
 
@@ -59,11 +60,19 @@
 
 		<h3>[property:Float clearcoat]</h3>
 		<p>
-		Clearcoat level, from *0.0* to *1.0*. Default is *0.0*.
+		Represents the thickness of the clear coat layer, from *0.0* to *1.0*. You can use clear coat related properties to enable multilayer
+		materials that have a thin translucent layer over the base layer. Typical examples for this model are car paints or acrylic.
+		Default is *0.0*.
 		</p>
 
+		<h3>[property:Float clearcoatNormalMap]</h3>
+		<p>Can be used to enable independent normals for the clear coat layer. Default is *null*.</p>
+
+		<h3>[property:Vector2 clearcoatNormalScale]</h3>
+		<p>How much [page:.clearcoatNormalMap] affects the clear coat layer, from *(0,0)* to *(1,1)*. Default is *(1,1)*.</p>
+
 		<h3>[property:Float clearcoatRoughness]</h3>
-		<p>How rough the clearcoat appears, from *0.0* to *1.0*. Default is *0.0*.</p>
+		<p>Roughness of the clear coat layer, from *0.0* to *1.0*. Default is *0.0*.</p>
 
 		<h3>[property:Object defines]</h3>
 		<p>An object of the form:

+ 0 - 1
docs/api/zh/cameras/OrthographicCamera.html

@@ -34,7 +34,6 @@
 		<p>[example:webgl_rtt rtt ]</p>
 		<p>[example:webgl_shaders_tonemapping shaders / tonemapping ]</p>
 		<p>[example:webgl_shadowmap shadowmap ]</p>
-		<p>[example:webgl_terrain_dynamic terrain / dynamic ]</p>
 
 		<code>var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
 scene.add( camera );</code>

+ 1 - 2
docs/api/zh/loaders/managers/LoadingManager.html

@@ -26,8 +26,7 @@
 			[example:webgl_loader_fbx WebGL / loader / fbx]<br />
 			[example:webgl_loader_obj WebGL / loader / obj]<br />
 			[example:webgl_materials_physical_reflectivity WebGL / materials / physical / reflectivity]<br />
-			[example:webgl_postprocessing_outline WebGL / postprocesing / outline]<br />
-			[example:webgl_terrain_dynamic WebGL / terrain / dynamic]
+			[example:webgl_postprocessing_outline WebGL / postprocesing / outline]
 		</p>
 
 		<p>

+ 11 - 2
docs/api/zh/materials/MeshPhysicalMaterial.html

@@ -38,6 +38,7 @@
 
 		<p>
 			[example:webgl_materials_variations_physical materials / variations / physical]<br />
+			[example:webgl_materials_physical_clearcoat materials / physical / clearcoat]<br />
 			[example:webgl_materials_physical_reflectivity materials / physical / reflectivity]
 		</p>
 
@@ -55,11 +56,19 @@
 
 		<h3>[property:Float clearcoat]</h3>
 		<p>
-			Clearcoat级别,从*0.0*到*1.0*。默认值为*0.0*。
+		Represents the thickness of the clear coat layer, from *0.0* to *1.0*. You can use clear coat related properties to enable multilayer
+		materials that have a thin translucent layer over the base layer. Typical examples for this model are car paints or acrylic.
+		Default is *0.0*.
 		</p>
 
+		<h3>[property:Float clearcoatNormalMap]</h3>
+		<p>Can be used to enable independent normals for the clear coat layer. Default is *null*.</p>
+
+		<h3>[property:Vector2 clearcoatNormalScale]</h3>
+		<p>How much [page:.clearcoatNormalMap] affects the clear coat layer, from *(0,0)* to *(1,1)*. Default is *(1,1)*.</p>
+
 		<h3>[property:Float clearcoatRoughness]</h3>
-		<p> clearcoat看起来的粗糙程度,从*0.0*到*1.0*。默认值为*0.0*。</p>
+		<p>Roughness of the clear coat layer, from *0.0* to *1.0*. Default is *0.0*.</p>
 
 		<h3>[property:Object defines]</h3>
 		<p> 如下形式的对象:

+ 1 - 1
docs/manual/en/introduction/FAQ.html

@@ -22,7 +22,7 @@
 
 		<h2>Why are there meta viewport tags in examples?</h2>
 		<div>
-			<div class="highlight highlight-text-html-basic"><pre>&lt;<span class="pl-ent">meta</span> <span class="pl-e">name</span>=<span class="pl-s"><span class="pl-pds">"</span>viewport<span class="pl-pds">"</span></span> <span class="pl-e">content</span>=<span class="pl-s"><span class="pl-pds">"</span>width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0<span class="pl-pds">"</span></span>&gt;</pre></div>
+				<code>&lt;meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"&gt;</code>
 
 				<p>These tags control viewport size and scale for mobile browsers (where page content may be rendered at different size than visible viewport).</p>
 

+ 3 - 3
docs/manual/zh/introduction/FAQ.html

@@ -15,8 +15,8 @@
 			<p>
 			推荐使用glTF(gl传输格式)来对三维物体进行导入和导出,由于glTF这种格式专注于在程序运行时呈现三维物体,因此它的传输效率非常高,且加载速度非常快。
 			</p>
-			
-			
+
+
 			<p>three.js同样也为其它广受欢迎的格式(例如FBX、Collada以及OBJ等)提供了载入工具。即便如此,你应当还是首先尝试着在你的项目中建立一个基于glTF的工作流程。
 				了解更多详细信息,请查看[link:#manual/introduction/Loading-3D-models loading 3D models]。
 			</p>
@@ -24,7 +24,7 @@
 
 		<h2>为什么在示例中会有一些和viewport相关的meta标签?</h2>
 		<div>
-			<div class="highlight highlight-text-html-basic"><pre>&lt;<span class="pl-ent">meta</span> <span class="pl-e">name</span>=<span class="pl-s"><span class="pl-pds">"</span>viewport<span class="pl-pds">"</span></span> <span class="pl-e">content</span>=<span class="pl-s"><span class="pl-pds">"</span>width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0<span class="pl-pds">"</span></span>&gt;</pre></div>
+				<code>&lt;meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"&gt;</code>
 
 				<p>这些标签用于在移动端浏览器上控制视口的大小和缩放(页面内容可能会以与可视区域不同的大小来呈现)。</p>
 

+ 1 - 0
docs/page.css

@@ -61,6 +61,7 @@ body {
 	padding-bottom: var(--page-padding);
 	padding-right: var(--page-padding);
 	padding-left: calc(var(--page-padding) + var(--panel-width));
+	word-break: break-word;
 }
 
 a {

+ 1 - 0
examples/jsm/postprocessing/EffectComposer.d.ts

@@ -18,6 +18,7 @@ export class EffectComposer {
 	passes: Pass[];
 	copyPass: ShaderPass;
 	clock: Clock;
+	renderToScreen: boolean;
 
 	swapBuffers(): void;
 	addPass( pass: Pass ): void;

+ 5 - 5
examples/webgl_materials_video_webcam.html

@@ -95,17 +95,17 @@
 
 			function onWindowResize() {
 
-				 camera.aspect = window.innerWidth / window.innerHeight;
-				 camera.updateProjectionMatrix();
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
 
-				 renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 			}
 
 			function animate() {
 
-				 requestAnimationFrame( animate );
-				 renderer.render( scene, camera );
+				requestAnimationFrame( animate );
+				renderer.render( scene, camera );
 
 			}
 

+ 6 - 0
src/renderers/WebGLRenderer.js

@@ -1612,9 +1612,12 @@ function WebGLRenderer( parameters ) {
 			uniforms.ambientLightColor.value = lights.state.ambient;
 			uniforms.lightProbe.value = lights.state.probe;
 			uniforms.directionalLights.value = lights.state.directional;
+			uniforms.directionalLightShadows.value = lights.state.directionalShadow;
 			uniforms.spotLights.value = lights.state.spot;
+			uniforms.spotLightShadows.value = lights.state.spotShadow;
 			uniforms.rectAreaLights.value = lights.state.rectArea;
 			uniforms.pointLights.value = lights.state.point;
+			uniforms.pointLightShadows.value = lights.state.pointShadow;
 			uniforms.hemisphereLights.value = lights.state.hemi;
 
 			uniforms.directionalShadowMap.value = lights.state.directionalShadowMap;
@@ -2595,8 +2598,11 @@ function WebGLRenderer( parameters ) {
 		uniforms.lightProbe.needsUpdate = value;
 
 		uniforms.directionalLights.needsUpdate = value;
+		uniforms.directionalLightShadows.needsUpdate = value;
 		uniforms.pointLights.needsUpdate = value;
+		uniforms.pointLightShadows.needsUpdate = value;
 		uniforms.spotLights.needsUpdate = value;
+		uniforms.spotLightShadows.needsUpdate = value;
 		uniforms.rectAreaLights.needsUpdate = value;
 		uniforms.hemisphereLights.needsUpdate = value;
 

+ 15 - 3
src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js

@@ -31,6 +31,9 @@ IncidentLight directLight;
 #if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )
 
 	PointLight pointLight;
+	#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0
+	PointLightShadow pointLightShadow;
+	#endif
 
 	#pragma unroll_loop
 	for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
@@ -40,7 +43,8 @@ IncidentLight directLight;
 		getPointDirectLightIrradiance( pointLight, geometry, directLight );
 
 		#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )
-		directLight.color *= all( bvec3( pointLight.shadow, directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
+		pointLightShadow = pointLightShadows[ i ];
+		directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;
 		#endif
 
 		RE_Direct( directLight, geometry, material, reflectedLight );
@@ -52,6 +56,9 @@ IncidentLight directLight;
 #if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )
 
 	SpotLight spotLight;
+	#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0
+	SpotLightShadow spotLightShadow;
+	#endif
 
 	#pragma unroll_loop
 	for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
@@ -61,7 +68,8 @@ IncidentLight directLight;
 		getSpotDirectLightIrradiance( spotLight, geometry, directLight );
 
 		#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )
-		directLight.color *= all( bvec3( spotLight.shadow, directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
+		spotLightShadow = spotLightShadows[ i ];
+		directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
 		#endif
 
 		RE_Direct( directLight, geometry, material, reflectedLight );
@@ -73,6 +81,9 @@ IncidentLight directLight;
 #if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )
 
 	DirectionalLight directionalLight;
+	#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0
+	DirectionalLightShadow directionalLightShadow;
+	#endif
 
 	#pragma unroll_loop
 	for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
@@ -82,7 +93,8 @@ IncidentLight directLight;
 		getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );
 
 		#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
-		directLight.color *= all( bvec3( directionalLight.shadow, directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
+		directionalLightShadow = directionalLightShadows[ i ];
+		directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
 		#endif
 
 		RE_Direct( directLight, geometry, material, reflectedLight );

+ 39 - 17
src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js

@@ -59,15 +59,23 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
 	struct DirectionalLight {
 		vec3 direction;
 		vec3 color;
-
-		int shadow;
-		float shadowBias;
-		float shadowRadius;
-		vec2 shadowMapSize;
 	};
 
 	uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
 
+	#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0
+
+		struct DirectionalLightShadow {
+			float shadowBias;
+			float shadowRadius;
+			vec2 shadowMapSize;
+		};
+
+		uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];
+
+	#endif
+
+
 	void getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {
 
 		directLight.color = directionalLight.color;
@@ -86,17 +94,24 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
 		vec3 color;
 		float distance;
 		float decay;
-
-		int shadow;
-		float shadowBias;
-		float shadowRadius;
-		vec2 shadowMapSize;
-		float shadowCameraNear;
-		float shadowCameraFar;
 	};
 
 	uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
 
+	#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0
+
+		struct PointLightShadow {
+			float shadowBias;
+			float shadowRadius;
+			vec2 shadowMapSize;
+			float shadowCameraNear;
+			float shadowCameraFar;
+		};
+
+		uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];
+
+	#endif
+
 	// directLight is an out parameter as having it as a return value caused compiler errors on some devices
 	void getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {
 
@@ -124,15 +139,22 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
 		float decay;
 		float coneCos;
 		float penumbraCos;
-
-		int shadow;
-		float shadowBias;
-		float shadowRadius;
-		vec2 shadowMapSize;
 	};
 
 	uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];
 
+	#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0
+
+		struct SpotLightShadow {
+			float shadowBias;
+			float shadowRadius;
+			vec2 shadowMapSize;
+		};
+
+		uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];
+
+	#endif
+
 	// directLight is an out parameter as having it as a return value caused compiler errors on some devices
 	void getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight  ) {
 

+ 9 - 9
src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js

@@ -7,13 +7,13 @@ float getShadowMask() {
 
 	#if NUM_DIR_LIGHT_SHADOWS > 0
 
-	DirectionalLight directionalLight;
+	DirectionalLightShadow directionalLight;
 
 	#pragma unroll_loop
 	for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {
 
-		directionalLight = directionalLights[ i ];
-		shadow *= all( bvec2( directionalLight.shadow, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
+		directionalLight = directionalLightShadows[ i ];
+		shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
 
 	}
 
@@ -21,13 +21,13 @@ float getShadowMask() {
 
 	#if NUM_SPOT_LIGHT_SHADOWS > 0
 
-	SpotLight spotLight;
+	SpotLightShadow spotLight;
 
 	#pragma unroll_loop
 	for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {
 
-		spotLight = spotLights[ i ];
-		shadow *= all( bvec2( spotLight.shadow, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
+		spotLight = spotLightShadows[ i ];
+		shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
 
 	}
 
@@ -35,13 +35,13 @@ float getShadowMask() {
 
 	#if NUM_POINT_LIGHT_SHADOWS > 0
 
-	PointLight pointLight;
+	PointLightShadow pointLight;
 
 	#pragma unroll_loop
 	for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {
 
-		pointLight = pointLights[ i ];
-		shadow *= all( bvec2( pointLight.shadow, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
+		pointLight = pointLightShadows[ i ];
+		shadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
 
 	}
 

+ 15 - 3
src/renderers/shaders/UniformsLib.d.ts

@@ -67,7 +67,11 @@ export let UniformsLib: {
 			properties: {
 				direction: {};
 				color: {};
-				shadow: {};
+			};
+		};
+		directionalLightShadows: {
+			value: any[];
+			properties: {
 				shadowBias: {};
 				shadowRadius: {};
 				shadowMapSize: {};
@@ -85,7 +89,11 @@ export let UniformsLib: {
 				coneCos: {};
 				penumbraCos: {};
 				decay: {};
-				shadow: {};
+			};
+		};
+		spotLightShadows: {
+			value: any[];
+			properties: {
 				shadowBias: {};
 				shadowRadius: {};
 				shadowMapSize: {};
@@ -100,7 +108,11 @@ export let UniformsLib: {
 				position: {};
 				decay: {};
 				distance: {};
-				shadow: {};
+			};
+		};
+		pointLightShadows: {
+			value: any[];
+			properties: {
 				shadowBias: {};
 				shadowRadius: {};
 				shadowMapSize: {};

+ 9 - 6
src/renderers/shaders/UniformsLib.js

@@ -114,9 +114,10 @@ var UniformsLib = {
 
 		directionalLights: { value: [], properties: {
 			direction: {},
-			color: {},
+			color: {}
+		} },
 
-			shadow: {},
+		directionalLightShadows: { value: [], properties: {
 			shadowBias: {},
 			shadowRadius: {},
 			shadowMapSize: {}
@@ -132,9 +133,10 @@ var UniformsLib = {
 			distance: {},
 			coneCos: {},
 			penumbraCos: {},
-			decay: {},
+			decay: {}
+		} },
 
-			shadow: {},
+		spotLightShadows: { value: [], properties: {
 			shadowBias: {},
 			shadowRadius: {},
 			shadowMapSize: {}
@@ -147,9 +149,10 @@ var UniformsLib = {
 			color: {},
 			position: {},
 			decay: {},
-			distance: {},
+			distance: {}
+		} },
 
-			shadow: {},
+		pointLightShadows: { value: [], properties: {
 			shadowBias: {},
 			shadowRadius: {},
 			shadowMapSize: {},

+ 1 - 0
src/renderers/webgl/WebGLClipping.js

@@ -153,6 +153,7 @@ function WebGLClipping() {
 		}
 
 		scope.numPlanes = nPlanes;
+		scope.numIntersection = 0;
 
 		return dstArray;
 

+ 3 - 0
src/renderers/webgl/WebGLLights.d.ts

@@ -20,13 +20,16 @@ export class WebGLLights {
 		ambient: Array<number>;
 		probe: Array<any>;
 		directional: Array<any>;
+		directionalShadow: Array<any>;
 		directionalShadowMap: Array<any>;
 		directionalShadowMatrix: Array<any>;
 		spot: Array<any>;
+		spotShadow: Array<any>;
 		spotShadowMap: Array<any>;
 		spotShadowMatrix: Array<any>;
 		rectArea: Array<any>;
 		point: Array<any>;
+		pointShadow: Array<any>;
 		pointShadowMap: Array<any>;
 		pointShadowMatrix: Array<any>;
 		hemi: Array<any>;

+ 88 - 35
src/renderers/webgl/WebGLLights.js

@@ -29,11 +29,6 @@ function UniformsCache() {
 					uniforms = {
 						direction: new Vector3(),
 						color: new Color(),
-
-						shadow: false,
-						shadowBias: 0,
-						shadowRadius: 1,
-						shadowMapSize: new Vector2()
 					};
 					break;
 
@@ -46,11 +41,6 @@ function UniformsCache() {
 						coneCos: 0,
 						penumbraCos: 0,
 						decay: 0,
-
-						shadow: false,
-						shadowBias: 0,
-						shadowRadius: 1,
-						shadowMapSize: new Vector2()
 					};
 					break;
 
@@ -60,13 +50,6 @@ function UniformsCache() {
 						color: new Color(),
 						distance: 0,
 						decay: 0,
-
-						shadow: false,
-						shadowBias: 0,
-						shadowRadius: 1,
-						shadowMapSize: new Vector2(),
-						shadowCameraNear: 1,
-						shadowCameraFar: 1000
 					};
 					break;
 
@@ -84,7 +67,6 @@ function UniformsCache() {
 						position: new Vector3(),
 						halfWidth: new Vector3(),
 						halfHeight: new Vector3()
-						// TODO (abelnation): set RectAreaLight shadow uniforms
 					};
 					break;
 
@@ -100,6 +82,66 @@ function UniformsCache() {
 
 }
 
+function ShadowUniformsCache() {
+
+	var lights = {};
+
+	return {
+
+		get: function ( light ) {
+
+			if ( lights[ light.id ] !== undefined ) {
+
+				return lights[ light.id ];
+
+			}
+
+			var uniforms;
+
+			switch ( light.type ) {
+
+				case 'DirectionalLight':
+					uniforms = {
+						shadowBias: 0,
+						shadowRadius: 1,
+						shadowMapSize: new Vector2()
+					};
+					break;
+
+				case 'SpotLight':
+					uniforms = {
+						shadowBias: 0,
+						shadowRadius: 1,
+						shadowMapSize: new Vector2()
+					};
+					break;
+
+				case 'PointLight':
+					uniforms = {
+						shadowBias: 0,
+						shadowRadius: 1,
+						shadowMapSize: new Vector2(),
+						shadowCameraNear: 1,
+						shadowCameraFar: 1000
+					};
+					break;
+
+				// TODO (abelnation): set RectAreaLight shadow uniforms
+
+			}
+
+			lights[ light.id ] = uniforms;
+
+			return uniforms;
+
+		}
+
+	};
+
+}
+
+
+
 var nextVersion = 0;
 
 function shadowCastingLightsFirst( lightA, lightB ) {
@@ -112,6 +154,8 @@ function WebGLLights() {
 
 	var cache = new UniformsCache();
 
+	var shadowCache = ShadowUniformsCache();
+
 	var state = {
 
 		version: 0,
@@ -131,13 +175,16 @@ function WebGLLights() {
 		ambient: [ 0, 0, 0 ],
 		probe: [],
 		directional: [],
+		directionalShadow: [],
 		directionalShadowMap: [],
 		directionalShadowMatrix: [],
 		spot: [],
+		spotShadow: [],
 		spotShadowMap: [],
 		spotShadowMatrix: [],
 		rectArea: [],
 		point: [],
+		pointShadow: [],
 		pointShadowMap: [],
 		pointShadowMatrix: [],
 		hemi: []
@@ -204,16 +251,17 @@ function WebGLLights() {
 				uniforms.direction.sub( vector3 );
 				uniforms.direction.transformDirection( viewMatrix );
 
-				uniforms.shadow = light.castShadow;
-
 				if ( light.castShadow ) {
 
 					var shadow = light.shadow;
 
-					uniforms.shadowBias = shadow.bias;
-					uniforms.shadowRadius = shadow.radius;
-					uniforms.shadowMapSize = shadow.mapSize;
+					var shadowUniforms = shadowCache.get( light );
+
+					shadowUniforms.shadowBias = shadow.bias;
+					shadowUniforms.shadowRadius = shadow.radius;
+					shadowUniforms.shadowMapSize = shadow.mapSize;
 
+					state.directionalShadow[ directionalLength ] = shadowUniforms;
 					state.directionalShadowMap[ directionalLength ] = shadowMap;
 					state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
 
@@ -244,16 +292,17 @@ function WebGLLights() {
 				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
 				uniforms.decay = light.decay;
 
-				uniforms.shadow = light.castShadow;
-
 				if ( light.castShadow ) {
 
 					var shadow = light.shadow;
 
-					uniforms.shadowBias = shadow.bias;
-					uniforms.shadowRadius = shadow.radius;
-					uniforms.shadowMapSize = shadow.mapSize;
+					var shadowUniforms = shadowCache.get( light );
+
+					shadowUniforms.shadowBias = shadow.bias;
+					shadowUniforms.shadowRadius = shadow.radius;
+					shadowUniforms.shadowMapSize = shadow.mapSize;
 
+					state.spotShadow[ spotLength ] = shadowUniforms;
 					state.spotShadowMap[ spotLength ] = shadowMap;
 					state.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
 
@@ -308,18 +357,19 @@ function WebGLLights() {
 				uniforms.distance = light.distance;
 				uniforms.decay = light.decay;
 
-				uniforms.shadow = light.castShadow;
-
 				if ( light.castShadow ) {
 
 					var shadow = light.shadow;
 
-					uniforms.shadowBias = shadow.bias;
-					uniforms.shadowRadius = shadow.radius;
-					uniforms.shadowMapSize = shadow.mapSize;
-					uniforms.shadowCameraNear = shadow.camera.near;
-					uniforms.shadowCameraFar = shadow.camera.far;
+					var shadowUniforms = shadowCache.get( light );
+
+					shadowUniforms.shadowBias = shadow.bias;
+					shadowUniforms.shadowRadius = shadow.radius;
+					shadowUniforms.shadowMapSize = shadow.mapSize;
+					shadowUniforms.shadowCameraNear = shadow.camera.near;
+					shadowUniforms.shadowCameraFar = shadow.camera.far;
 
+					state.pointShadow[ pointLength ] = shadowUniforms;
 					state.pointShadowMap[ pointLength ] = shadowMap;
 					state.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
 
@@ -371,8 +421,11 @@ function WebGLLights() {
 			state.point.length = pointLength;
 			state.hemi.length = hemiLength;
 
+			state.directionalShadow.length = numDirectionalShadows;
 			state.directionalShadowMap.length = numDirectionalShadows;
+			state.pointShadow.length = numPointShadows;
 			state.pointShadowMap.length = numPointShadows;
+			state.spotShadow.length = numSpotShadows;
 			state.spotShadowMap.length = numSpotShadows;
 			state.directionalShadowMatrix.length = numDirectionalShadows;
 			state.pointShadowMatrix.length = numPointShadows;

+ 4 - 4
src/renderers/webgl/WebGLObjects.js

@@ -4,7 +4,7 @@
 
 function WebGLObjects( gl, geometries, attributes, info ) {
 
-	var updateList = {};
+	var updateMap = new WeakMap();
 
 	function update( object ) {
 
@@ -15,7 +15,7 @@ function WebGLObjects( gl, geometries, attributes, info ) {
 
 		// Update once per frame
 
-		if ( updateList[ buffergeometry.id ] !== frame ) {
+		if ( updateMap.get( buffergeometry ) !== frame ) {
 
 			if ( geometry.isGeometry ) {
 
@@ -25,7 +25,7 @@ function WebGLObjects( gl, geometries, attributes, info ) {
 
 			geometries.update( buffergeometry );
 
-			updateList[ buffergeometry.id ] = frame;
+			updateMap.set( buffergeometry, frame );
 
 		}
 
@@ -41,7 +41,7 @@ function WebGLObjects( gl, geometries, attributes, info ) {
 
 	function dispose() {
 
-		updateList = {};
+		updateMap = new WeakMap();
 
 	}