浏览代码

Merge pull request #7324 from bhouston/simplified_lighting

attempt to simplify the phong shaders and lights.
Mr.doob 9 年之前
父节点
当前提交
d09017fa25

+ 19 - 109
examples/js/ShaderSkin.js

@@ -80,35 +80,11 @@ THREE.ShaderSkin = {
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
-			"uniform vec3 ambientLightColor;",
-
-			"#if MAX_DIR_LIGHTS > 0",
-
-				"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
-				"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
-
-			"#endif",
-
-			"#if MAX_HEMI_LIGHTS > 0",
-
-				"uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
-				"uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
-				"uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];",
-
-			"#endif",
-
-			"#if MAX_POINT_LIGHTS > 0",
-
-				"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
-				"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
-				"uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
-				"uniform float pointLightDecay[ MAX_POINT_LIGHTS ];",
-
-			"#endif",
-
 			"varying vec3 vViewPosition;",
 
 			THREE.ShaderChunk[ "common" ],
+			THREE.ShaderChunk[ "bsdfs" ],
+			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 			THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
@@ -198,9 +174,9 @@ THREE.ShaderSkin = {
 
 					"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
 
-						"vec3 lVector = pointLightPosition[ i ] + vViewPosition.xyz;",
+						"vec3 lVector = pointLights[ i ].position + vViewPosition.xyz;",
 
-						"float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );",
+						"float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );",
 
 						"lVector = normalize( lVector );",
 
@@ -210,8 +186,8 @@ THREE.ShaderSkin = {
 
 						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
-						"totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );",
-						"totalSpecularLight += pointLightColor[ i ] * specular * ( pointSpecularWeight * specularStrength * attenuation );",
+						"totalDiffuseLight += pointLight[ i ].color * ( pointDiffuseWeight * attenuation );",
+						"totalSpecularLight += pointLight[ i ].color * specular * ( pointSpecularWeight * specularStrength * attenuation );",
 
 					"}",
 
@@ -223,7 +199,7 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
-						"vec3 dirVector = directionalLightDirection[ i ];",
+						"vec3 dirVector = directionalLights[ i ].direction;",
 
 						"float dirDiffuseWeightFull = max( dot( normal, dirVector ), 0.0 );",
 						"float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );",
@@ -231,8 +207,8 @@ THREE.ShaderSkin = {
 
 						"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
-						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
-						"totalSpecularLight += directionalLightColor[ i ] * ( dirSpecularWeight * specularStrength );",
+						"totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;",
+						"totalSpecularLight += directionalLights[ i ].color * ( dirSpecularWeight * specularStrength );",
 
 					"}",
 
@@ -394,21 +370,10 @@ THREE.ShaderSkin = {
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
-			"uniform vec3 ambientLightColor;",
-
-			"#if MAX_DIR_LIGHTS > 0",
-				"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
-				"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
-			"#endif",
-
-			"#if MAX_POINT_LIGHTS > 0",
-				"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
-				"varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
-			"#endif",
-
 			"varying vec3 vViewPosition;",
 
 			THREE.ShaderChunk[ "common" ],
+			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 
 			"float fresnelReflectance( vec3 H, vec3 V, float F0 ) {",
@@ -490,12 +455,12 @@ THREE.ShaderSkin = {
 				"#if MAX_POINT_LIGHTS > 0",
 
 					"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
-
-						"vec3 pointVector = normalize( vPointLight[ i ].xyz );",
-						"float attenuation = vPointLight[ i ].w;",
-
+						
+						"vec3 pointVector = normalize( pointLights[ i ].direction );",
+						"float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );",
+				
 						"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
-
+				
 						"totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );",
 
 						"if ( passID == 1 ) {",
@@ -516,17 +481,18 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
-						"vec3 dirVector = directionalLightDirection[ i ];",
+						"vec3 dirVector = directionalLights[ i ].direction;",
 
 						"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
 
-						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
+					
+						"totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;",
 
 						"if ( passID == 1 ) {",
 
 							"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
-							"totalSpecularLight += directionalLightColor[ i ] * mSpecular.xyz * dirSpecularWeight;",
+							"totalSpecularLight += directionalLights[ i ].color * mSpecular.xyz * dirSpecularWeight;",
 
 						"}",
 
@@ -607,16 +573,6 @@ THREE.ShaderSkin = {
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
-			"#if MAX_POINT_LIGHTS > 0",
-
-				"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
-				"uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
-				"uniform float pointLightDecay[ MAX_POINT_LIGHTS ];",
-
-				"varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
-
-			"#endif",
-
 			"varying vec3 vViewPosition;",
 
 			THREE.ShaderChunk[ "common" ],
@@ -633,24 +589,6 @@ THREE.ShaderSkin = {
 
 				"vUv = uv;",
 
-				// point lights
-
-				"#if MAX_POINT_LIGHTS > 0",
-
-					"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
-
-						"vec3 lVector = pointLightPosition[ i ] - vViewPosition;",
-
-						"float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );",
-
-						"lVector = normalize( lVector );",
-
-						"vPointLight[ i ] = vec4( lVector, attenuation );",
-
-					"}",
-
-				"#endif",
-
 				// displacement mapping
 
 				"#ifdef VERTEX_TEXTURES",
@@ -675,16 +613,6 @@ THREE.ShaderSkin = {
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
-			"#if MAX_POINT_LIGHTS > 0",
-
-				"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
-				"uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
-				"uniform float pointLightDecay[ MAX_POINT_LIGHTS ];",
-
-				"varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
-
-			"#endif",
-
 			"varying vec3 vViewPosition;",
 
 			THREE.ShaderChunk[ "common" ],
@@ -701,24 +629,6 @@ THREE.ShaderSkin = {
 
 				"vUv = uv;",
 
-				// point lights
-
-				"#if MAX_POINT_LIGHTS > 0",
-
-					"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
-
-						"vec3 lVector = pointLightPosition[ i ] - vViewPosition;",
-
-						"float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );",
-
-						"lVector = normalize( lVector );",
-
-						"vPointLight[ i ] = vec4( lVector, attenuation );",
-
-					"}",
-
-				"#endif",
-
 				"gl_Position = vec4( uv.x * 2.0 - 1.0, uv.y * 2.0 - 1.0, 0.0, 1.0 );",
 
 			"}"

+ 11 - 33
examples/js/ShaderTerrain.js

@@ -86,33 +86,11 @@ THREE.ShaderTerrain = {
 
 			"uniform vec3 ambientLightColor;",
 
-			"#if MAX_DIR_LIGHTS > 0",
-
-				"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
-				"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
-
-			"#endif",
-
-			"#if MAX_HEMI_LIGHTS > 0",
-
-				"uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
-				"uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
-				"uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];",
-
-			"#endif",
-
-			"#if MAX_POINT_LIGHTS > 0",
-
-				"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
-				"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
-				"uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
-				"uniform float pointLightDecay[ MAX_POINT_LIGHTS ];",
-
-			"#endif",
-
 			"varying vec3 vViewPosition;",
 
 			THREE.ShaderChunk[ "common" ],
+			THREE.ShaderChunk[ "bsdfs" ],
+			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 
@@ -168,9 +146,9 @@ THREE.ShaderTerrain = {
 
 					"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
 
-						"vec3 lVector = pointLightPosition[ i ] + vViewPosition.xyz;",
+						"vec3 lVector = pointLights[ i ].position + vViewPosition.xyz;",
 
-						"float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );",
+						"float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );",
 
 						"lVector = normalize( lVector );",
 
@@ -181,8 +159,8 @@ THREE.ShaderTerrain = {
 
 						"float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
 
-						"totalDiffuseLight += attenuation * pointLightColor[ i ] * pointDiffuseWeight;",
-						"totalSpecularLight += attenuation * pointLightColor[ i ] * specular * pointSpecularWeight * pointDiffuseWeight;",
+						"totalDiffuseLight += attenuation * pointLights[ i ].color * pointDiffuseWeight;",
+						"totalSpecularLight += attenuation * pointLights[ i ].color * specular * pointSpecularWeight * pointDiffuseWeight;",
 
 					"}",
 
@@ -197,7 +175,7 @@ THREE.ShaderTerrain = {
 
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
-						"vec3 dirVector = directionalLightDirection[ i ];",
+						"vec3 dirVector = directionalLights[ i ].direction;",
 						"vec3 dirHalfVector = normalize( dirVector + viewPosition );",
 
 						"float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
@@ -205,8 +183,8 @@ THREE.ShaderTerrain = {
 
 						"float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );",
 
-						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
-						"totalSpecularLight += directionalLightColor[ i ] * specular * dirSpecularWeight * dirDiffuseWeight;",
+						"totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;",
+						"totalSpecularLight += directionalLights[ i ].color * specular * dirSpecularWeight * dirDiffuseWeight;",
 
 					"}",
 
@@ -228,7 +206,7 @@ THREE.ShaderTerrain = {
 						"float dotProduct = dot( normal, lVector );",
 						"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
 
-						"totalDiffuseLight += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+						"totalDiffuseLight += mix( hemisphereLights[ i ].groundColor, hemisphereLights[ i ].skyColor, hemiDiffuseWeight );",
 
 						// specular (sky light)
 
@@ -246,7 +224,7 @@ THREE.ShaderTerrain = {
 						"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
 						"hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",
 
-						"totalSpecularLight += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;",
+						"totalSpecularLight += specular * mix( hemisphereLights[ i ].groundColor, hemisphereLights[ i ].skyColor, hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;",
 
 					"}",
 

+ 2 - 0
examples/webgl_animation_skinning_morph.html

@@ -160,6 +160,8 @@
 				var loader = new THREE.JSONLoader();
 				loader.load( "models/skinned/knight.js", function ( geometry, materials ) {
 
+					console.log( 'materials', materials );
+
 					createScene( geometry, materials, 0, FLOOR, -300, 60 )
 
 					// GUI

+ 1 - 1
examples/webgl_lights_pointlights.html

@@ -72,7 +72,7 @@
 
 				var callback = function( geometry ) {
 
-					object = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: 0x555555, specular: 0xffffff, shininess: 50 }  )  );
+					object = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: 0x555555, specular: 0x111111, shininess: 50 }  )  );
 					object.scale.x = object.scale.y = object.scale.z = 0.80;
 					scene.add( object );
 

+ 9 - 4
examples/webgl_materials_lambert_variations.html

@@ -88,8 +88,7 @@
 
 				var geometry = new THREE.SphereBufferGeometry( sphereRadius, 32, 16 );
 
-	
-				for( var alpha = 0; alpha <= 1.0; alpha += stepSize ) {
+				for( var alpha = 0, alphaIndex = 0; alpha <= 1.0; alpha += stepSize, alphaIndex ++ ) {
 
 					var baseColor = new THREE.Color().setHSL( alpha, 0.5, 0.5 );
 
@@ -97,15 +96,21 @@
 						reflectionCube = null;
 					}
 
-					for( var beta = 0; beta <= 1.0; beta += stepSize ) {
+					for( var beta = 0, betaIndex = 0; beta <= 1.0; beta += stepSize, betaIndex ++ ) {
 
 						var reflectivity = beta;
 
+						var side = THREE.FrontSide; 
+						if( ( betaIndex % 2 ) === 0 ) {
+							side = THREE.DoubleSide;
+						}
+
 						for( var gamma = 0; gamma <= 1.0; gamma += stepSize ) {
 
 							var diffuseColor = baseColor.clone().multiplyScalar( gamma );
 
-							var material = new THREE.MeshLambertMaterial( { map: imgTexture, color: diffuseColor, reflectivity: reflectivity, shading: THREE.SmoothShading, envMap: reflectionCube } )
+							var material = new THREE.MeshLambertMaterial( { map: imgTexture, color: diffuseColor,
+								 reflectivity: reflectivity, envMap: reflectionCube, side: side } )
 
 							var mesh = new THREE.Mesh( geometry, material );
 

+ 6 - 3
examples/webgl_shaders_tonemapping.html

@@ -37,7 +37,7 @@
 			<div class="label" style="position: absolute;left: 80%;bottom: 5%;">Adaptive Tone Mapping</div>
 		</div>
 
-		<script src="../build/three.js"></script>
+		<script src="../build/three.min.js"></script>
 
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/dat.gui.min.js"></script>
@@ -158,6 +158,9 @@
 
 					fragmentShader: [
 
+						THREE.ShaderChunk[ "common" ],
+						THREE.ShaderChunk[ "bsdfs" ],
+						THREE.ShaderChunk[ "lights_pars" ],
 						THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
 
 						"void main() {",
@@ -169,12 +172,12 @@
 
 								"for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
 
-									"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
+									"vec4 lDirection = viewMatrix * vec4( directionalLights[i].direction, 0.0 );",
 									"vec3 dirVector = normalize( lDirection.xyz );",
 									"float dotProduct = dot( viewPosition, dirVector );",
 									"dotProduct = 1.0 * max( dotProduct, 0.0 ) + (1.0 - max( -dot( normal, dirVector ), 0.0 ));",
 									"dotProduct *= dotProduct;",
-									"dirDiffuse += max( 0.5 * dotProduct, 0.0 ) * directionalLightColor[ i ];",
+									"dirDiffuse += max( 0.5 * dotProduct, 0.0 ) * directionalLights[i].color;",
 								"}",
 							"#endif",
 

+ 160 - 167
src/renderers/WebGLRenderer.js

@@ -2015,27 +2015,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 	function refreshUniformsLights ( uniforms, lights ) {
 
 		uniforms.ambientLightColor.value = lights.ambient;
-
-		uniforms.directionalLightColor.value = lights.directional.colors;
-		uniforms.directionalLightDirection.value = lights.directional.positions;
-
-		uniforms.pointLightColor.value = lights.point.colors;
-		uniforms.pointLightPosition.value = lights.point.positions;
-		uniforms.pointLightDistance.value = lights.point.distances;
-		uniforms.pointLightDecay.value = lights.point.decays;
-
-		uniforms.spotLightColor.value = lights.spot.colors;
-		uniforms.spotLightPosition.value = lights.spot.positions;
-		uniforms.spotLightDistance.value = lights.spot.distances;
-		uniforms.spotLightDirection.value = lights.spot.directions;
-		uniforms.spotLightAngleCos.value = lights.spot.anglesCos;
-		uniforms.spotLightExponent.value = lights.spot.exponents;
-		uniforms.spotLightDecay.value = lights.spot.decays;
-
-		uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
-		uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
-		uniforms.hemisphereLightDirection.value = lights.hemi.positions;
-
+		uniforms.directionalLights.value = lights.directional;
+		uniforms.pointLights.value = lights.point;
+		uniforms.spotLights.value = lights.spot;
+		uniforms.hemisphereLights.value = lights.hemi;
 	}
 
 	// If uniforms are marked as clean, they don't need to be loaded to the GPU.
@@ -2044,25 +2027,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		uniforms.ambientLightColor.needsUpdate = value;
 
-		uniforms.directionalLightColor.needsUpdate = value;
-		uniforms.directionalLightDirection.needsUpdate = value;
-
-		uniforms.pointLightColor.needsUpdate = value;
-		uniforms.pointLightPosition.needsUpdate = value;
-		uniforms.pointLightDistance.needsUpdate = value;
-		uniforms.pointLightDecay.needsUpdate = value;
-
-		uniforms.spotLightColor.needsUpdate = value;
-		uniforms.spotLightPosition.needsUpdate = value;
-		uniforms.spotLightDistance.needsUpdate = value;
-		uniforms.spotLightDirection.needsUpdate = value;
-		uniforms.spotLightAngleCos.needsUpdate = value;
-		uniforms.spotLightExponent.needsUpdate = value;
-		uniforms.spotLightDecay.needsUpdate = value;
-
-		uniforms.hemisphereLightSkyColor.needsUpdate = value;
-		uniforms.hemisphereLightGroundColor.needsUpdate = value;
-		uniforms.hemisphereLightDirection.needsUpdate = value;
+		uniforms.directionalLights.needsUpdate = value;
+		uniforms.pointLights.needsUpdate = value;
+		uniforms.spotLights.needsUpdate = value;
+		uniforms.hemisphereLights.needsUpdate = value;
 
 	}
 
@@ -2258,6 +2226,72 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 					break;
 
+				case 's':
+
+					// TODO: Optimize this.
+					for( var propertyName in uniform.properties ) {
+	
+						var property = uniform.properties[ propertyName ];
+						var locationProperty =  location[ propertyName ];
+						var valueProperty = value[ propertyName ];
+	
+						switch( property.type ) {
+							case 'f':
+								_gl.uniform1f( locationProperty, valueProperty );
+								break;
+							case 'v2':
+								_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
+								break;
+							case 'v3':
+								_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
+								break;
+							case 'v4':
+								_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
+								break;
+							case 'c':
+								_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
+								break;
+						};
+
+					}
+
+					break;
+
+				case 'sa':
+
+					// TODO: Optimize this.
+					for( var i = 0; i < value.length; i ++ ) {
+
+						for( var propertyName in uniform.properties ) {
+							
+							var property = uniform.properties[ propertyName ];
+							var locationProperty =  location[ i ][ propertyName ];
+							var valueProperty = value[i][ propertyName ];
+	
+							switch( property.type ) {
+								case 'f':
+									_gl.uniform1f( locationProperty, valueProperty );
+									break;
+								case 'v2':
+									_gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
+									break;
+								case 'v3':
+									_gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
+									break;
+								case 'v4':
+									_gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
+									break;
+								case 'c':
+									_gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
+									break;
+							};
+
+						}
+
+					}
+					
+					break;
+
 				case 'iv1':
 
 					// flat array of integers (JS or typed array)
@@ -2500,60 +2534,22 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	}
 
-	function setColorLinear( array, offset, color, intensity ) {
-
-		array[ offset + 0 ] = color.r * intensity;
-		array[ offset + 1 ] = color.g * intensity;
-		array[ offset + 2 ] = color.b * intensity;
-
-	}
-
 	function setupLights ( lights, camera ) {
 
 		var l, ll, light,
 		r = 0, g = 0, b = 0,
-		color, skyColor, groundColor,
+		color,
 		intensity,
 		distance,
 
 		zlights = _lights,
 
-		viewMatrix = camera.matrixWorldInverse,
-
-		dirColors = zlights.directional.colors,
-		dirPositions = zlights.directional.positions,
-
-		pointColors = zlights.point.colors,
-		pointPositions = zlights.point.positions,
-		pointDistances = zlights.point.distances,
-		pointDecays = zlights.point.decays,
-
-		spotColors = zlights.spot.colors,
-		spotPositions = zlights.spot.positions,
-		spotDistances = zlights.spot.distances,
-		spotDirections = zlights.spot.directions,
-		spotAnglesCos = zlights.spot.anglesCos,
-		spotExponents = zlights.spot.exponents,
-		spotDecays = zlights.spot.decays,
-
-		hemiSkyColors = zlights.hemi.skyColors,
-		hemiGroundColors = zlights.hemi.groundColors,
-		hemiPositions = zlights.hemi.positions,
-
-		dirLength = 0,
-		pointLength = 0,
-		spotLength = 0,
-		hemiLength = 0,
-
-		dirCount = 0,
-		pointCount = 0,
-		spotCount = 0,
-		hemiCount = 0,
+		viewMatrix = camera.matrixWorldInverse;
 
-		dirOffset = 0,
-		pointOffset = 0,
-		spotOffset = 0,
-		hemiOffset = 0;
+		zlights.directional = [];
+		zlights.point = [];
+		zlights.spot = [];
+		zlights.hemi = [];
 
 		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
 
@@ -2573,122 +2569,119 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			} else if ( light instanceof THREE.DirectionalLight ) {
 
-				dirCount += 1;
-
-				if ( ! light.visible ) continue;
-
-				_direction.setFromMatrixPosition( light.matrixWorld );
-				_vector3.setFromMatrixPosition( light.target.matrixWorld );
-				_direction.sub( _vector3 );
-				_direction.transformDirection( viewMatrix );
+				if( ! light.__webglUniforms ) {
+					light.__webglUniforms = {
+						direction: new THREE.Vector3(),
+						color: new THREE.Color()
+					}
+				}
 
-				dirOffset = dirLength * 3;
+				var lightUniforms = light.__webglUniforms;
+				zlights.directional.push( lightUniforms ); 
 
-				dirPositions[ dirOffset + 0 ] = _direction.x;
-				dirPositions[ dirOffset + 1 ] = _direction.y;
-				dirPositions[ dirOffset + 2 ] = _direction.z;
+				if ( ! light.visible ) {
+					lightUniforms.color.setRGB( 0, 0, 0 );
+					continue;
+				}
 
-				setColorLinear( dirColors, dirOffset, color, intensity );
+				lightUniforms.direction.setFromMatrixPosition( light.matrixWorld );
+				_vector3.setFromMatrixPosition( light.target.matrixWorld );
+				lightUniforms.direction.sub( _vector3 );
+				lightUniforms.direction.transformDirection( viewMatrix );
 
-				dirLength += 1;
+				lightUniforms.color.copy( light.color ).multiplyScalar( light.intensity );
 
 			} else if ( light instanceof THREE.PointLight ) {
 
-				pointCount += 1;
-
-				if ( ! light.visible ) continue;
-
-				pointOffset = pointLength * 3;
-
-				setColorLinear( pointColors, pointOffset, color, intensity );
+				if( ! light.__webglUniforms ) {
+					light.__webglUniforms = {
+						position: new THREE.Vector3(),
+						color: new THREE.Color(),
+						distance: 0,
+						decay: 0
+					}
+				}
 
-				_vector3.setFromMatrixPosition( light.matrixWorld );
-				_vector3.applyMatrix4( viewMatrix );
+				var lightUniforms = light.__webglUniforms;
+				zlights.point.push( lightUniforms ); 
 
-				pointPositions[ pointOffset + 0 ] = _vector3.x;
-				pointPositions[ pointOffset + 1 ] = _vector3.y;
-				pointPositions[ pointOffset + 2 ] = _vector3.z;
+				if ( ! light.visible ) {
+					lightUniforms.color.setRGB( 0, 0, 0 );
+					continue;
+				}
 
-				// distance is 0 if decay is 0, because there is no attenuation at all.
-				pointDistances[ pointLength ] = distance;
-				pointDecays[ pointLength ] = ( light.distance === 0 ) ? 0.0 : light.decay;
+				lightUniforms.position.setFromMatrixPosition( light.matrixWorld );
+				lightUniforms.position.applyMatrix4( viewMatrix );
 
-				pointLength += 1;
+				lightUniforms.color.copy( light.color ).multiplyScalar( light.intensity );
+				lightUniforms.distance = light.distance;
+				lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
 
 			} else if ( light instanceof THREE.SpotLight ) {
 
-				spotCount += 1;
-
-				if ( ! light.visible ) continue;
-
-				spotOffset = spotLength * 3;
+				if( ! light.__webglUniforms ) {
+					light.__webglUniforms = {
+						position: new THREE.Vector3(),
+						direction: new THREE.Vector3(),
+						color: new THREE.Color(),
+						distance: 0,
+						decay: 0,
+						angleCos: 0
+					}
+				}
 
-				setColorLinear( spotColors, spotOffset, color, intensity );
+				var lightUniforms = light.__webglUniforms;
+				zlights.spot.push( lightUniforms ); 
 
-				_direction.setFromMatrixPosition( light.matrixWorld );
-				_vector3.copy( _direction ).applyMatrix4( viewMatrix );
+				if ( ! light.visible ) {
+					lightUniforms.color.setRGB( 0, 0, 0 );
+					continue;
+				}
 
-				spotPositions[ spotOffset + 0 ] = _vector3.x;
-				spotPositions[ spotOffset + 1 ] = _vector3.y;
-				spotPositions[ spotOffset + 2 ] = _vector3.z;
+				lightUniforms.position.setFromMatrixPosition( light.matrixWorld );
+				lightUniforms.position.applyMatrix4( viewMatrix );
 
-				spotDistances[ spotLength ] = distance;
+				lightUniforms.color.copy( color ).multiplyScalar( intensity );
+				lightUniforms.distance = distance;
 
+				lightUniforms.direction.setFromMatrixPosition( light.matrixWorld );
 				_vector3.setFromMatrixPosition( light.target.matrixWorld );
-				_direction.sub( _vector3 );
-				_direction.transformDirection( viewMatrix );
+				lightUniforms.direction.sub( _vector3 );
+				lightUniforms.direction.transformDirection( viewMatrix );
 
-				spotDirections[ spotOffset + 0 ] = _direction.x;
-				spotDirections[ spotOffset + 1 ] = _direction.y;
-				spotDirections[ spotOffset + 2 ] = _direction.z;
-
-				spotAnglesCos[ spotLength ] = Math.cos( light.angle );
-				spotExponents[ spotLength ] = light.exponent;
-				spotDecays[ spotLength ] = ( light.distance === 0 ) ? 0.0 : light.decay;
-
-				spotLength += 1;
+				lightUniforms.angleCos = Math.cos( light.angle );
+				lightUniforms.exponent = light.exponent;
+				lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
 
 			} else if ( light instanceof THREE.HemisphereLight ) {
 
-				hemiCount += 1;
-
-				if ( ! light.visible ) continue;
-
-				_direction.setFromMatrixPosition( light.matrixWorld );
-				_direction.transformDirection( viewMatrix );
-
-				hemiOffset = hemiLength * 3;
+				if( ! light.__webglUniforms ) {
+					light.__webglUniforms = {
+						direction: new THREE.Vector3(),
+						skyColor: new THREE.Color(),
+						groundColor: new THREE.Color()
+					}
+				}
 
-				hemiPositions[ hemiOffset + 0 ] = _direction.x;
-				hemiPositions[ hemiOffset + 1 ] = _direction.y;
-				hemiPositions[ hemiOffset + 2 ] = _direction.z;
+				var lightUniforms = light.__webglUniforms;
+				zlights.hemi.push( lightUniforms ); 
 
-				skyColor = light.color;
-				groundColor = light.groundColor;
+				if ( ! light.visible ) {
+					lightUniforms.skyColor.setRGB( 0, 0, 0 );
+					continue;
+				}
 
-				setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
-				setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );
+				lightUniforms.direction.setFromMatrixPosition( light.matrixWorld );
+				lightUniforms.direction.transformDirection( viewMatrix );
+				lightUniforms.direction.normalize();
 
-				hemiLength += 1;
+				lightUniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
+				lightUniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
 
 			}
 
 		}
 
-		// null eventual remains from removed lights
-		// (this is to avoid if in shader)
-
-		for ( l = dirLength * 3, ll = Math.max( dirColors.length, dirCount * 3 ); l < ll; l ++ ) dirColors[ l ] = 0.0;
-		for ( l = pointLength * 3, ll = Math.max( pointColors.length, pointCount * 3 ); l < ll; l ++ ) pointColors[ l ] = 0.0;
-		for ( l = spotLength * 3, ll = Math.max( spotColors.length, spotCount * 3 ); l < ll; l ++ ) spotColors[ l ] = 0.0;
-		for ( l = hemiLength * 3, ll = Math.max( hemiSkyColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
-		for ( l = hemiLength * 3, ll = Math.max( hemiGroundColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
-
-		zlights.directional.length = dirLength;
-		zlights.point.length = pointLength;
-		zlights.spot.length = spotLength;
-		zlights.hemi.length = hemiLength;
-
 		zlights.ambient[ 0 ] = r;
 		zlights.ambient[ 1 ] = g;
 		zlights.ambient[ 2 ] = b;

+ 1 - 1
src/renderers/shaders/ShaderChunk/aomap_fragment.glsl

@@ -1,5 +1,5 @@
 #ifdef USE_AOMAP
 
-	totalAmbientLight *= ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;
+	indirectReflectedLight.diffuse *= ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;
 
 #endif

+ 149 - 0
src/renderers/shaders/ShaderChunk/bsdfs.glsl

@@ -0,0 +1,149 @@
+float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {
+
+	if ( decayExponent > 0.0 ) {
+
+	  return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );
+
+	}
+
+	return 1.0;
+
+}
+
+
+vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {
+
+	// factor of 1/PI in BRDF omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source
+
+	return diffuseColor;
+
+} // validated
+
+
+vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {
+
+	// Original approximation by Christophe Schlick '94
+	//;float fresnel = pow( 1.0 - dotLH, 5.0 );
+
+	// Optimized variant (presented by Epic at SIGGRAPH '13)
+	float fresnel = exp2( ( -5.55437 * dotLH - 6.98316 ) * dotLH );
+
+	return ( 1.0 - specularColor ) * fresnel + specularColor;
+
+} // validated
+
+
+// Microfacet Models for Refraction through Rough Surfaces - equation (34)
+// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
+// alpha is "roughness squared" in Disney’s reparameterization
+float G_GGX_Smith( in float alpha, in float dotNL, in float dotNV ) {
+
+	// geometry term = G(l)⋅G(v) / 4(n⋅l)(n⋅v)
+
+	float a2 = alpha * alpha;
+
+	float gl = dotNL + pow( a2 + ( 1.0 - a2 ) * dotNL * dotNL, 0.5 );
+
+	float gv = dotNV + pow( a2 + ( 1.0 - a2 ) * dotNV * dotNV, 0.5 );
+
+	return 1.0 / ( gl * gv );
+
+} // validated
+
+
+// Microfacet Models for Refraction through Rough Surfaces - equation (33)
+// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
+// alpha is "roughness squared" in Disney’s reparameterization
+float D_GGX( in float alpha, in float dotNH ) {
+
+	// factor of 1/PI in distribution term omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source
+
+	float a2 = alpha * alpha;
+
+	float denom = dotNH * dotNH * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1
+
+	return a2 / ( denom * denom );
+
+}
+
+
+// GGX Distribution, Schlick Fresnel, GGX-Smith Visibility
+vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {
+	
+	// factor of 1/PI in BRDF omitted (normally it is in D_GGX) as incoming light intensity is scaled up by PI because it is considered a punctual light source
+
+	float alpha = roughness * roughness; // UE4's roughness
+
+	vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );
+
+	float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );
+	float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
+	float dotNH = saturate( dot( geometry.normal, halfDir ) );
+	float dotLH = saturate( dot( incidentLight.direction, halfDir ) );
+
+	vec3 F = F_Schlick( specularColor, dotLH );
+
+	float G = G_GGX_Smith( alpha, dotNL, dotNV );
+
+	float D = D_GGX( alpha, dotNH );
+
+	return F * ( G * D );
+
+} // validated
+
+
+// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile
+vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, vec3 specularColor, float roughness ) {
+
+	float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
+
+	const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );
+
+	const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );
+
+	vec4 r = roughness * c0 + c1;
+
+	float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;
+
+	vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
+
+	return specularColor * AB.x + AB.y;
+
+} // validated
+
+
+float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) {
+
+	// geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v)
+	return 0.25;
+
+}
+
+float D_BlinnPhong( const in float shininess, const in float dotNH ) {
+
+	// factor of 1/PI in distribution term omitted as incoming light intensity is scaled up by PI because it is considered a punctual light source
+
+	return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );
+
+}
+
+vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {
+
+	// factor of 1/PI in BRDF omitted (normally it is in D_BlinnPhong) as incoming light intensity is scaled up by PI because it is considered a punctual light source
+
+	vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );
+
+	//float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );
+	//float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
+	float dotNH = saturate( dot( geometry.normal, halfDir ) );
+	float dotLH = saturate( dot( incidentLight.direction, halfDir ) );
+
+	vec3 F = F_Schlick( specularColor, dotLH );
+
+	float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );
+
+	float D = D_BlinnPhong( shininess, dotNH );
+
+	return F * ( G * D );
+
+} // validated

+ 21 - 142
src/renderers/shaders/ShaderChunk/common.glsl

@@ -1,5 +1,6 @@
 #define PI 3.14159
 #define PI2 6.28318
+#define RECIPROCAL_PI 0.31830988618
 #define RECIPROCAL_PI2 0.15915494
 #define LOG2 1.442695
 #define EPSILON 1e-6
@@ -7,6 +8,26 @@
 #define saturate(a) clamp( a, 0.0, 1.0 )
 #define whiteCompliment(a) ( 1.0 - saturate( a ) )
 
+float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
+
+
+struct IncidentLight {
+ 	vec3 color;
+ 	vec3 direction;
+};
+
+struct ReflectedLight {
+ 	vec3 specular;
+ 	vec3 diffuse;
+};
+
+struct GeometricContext {
+	vec3 position;
+	vec3 normal;
+	vec3 viewDir;
+};
+
+
 vec3 transformDirection( in vec3 normal, in mat4 matrix ) {
 
 	return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz );
@@ -40,148 +61,6 @@ vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 poi
 
 }
 
-float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {
-
-	if ( decayExponent > 0.0 ) {
-
-	  return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );
-
-	}
-
-	return 1.0;
-
-}
-
-vec3 F_Schlick( in vec3 specularColor, in float dotLH ) {
-
-	// Original approximation by Christophe Schlick '94
-	//;float fresnel = pow( 1.0 - dotLH, 5.0 );
-
-	// Optimized variant (presented by Epic at SIGGRAPH '13)
-	float fresnel = exp2( ( -5.55437 * dotLH - 6.98316 ) * dotLH );
-
-	return ( 1.0 - specularColor ) * fresnel + specularColor;
-
-}
-
-float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) {
-
-	// geometry term is (n⋅l)(n⋅v) / 4(n⋅l)(n⋅v)
-
-	return 0.25;
-
-}
-
-float D_BlinnPhong( in float shininess, in float dotNH ) {
-
-	// factor of 1/PI in distribution term omitted
-
-	return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );
-
-}
-
-vec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in vec3 normal, in vec3 lightDir, in vec3 viewDir ) {
-
-	vec3 halfDir = normalize( lightDir + viewDir );
-
-	//float dotNL = saturate( dot( normal, lightDir ) );
-	//float dotNV = saturate( dot( normal, viewDir ) );
-	float dotNH = saturate( dot( normal, halfDir ) );
-	float dotLH = saturate( dot( lightDir, halfDir ) );
-
-	vec3 F = F_Schlick( specularColor, dotLH );
-
-	float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );
-
-	float D = D_BlinnPhong( shininess, dotNH );
-
-	return F * G * D;
-
-}
-
-// Microfacet Models for Refraction through Rough Surfaces - equation (34)
-// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
-// alpha is "roughness squared" in Disney’s reparameterization
-float G_GGX_Smith( in float alpha, in float dotNL, in float dotNV ) {
-
-	// geometry term = G(l)⋅G(v) / 4(n⋅l)(n⋅v)
-
-	float a2 = alpha * alpha;
-
-	float gl = dotNL + pow( a2 + ( 1.0 - a2 ) * dotNL * dotNL, 0.5 );
-
-	float gv = dotNV + pow( a2 + ( 1.0 - a2 ) * dotNV * dotNV, 0.5 );
-
-	return 1.0 / ( gl * gv );
-
-}
-
-// Microfacet Models for Refraction through Rough Surfaces - equation (33)
-// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
-// alpha is "roughness squared" in Disney’s reparameterization
-float D_GGX( in float alpha, in float dotNH ) {
-
-	// factor of 1/PI in distribution term omitted
-
-	float a2 = alpha * alpha;
-
-	float denom = dotNH * dotNH * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1
-
-	return a2 / ( denom * denom );
-
-}
-
-// GGX Distribution, Schlick Fresnel, GGX-Smith Visibility
-vec3 BRDF_GGX( in vec3 specularColor, in float roughness, in vec3 normal, in vec3 lightDir, in vec3 viewDir ) {
-
-	// factor of 1/PI in BRDF omitted
-
-	float alpha = roughness * roughness; // UE4's roughness
-
-	vec3 halfDir = normalize( lightDir + viewDir );
-
-	float dotNL = saturate( dot( normal, lightDir ) );
-	float dotNV = saturate( dot( normal, viewDir ) );
-	float dotNH = saturate( dot( normal, halfDir ) );
-	float dotLH = saturate( dot( lightDir, halfDir ) );
-
-	vec3 F = F_Schlick( specularColor, dotLH );
-
-	float G = G_GGX_Smith( alpha, dotNL, dotNV );
-
-	float D = D_GGX( alpha, dotNH );
-
-	return F * G * D;
-
-}
-
-vec3 BRDF_Lambert( in vec3 diffuseColor ) {
-
-	// factor of 1/PI in BRDF omitted
-
-	return diffuseColor;
-
-}
-
-// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile
-vec3 envBRDFApprox( vec3 specularColor, float roughness, in vec3 normal, in vec3 viewDir  ) {
-
-	float dotNV = saturate( dot( normal, viewDir ) );
-
-	const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );
-
-	const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );
-
-	vec4 r = roughness * c0 + c1;
-
-	float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;
-
-	vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
-
-	return specularColor * AB.x + AB.y;
-
-}
-
 vec3 inputToLinear( in vec3 a ) {
 
 	#ifdef GAMMA_INPUT

+ 0 - 63
src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl

@@ -1,63 +0,0 @@
-#ifdef USE_ENVMAP
-
-	float reflectivityFactor = reflectivity; // fix add map - replace specular strength?
-
-	vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );
-
-	// Transforming Normal Vectors with the Inverse Transformation
-	vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
-
-	#ifdef ENVMAP_MODE_REFLECTION
-
-		vec3 reflectVec = reflect( cameraToVertex, worldNormal );
-
-	#else
-
-		vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );
-
-	#endif
-
-	#ifdef DOUBLE_SIDED
-
-		float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );
-
-	#else
-
-		float flipNormal = 1.0;
-
-	#endif
-
-	#ifdef ENVMAP_TYPE_CUBE
-
-		#if defined( TEXTURE_CUBE_LOD_EXT )
-
-			float bias = pow( roughness, 0.5 ) * 7.0; // from bhouston - there are other models for this calculation (roughness; not roughnesFactor)
-
-			vec4 envMapColor = textureCubeLodEXT( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), bias );
-
-		#else
-
-			vec4 envMapColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
-
-		#endif
-
-	#elif defined( ENVMAP_TYPE_EQUIREC )
-
-		vec2 sampleUV;
-		sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );
-		sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;
-		vec4 envMapColor = texture2D( envMap, sampleUV );
-
-	#elif defined( ENVMAP_TYPE_SPHERE )
-
-		vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));
-		vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );
-
-	#endif
-
-	envMapColor.rgb = inputToLinear( envMapColor.rgb );
-
-    outgoingLight += envBRDFApprox( specularColor, roughnessFactor, normal, viewDir  ) * envMapColor.rgb * envMapIntensity * reflectivityFactor;
-
-#endif
-

+ 0 - 18
src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl

@@ -1,18 +0,0 @@
-#if MAX_HEMI_LIGHTS > 0
-
-	for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {
-
-		vec3 lightDir = hemisphereLightDirection[ i ];
-
-		float dotProduct = dot( normal, lightDir );
-
-		float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;
-
-		vec3 lightColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );
-
-		totalAmbientLight += lightColor;
-
-	}
-
-#endif
-

+ 0 - 5
src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl

@@ -1,5 +0,0 @@
-#ifdef USE_LIGHTMAP
-
-	totalAmbientLight += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;
-
-#endif

+ 39 - 70
src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl

@@ -1,35 +1,22 @@
-vLightFront = vec3( 0.0 );
+vec3 diffuse = vec3( 1.0 );
 
-#ifdef DOUBLE_SIDED
-
-	vLightBack = vec3( 0.0 );
-
-#endif
-
-vec3 normal = normalize( transformedNormal );
+GeometricContext geometry = GeometricContext( mvPosition.xyz, normalize( transformedNormal ), normalize( -mvPosition.xyz ) );
+GeometricContext backGeometry = GeometricContext( geometry.position, -geometry.normal, geometry.viewDir );
 
 #if MAX_POINT_LIGHTS > 0
 
 	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
 
-		vec3 lightColor = pointLightColor[ i ];
-
-		vec3 lVector = pointLightPosition[ i ] - mvPosition.xyz;
-		vec3 lightDir = normalize( lVector );
-
-		// attenuation
-
-		float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );
-
-		// diffuse
+		IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry );
 
-		float dotProduct = dot( normal, lightDir );
+		float dotNL = dot( geometry.normal, directLight.direction );
+		vec3 directLightColor_Diffuse = directLight.color * BRDF_Diffuse_Lambert( diffuse );
 
-		vLightFront += lightColor * attenuation * saturate( dotProduct );
+		vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
 
 		#ifdef DOUBLE_SIDED
 
-			vLightBack += lightColor * attenuation * saturate( - dotProduct );
+			vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;
 
 		#endif
 
@@ -41,38 +28,18 @@ vec3 normal = normalize( transformedNormal );
 
 	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {
 
-		vec3 lightColor = spotLightColor[ i ];
-
-		vec3 lightPosition = spotLightPosition[ i ];
-		vec3 lVector = lightPosition - mvPosition.xyz;
-		vec3 lightDir = normalize( lVector );
-
-		float spotEffect = dot( spotLightDirection[ i ], lightDir );
-
-		if ( spotEffect > spotLightAngleCos[ i ] ) {
-
-			spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) );
-
-			// attenuation
-
-			float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );
-
-			attenuation *= spotEffect;
+		IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry );
 
-			// diffuse
+		float dotNL = dot( geometry.normal, directLight.direction );
+		vec3 directLightColor_Diffuse = directLight.color * BRDF_Diffuse_Lambert( diffuse );
 
-			float dotProduct = dot( normal, lightDir );
+		vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
 
-			vLightFront += lightColor * attenuation * saturate( dotProduct );
-
-			#ifdef DOUBLE_SIDED
-
-				vLightBack += lightColor * attenuation * saturate( - dotProduct );
-
-			#endif
+		#ifdef DOUBLE_SIDED
 
-		}
+			vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;
 
+		#endif
 	}
 
 #endif
@@ -81,19 +48,16 @@ vec3 normal = normalize( transformedNormal );
 
 	for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
 
-		vec3 lightColor = directionalLightColor[ i ];
-
-		vec3 lightDir = directionalLightDirection[ i ];
-
-		// diffuse
+		IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry );
 
-		float dotProduct = dot( normal, lightDir );
+		float dotNL = dot( geometry.normal, directLight.direction );
+		vec3 directLightColor_Diffuse = directLight.color * BRDF_Diffuse_Lambert( diffuse );
 
-		vLightFront += lightColor * saturate( dotProduct );
+		vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
 
 		#ifdef DOUBLE_SIDED
 
-			vLightBack += lightColor * saturate( - dotProduct );
+			vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;
 
 		#endif
 
@@ -101,28 +65,33 @@ vec3 normal = normalize( transformedNormal );
 
 #endif
 
-#if MAX_HEMI_LIGHTS > 0
+	{
+		// dotNL is always one, and diffuseColor is vec3(1.0), thus the result is equivalent to summing indirectDiffuse lights
+		//float frontDotNL = saturate( dot( geometry.normal, frontIndirectLight.direction ) );
+		//vLightFront += frontDotNL * frontIndirectLight.color * BRDF_Diffuse_Lambert( diffuse );
+		
+		vLightFront += ambientLightColor;
 
-	for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {
-
-		vec3 lightDir = hemisphereLightDirection[ i ];
+		#ifdef DOUBLE_SIDED
+		
+			vLightBack += ambientLightColor;
 
-		// diffuse
+		#endif
 
-		float dotProduct = dot( normal, lightDir );
+		#if MAX_HEMI_LIGHTS > 0
 
-		float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;
+			for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {
 
-		vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );
+				vLightFront += getHemisphereIndirectLightColor( hemisphereLights[ i ], geometry );
 
-		#ifdef DOUBLE_SIDED
+				#ifdef DOUBLE_SIDED
+			
+					vLightBack += getHemisphereIndirectLightColor( hemisphereLights[ i ], backGeometry );
 
-			float hemiDiffuseWeightBack = - 0.5 * dotProduct + 0.5;
+				#endif
 
-			vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );
+			}
 
 		#endif
 
-	}
-
-#endif
+	}

+ 150 - 18
src/renderers/shaders/ShaderChunk/lights_pars.glsl

@@ -1,35 +1,167 @@
+uniform vec3 ambientLightColor;
+
+
 #if MAX_DIR_LIGHTS > 0
 
-	uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];
-	uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];
+	struct DirectionalLight {
+	  vec3 direction;
+	  vec3 color;
+	};
 
-#endif
+	uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ];
 
-#if MAX_HEMI_LIGHTS > 0
+	IncidentLight getDirectionalDirectLight( const in DirectionalLight directionalLight, const in GeometricContext geometry ) { 
 
-	uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];
-	uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];
-	uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];
+		IncidentLight directLight;
+	
+		directLight.color = directionalLight.color;
+		directLight.direction = directionalLight.direction; 
+
+		return directLight;
+	}
 
 #endif
 
+
 #if MAX_POINT_LIGHTS > 0
 
-	uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];
-	uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];
-	uniform float pointLightDistance[ MAX_POINT_LIGHTS ];
-	uniform float pointLightDecay[ MAX_POINT_LIGHTS ];
+	struct PointLight {
+	  vec3 position;
+	  vec3 color;
+	  float distance;
+	  float decay;
+	};
+
+	uniform PointLight pointLights[ MAX_POINT_LIGHTS ];
+
+	IncidentLight getPointDirectLight( const in PointLight pointLight, const in GeometricContext geometry ) { 
+	
+		IncidentLight directLight;
+	
+		vec3 lVector = pointLight.position - geometry.position; 
+		directLight.direction = normalize( lVector ); 
+	
+		directLight.color = pointLight.color; 
+		directLight.color *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay ); 
+	
+		return directLight;
+	}
 
 #endif
 
+
 #if MAX_SPOT_LIGHTS > 0
 
-	uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];
-	uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];
-	uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];
-	uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];
-	uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];
-	uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];
-	uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];
+	struct SpotLight {
+	  vec3 position;
+	  vec3 direction;
+	  vec3 color;
+	  float distance;
+	  float decay;
+	  float angleCos;
+	  float exponent;
+	};
+
+	uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ];
+
+	IncidentLight getSpotDirectLight( const in SpotLight spotLight, const in GeometricContext geometry ) {
+	
+		IncidentLight directLight;
+
+		vec3 lVector = spotLight.position - geometry.position;
+		directLight.direction = normalize( lVector );
+	
+		float spotEffect = dot( spotLight.direction, directLight.direction );
+		spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) );
+	
+		directLight.color = spotLight.color;
+		directLight.color *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) );
+
+		return directLight;
+	}
 
 #endif
+
+
+#if MAX_HEMI_LIGHTS > 0
+
+	struct HemisphereLight {
+	  vec3 direction;
+	  vec3 skyColor;
+	  vec3 groundColor;
+	};
+
+	uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ];
+
+	vec3 getHemisphereIndirectLightColor( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { 
+	
+		float dotNL = dot( geometry.normal, hemiLight.direction );
+		float hemiDiffuseWeight = 0.5 * dotNL + 0.5;
+
+		return mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );
+
+	}
+
+#endif
+
+
+#if defined( USE_ENVMAP ) && defined( PHYSICAL )
+
+	vec3 getSpecularLightProbeIndirectLightColor( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float lodLevel ) { 
+	
+		#ifdef ENVMAP_MODE_REFLECTION
+
+			vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );
+
+		#else
+
+			vec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );
+
+		#endif
+
+		#ifdef DOUBLE_SIDED
+
+			float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );
+
+		#else
+
+			float flipNormal = 1.0;
+
+		#endif
+
+		reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
+
+		#ifdef ENVMAP_TYPE_CUBE
+
+			#if defined( TEXTURE_CUBE_LOD_EXT )				
+
+				vec4 envMapColor = textureCubeLodEXT( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ), lodLevel );
+
+			#else
+
+				vec4 envMapColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
+
+			#endif
+
+		#elif defined( ENVMAP_TYPE_EQUIREC )
+
+			vec2 sampleUV;
+			sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );
+			sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;
+			vec4 envMapColor = texture2D( envMap, sampleUV );
+
+		#elif defined( ENVMAP_TYPE_SPHERE )
+
+			vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));
+			vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );
+
+		#endif
+
+		envMapColor.rgb = inputToLinear( envMapColor.rgb );
+
+		return envMapColor.rgb * reflectivity;
+
+	}
+
+#endif
+

+ 7 - 96
src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl

@@ -1,99 +1,10 @@
-vec3 viewDir = normalize( vViewPosition );
+BlinnPhongMaterial material;
+material.specularColor = specular;
+material.specularShininess = shininess;
+material.diffuseColor = diffuseColor.rgb;
 
-vec3 totalDiffuseLight = vec3( 0.0 );
-vec3 totalSpecularLight = vec3( 0.0 );
+#ifdef METAL
 
-#if MAX_POINT_LIGHTS > 0
+	material.diffuseColor = vec3( 0.0 );
 
-	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
-
-		vec3 lightColor = pointLightColor[ i ];
-
-		vec3 lightPosition = pointLightPosition[ i ];
-		vec3 lVector = lightPosition + vViewPosition.xyz;
-		vec3 lightDir = normalize( lVector );
-
-		// attenuation
-
-		float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );
-
-		// diffuse
-
-		float cosineTerm = saturate( dot( normal, lightDir ) );
-
-		totalDiffuseLight += lightColor * attenuation * cosineTerm;
-
-		// specular
-
-		vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir );
-
-		totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;
-
-
-	}
-
-#endif
-
-#if MAX_SPOT_LIGHTS > 0
-
-	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {
-
-		vec3 lightColor = spotLightColor[ i ];
-
-		vec3 lightPosition = spotLightPosition[ i ];
-		vec3 lVector = lightPosition + vViewPosition.xyz;
-		vec3 lightDir = normalize( lVector );
-
-		float spotEffect = dot( spotLightDirection[ i ], lightDir );
-
-		if ( spotEffect > spotLightAngleCos[ i ] ) {
-
-			spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) );
-
-			// attenuation
-
-			float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );
-
-			attenuation *= spotEffect;
-
-			// diffuse
-
-			float cosineTerm = saturate( dot( normal, lightDir ) );
-
-			totalDiffuseLight += lightColor * attenuation * cosineTerm;
-
-			// specular
-
-			vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir );
-
-			totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;
-
-		}
-
-	}
-
-#endif
-
-#if MAX_DIR_LIGHTS > 0
-
-	for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
-
-		vec3 lightColor = directionalLightColor[ i ];
-
-		vec3 lightDir = directionalLightDirection[ i ];
-
-		// diffuse
-
-		float cosineTerm = saturate( dot( normal, lightDir ) );
-
-		totalDiffuseLight += lightColor * cosineTerm;
-
-		// specular
-
-		vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir );
-
-		totalSpecularLight += brdf * specularStrength * lightColor * cosineTerm;
-
-	}
-
-#endif
+#endif

+ 31 - 2
src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl

@@ -1,5 +1,3 @@
-uniform vec3 ambientLightColor;
-
 #if MAX_SPOT_LIGHTS > 0 || defined( USE_ENVMAP )
 
 	varying vec3 vWorldPosition;
@@ -13,3 +11,34 @@ varying vec3 vViewPosition;
 	varying vec3 vNormal;
 
 #endif
+
+
+struct BlinnPhongMaterial {
+	vec3	diffuseColor;
+	float	specularShininess;
+	vec3	specularColor;
+};
+
+void BlinnPhongMaterial_RE_DirectLight( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight directReflectedLight ) {
+
+	float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
+
+	directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( material.diffuseColor );
+
+	directReflectedLight.specular += dotNL * directLight.color * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess );
+	
+}
+
+#define Material_RE_DirectLight    BlinnPhongMaterial_RE_DirectLight
+
+void BlinnPhongMaterial_RE_IndirectDiffuseLight( const in vec3 indirectDiffuseColor, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight indirectReflectedLight ) {
+
+	//float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) );  not required because result is always 1.0
+
+	indirectReflectedLight.diffuse += indirectDiffuseColor * BRDF_Diffuse_Lambert( material.diffuseColor );
+
+}
+
+#define Material_RE_IndirectDiffuseLight    BlinnPhongMaterial_RE_IndirectDiffuseLight
+
+#define Material_LightProbeLOD( material )   (0)

+ 4 - 112
src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl

@@ -1,112 +1,4 @@
-vec3 viewDir = normalize( vViewPosition );
-
-vec3 totalDiffuseLight = vec3( 0.0 );
-vec3 totalSpecularLight = vec3( 0.0 );
-
-
-// roughness linear remapping
-
-roughnessFactor = roughnessFactor * 0.5 + 0.5; // disney's remapping of [ 0, 1 ] roughness to [ 0.5, 1 ]
-
-
-// metalness effect on color
-
-vec3 specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );
-
-diffuseColor.rgb *= ( 1.0 - metalnessFactor );
-
-
-#if MAX_POINT_LIGHTS > 0
-
-	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
-
-		vec3 lightColor = pointLightColor[ i ];
-
-		vec3 lightPosition = pointLightPosition[ i ];
-		vec3 lVector = lightPosition + vViewPosition.xyz;
-		vec3 lightDir = normalize( lVector );
-
-		// attenuation
-
-		float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );
-
-		// diffuse
-
-		float cosineTerm = saturate( dot( normal, lightDir ) );
-
-		totalDiffuseLight += lightColor * attenuation * cosineTerm;
-
-		// specular
-
-    	vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir );
-
-		totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;
-
-
-	}
-
-#endif
-
-#if MAX_SPOT_LIGHTS > 0
-
-	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {
-
-		vec3 lightColor = spotLightColor[ i ];
-
-		vec3 lightPosition = spotLightPosition[ i ];
-		vec3 lVector = lightPosition + vViewPosition.xyz;
-		vec3 lightDir = normalize( lVector );
-
-		float spotEffect = dot( spotLightDirection[ i ], lightDir );
-
-		if ( spotEffect > spotLightAngleCos[ i ] ) {
-
-			spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) );
-
-			// attenuation
-
-			float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );
-
-			attenuation *= spotEffect;
-
-			// diffuse
-
-			float cosineTerm = saturate( dot( normal, lightDir ) );
-
-			totalDiffuseLight += lightColor * attenuation * cosineTerm;
-
-			// specular
-
-    		vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir );
-
-			totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;
-
-		}
-
-	}
-
-#endif
-
-#if MAX_DIR_LIGHTS > 0
-
-	for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
-
-		vec3 lightColor = directionalLightColor[ i ];
-
-		vec3 lightDir = directionalLightDirection[ i ];
-
-		// diffuse
-
-		float cosineTerm = saturate( dot( normal, lightDir ) );
-
-		totalDiffuseLight += lightColor * cosineTerm;
-
-		// specular
-
-    	vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir );
-
-		totalSpecularLight += brdf * specularStrength * lightColor * cosineTerm;
-
-	}
-
-#endif
+PhysicalMaterial material;
+material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );
+material.specularRoughness = roughnessFactor * 0.5 + 0.5; // disney's remapping of [ 0, 1 ] roughness to [ 0.5, 1 ]
+material.specularColor = mix( vec3( 0.04 ) * reflectivity, diffuseColor.rgb, metalnessFactor );

+ 42 - 0
src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl

@@ -0,0 +1,42 @@
+struct PhysicalMaterial {
+	vec3	diffuseColor;
+	float	specularRoughness;
+	vec3	specularColor;
+	float	clearCoatWeight;
+	float	clearCoatRoughness;
+};
+
+void PhysicalMaterial_RE_DirectLight( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight directReflectedLight ) {
+
+	float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
+
+	directReflectedLight.diffuse += dotNL * directLight.color * BRDF_Diffuse_Lambert( material.diffuseColor );
+	directReflectedLight.specular += dotNL * directLight.color * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );
+	
+}
+#define Material_RE_DirectLight    PhysicalMaterial_RE_DirectLight
+
+
+void PhysicalMaterial_RE_DiffuseIndirectLight( const in vec3 indirectDiffuseColor, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) {
+
+	//float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) );  not required because result is always 1.0
+
+	indirectReflectedLight.diffuse += indirectDiffuseColor * BRDF_Diffuse_Lambert( material.diffuseColor );
+
+}
+
+#define Material_RE_IndirectDiffuseLight    PhysicalMaterial_RE_DiffuseIndirectLight
+
+
+void PhysicalMaterial_RE_SpecularIndirectLight( const in vec3 indirectSpecularColor, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight indirectReflectedLight ) {
+
+	//float dotNL = saturate( dot( geometry.normal, indirectLight.direction ) );  not required because result is always 1.0
+
+    indirectReflectedLight.specular += indirectSpecularColor * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );
+
+}
+
+// from bhouston - there are other models for this calculation (roughness; not roughnesFactor)
+#define Material_LightProbeLOD( material )   (pow( ( material.specularRoughness - 0.5 ) * 2.0, 0.5 ) * 7.0)
+
+#define Material_RE_IndirectSpecularLight    PhysicalMaterial_RE_SpecularIndirectLight

+ 92 - 0
src/renderers/shaders/ShaderChunk/lights_template.glsl

@@ -0,0 +1,92 @@
+//
+// This is a template that can be used to light a material, it uses pluggable RenderEquations (RE)
+//   for specific lighting scenarios.
+//
+// Instructions for use:
+//  - Ensure that both Material_RE_DirectLight, Material_RE_IndirectDiffuseLight and Material_RE_IndirectSpecularLight are defined
+//  - If you have defined a Material_RE_IndirectSpecularLight, you need to also provide a Material_LightProbeLOD.
+//  - Create a material parameter that is to be passed as the third parameter to your lighting functions.
+//
+// TODO:
+//  - Add area light support.
+//  - Add sphere light support.
+//  - Add diffuse light probe (irradiance cubemap) support.
+//
+
+GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) );
+
+#if ( MAX_POINT_LIGHTS > 0 ) && defined( Material_RE_DirectLight )
+
+	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
+
+		IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry );
+
+		Material_RE_DirectLight( directLight, geometry, material, directReflectedLight );
+
+	}
+
+#endif
+
+#if ( MAX_SPOT_LIGHTS > 0 ) && defined( Material_RE_DirectLight )
+
+	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {
+
+		IncidentLight directLight = getSpotDirectLight( spotLights[ i ], geometry );
+
+		Material_RE_DirectLight( directLight, geometry, material, directReflectedLight );
+
+	}
+
+#endif
+
+#if ( MAX_DIR_LIGHTS > 0 ) && defined( Material_RE_DirectLight )
+
+	for ( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
+
+		IncidentLight directLight = getDirectionalDirectLight( directionalLights[ i ], geometry );
+
+		Material_RE_DirectLight( directLight, geometry, material, directReflectedLight );
+		
+	}
+
+#endif
+
+#if defined( Material_RE_IndirectDiffuseLight )
+
+	{
+	
+		vec3 indirectDiffuseColor = ambientLightColor;
+
+#ifdef USE_LIGHTMAP
+
+		indirectDiffuseColor += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;
+
+#endif
+
+#if ( MAX_HEMI_LIGHTS > 0 )
+
+		for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {
+
+			indirectDiffuseColor += getHemisphereIndirectLightColor( hemisphereLights[ i ], geometry );
+
+		}
+
+#endif
+
+		Material_RE_IndirectDiffuseLight( indirectDiffuseColor, geometry, material, indirectReflectedLight );
+
+	}
+
+#endif
+
+#if defined( USE_ENVMAP ) && defined( Material_RE_IndirectSpecularLight )
+
+	{
+
+		vec3 indirectSpecularColor = getSpecularLightProbeIndirectLightColor( /*specularLightProbe,*/ geometry, Material_LightProbeLOD( material ) );
+
+    	Material_RE_IndirectSpecularLight( indirectSpecularColor, geometry, material, indirectReflectedLight );
+
+    }
+
+#endif

+ 57 - 36
src/renderers/shaders/ShaderLib.js

@@ -67,6 +67,12 @@ THREE.ShaderLib = {
 			"uniform vec3 diffuse;",
 			"uniform float opacity;",
 
+			"#ifndef FLAT_SHADED",
+
+			"	varying vec3 vNormal;",
+
+			"#endif",
+
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "color_pars_fragment" ],
 			THREE.ShaderChunk[ "uv_pars_fragment" ],
@@ -82,9 +88,7 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	vec3 outgoingLight = vec3( 0.0 );",
 			"	vec4 diffuseColor = vec4( diffuse, opacity );",
-			"	vec3 totalAmbientLight = vec3( 1.0 );", // hardwired
 			"	vec3 shadowMask = vec3( 1.0 );",
 
 				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
@@ -93,15 +97,17 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "alphamap_fragment" ],
 				THREE.ShaderChunk[ "alphatest_fragment" ],
 				THREE.ShaderChunk[ "specularmap_fragment" ],
+
+			"	ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), diffuseColor.rgb );",
+
 				THREE.ShaderChunk[ "aomap_fragment" ],
 				THREE.ShaderChunk[ "shadowmap_fragment" ],
-
-			"	outgoingLight = diffuseColor.rgb * totalAmbientLight * shadowMask;",
+				"indirectReflectedLight.diffuse *= shadowMask;",
+		
+				"vec3 outgoingLight = indirectReflectedLight.diffuse;",
 
 				THREE.ShaderChunk[ "envmap_fragment" ],
-
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-
 				THREE.ShaderChunk[ "fog_fragment" ],
 
 			"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
@@ -143,6 +149,7 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "uv_pars_vertex" ],
 			THREE.ShaderChunk[ "uv2_pars_vertex" ],
 			THREE.ShaderChunk[ "envmap_pars_vertex" ],
+			THREE.ShaderChunk[ "bsdfs" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "color_pars_vertex" ],
 			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
@@ -223,18 +230,18 @@ THREE.ShaderLib = {
 			"	#ifdef DOUBLE_SIDED",
 
 			"		if ( gl_FrontFacing )",
-			"			outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;",
+			"			outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask ) + emissive;",
 			"		else",
-			"			outgoingLight += diffuseColor.rgb * ( vLightBack * shadowMask + totalAmbientLight ) + emissive;",
+			"			outgoingLight += diffuseColor.rgb * ( vLightBack * shadowMask ) + emissive;",
 
 			"	#else",
 
-			"		outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;",
+			"		outgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask ) + emissive;",
 
 			"	#endif",
 
 				THREE.ShaderChunk[ "envmap_fragment" ],
-
+		
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 
 				THREE.ShaderChunk[ "fog_fragment" ],
@@ -340,7 +347,7 @@ THREE.ShaderLib = {
 			"uniform float shininess;",
 			"uniform float opacity;",
 
-			THREE.ShaderChunk[ "common" ],
+			THREE.ShaderChunk[ "common" ],	
 			THREE.ShaderChunk[ "color_pars_fragment" ],
 			THREE.ShaderChunk[ "uv_pars_fragment" ],
 			THREE.ShaderChunk[ "uv2_pars_fragment" ],
@@ -351,6 +358,7 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "emissivemap_pars_fragment" ],
 			THREE.ShaderChunk[ "envmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
+			THREE.ShaderChunk[ "bsdfs" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
@@ -361,12 +369,11 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	vec3 outgoingLight = vec3( 0.0 );",
 			"	vec4 diffuseColor = vec4( diffuse, opacity );",
-			"	vec3 totalAmbientLight = ambientLightColor;",
+			"	ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );",
+			"	ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );",
 			"	vec3 totalEmissiveLight = emissive;",
-			"	vec3 shadowMask = vec3( 1.0 );",
-
+			
 				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 				THREE.ShaderChunk[ "map_fragment" ],
 				THREE.ShaderChunk[ "color_fragment" ],
@@ -374,29 +381,32 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "alphatest_fragment" ],
 				THREE.ShaderChunk[ "specularmap_fragment" ],
 				THREE.ShaderChunk[ "normal_phong_fragment" ],
-				THREE.ShaderChunk[ "lightmap_fragment" ],
-				THREE.ShaderChunk[ "hemilight_fragment" ],
-				THREE.ShaderChunk[ "aomap_fragment" ],
 				THREE.ShaderChunk[ "emissivemap_fragment" ],
 
+				// accumulation
 				THREE.ShaderChunk[ "lights_phong_fragment" ],
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
+				THREE.ShaderChunk[ "lights_template" ],
+				THREE.ShaderChunk[ "lightmap_fragment" ],
 
-				"totalDiffuseLight *= shadowMask;",
-				"totalSpecularLight *= shadowMask;",
+				// modulation
+				THREE.ShaderChunk[ "aomap_fragment" ],
+			
+				"vec3 shadowMask = vec3( 1.0 );",
+				THREE.ShaderChunk[ "shadowmap_fragment" ],
+				"directReflectedLight.diffuse *= shadowMask;",
+				"directReflectedLight.specular *= shadowMask;",
 
 				"#ifdef METAL",
 
-				"	outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) * specular + totalSpecularLight + totalEmissiveLight;",
+				"	vec3 outgoingLight = ( directReflectedLight.diffuse + indirectReflectedLight.diffuse ) * specular + directReflectedLight.specular + indirectReflectedLight.specular + totalEmissiveLight;",
 
 				"#else",
 
-				"	outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) + totalSpecularLight + totalEmissiveLight;",
+				"	vec3 outgoingLight = ( directReflectedLight.diffuse + indirectReflectedLight.diffuse ) + directReflectedLight.specular + indirectReflectedLight.specular + totalEmissiveLight;",
 
 				"#endif",
 
 				THREE.ShaderChunk[ "envmap_fragment" ],
-
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 
 				THREE.ShaderChunk[ "fog_fragment" ],
@@ -509,6 +519,14 @@ THREE.ShaderLib = {
 
 			"uniform float envMapIntensity;", // temporary
 
+			"varying vec3 vViewPosition;",
+
+			"#ifndef FLAT_SHADED",
+
+			"	varying vec3 vNormal;",
+
+			"#endif",
+
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "color_pars_fragment" ],
 			THREE.ShaderChunk[ "uv_pars_fragment" ],
@@ -520,8 +538,9 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "emissivemap_pars_fragment" ],
 			THREE.ShaderChunk[ "envmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
+			THREE.ShaderChunk[ "bsdfs" ],
 			THREE.ShaderChunk[ "lights_pars" ],
-			THREE.ShaderChunk[ "lights_phong_pars_fragment" ], // use phong chunk for now
+			THREE.ShaderChunk[ "lights_physical_pars_fragment" ], // use phong chunk for now
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
 			THREE.ShaderChunk[ "normalmap_pars_fragment" ],
@@ -532,11 +551,10 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	vec3 outgoingLight = vec3( 0.0 );",
 			"	vec4 diffuseColor = vec4( diffuse, opacity );",
-			"	vec3 totalAmbientLight = ambientLightColor;",
+			"	ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );",
+			"	ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );",
 			"	vec3 totalEmissiveLight = emissive;",
-			"	vec3 shadowMask = vec3( 1.0 );",
 
 				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 				THREE.ShaderChunk[ "map_fragment" ],
@@ -548,20 +566,23 @@ THREE.ShaderLib = {
 				//THREE.ShaderChunk[ "reflectivitymap_fragment" ],
 				THREE.ShaderChunk[ "metalnessmap_fragment" ],
 				THREE.ShaderChunk[ "normal_phong_fragment" ], // use phong chunk for now
-				THREE.ShaderChunk[ "lightmap_fragment" ],
-				THREE.ShaderChunk[ "hemilight_fragment" ],
-				THREE.ShaderChunk[ "aomap_fragment" ],
 				THREE.ShaderChunk[ "emissivemap_fragment" ],
 
+				// accumulation
 				THREE.ShaderChunk[ "lights_physical_fragment" ],
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
+				THREE.ShaderChunk[ "lights_template" ],		
+				THREE.ShaderChunk[ "lightmap_fragment" ],
+				THREE.ShaderChunk[ "envmap_physical_fragment" ],
 
-				"totalDiffuseLight *= shadowMask;",
-				"totalSpecularLight *= shadowMask;",
+				// modulation
+				THREE.ShaderChunk[ "aomap_fragment" ],
 
-				"outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) + totalSpecularLight + totalEmissiveLight;",
+				"vec3 shadowMask = vec3( 1.0 );",
+				THREE.ShaderChunk[ "shadowmap_fragment" ],
+				"directReflectedLight.diffuse *= shadowMask;",
+				"directReflectedLight.specular *= shadowMask;",
 
-				THREE.ShaderChunk[ "envmap_physical_fragment" ],
+				"vec3 outgoingLight = directReflectedLight.diffuse + indirectReflectedLight.diffuse + directReflectedLight.specular + indirectReflectedLight.specular + totalEmissiveLight;",
 
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 

+ 28 - 19
src/renderers/shaders/UniformsLib.js

@@ -95,25 +95,34 @@ THREE.UniformsLib = {
 
 		"ambientLightColor" : { type: "fv", value: [] },
 
-		"directionalLightDirection" : { type: "fv", value: [] },
-		"directionalLightColor" : { type: "fv", value: [] },
-
-		"hemisphereLightDirection" : { type: "fv", value: [] },
-		"hemisphereLightSkyColor" : { type: "fv", value: [] },
-		"hemisphereLightGroundColor" : { type: "fv", value: [] },
-
-		"pointLightColor" : { type: "fv", value: [] },
-		"pointLightPosition" : { type: "fv", value: [] },
-		"pointLightDistance" : { type: "fv1", value: [] },
-		"pointLightDecay" : { type: "fv1", value: [] },
-
-		"spotLightColor" : { type: "fv", value: [] },
-		"spotLightPosition" : { type: "fv", value: [] },
-		"spotLightDirection" : { type: "fv", value: [] },
-		"spotLightDistance" : { type: "fv1", value: [] },
-		"spotLightAngleCos" : { type: "fv1", value: [] },
-		"spotLightExponent" : { type: "fv1", value: [] },
-		"spotLightDecay" : { type: "fv1", value: [] }
+		"directionalLights" : { type: "sa", value: [], properties: {
+			"direction": { type: "v3" },
+			"color": { type: "c" }
+		} },
+
+		"hemisphereLights" : { type: "sa", value: [], properties: {
+			"direction": { type: "v3" },
+			"skyColor": { type: "c" },
+			"groundColor": { type: "c" }
+		} },
+
+		"pointLights" : { type: "sa", value: [], properties: {
+			"color": { type: "c" },
+			"position": { type: "v3" },
+			"decay": { type: "f" },
+			"distance": { type: "f" }
+		} },
+
+		"spotLights" : { type: "sa", value: [], properties: {
+			"color": { type: "c" },
+			"position": { type: "v3" },
+			"direction": { type: "v3" },
+			"distance": { type: "f" },
+			"angleCos": { type: "f" },
+			"exponent": { type: "f" },
+			"decay": { type: "f" }
+		} }
+
 
 	},
 

+ 48 - 5
src/renderers/webgl/WebGLProgram.js

@@ -1,6 +1,11 @@
 THREE.WebGLProgram = ( function () {
 
 	var programIdCount = 0;
+	
+	// TODO: Combine the regex
+	var structRe = /^([\w\d_]+)\.([\w\d_]+)$/; 
+	var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/; 
+	var arrayRe = /^([\w\d_]+)\[0\]$/; 
 
 	function generateDefines( defines ) {
 
@@ -25,20 +30,58 @@ THREE.WebGLProgram = ( function () {
 		var uniforms = {};
 
 		var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
-
+	
 		for ( var i = 0; i < n; i ++ ) {
 
 			var info = gl.getActiveUniform( program, i );
 			var name = info.name;
 			var location = gl.getUniformLocation( program, name );
 
-			// console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name);
+			//console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name);
+
+			var matches = structRe.exec(name);
+			if( matches ) {
+
+				var structName = matches[1];
+				var structProperty = matches[2];
+
+				var uniformsStruct = uniforms[ structName ];
+				if( ! uniformsStruct ) {
+					uniformsStruct = uniforms[ structName ] = {};
+				}
+				uniformsStruct[ structProperty ] = location;
+
+				continue;
+			}
+
+			matches = arrayStructRe.exec(name);
+			if( matches ) {
+
+				var arrayName = matches[1];
+				var arrayIndex = matches[2];
+				var arrayProperty = matches[3];
+
+				var uniformsArray = uniforms[ arrayName ];
+				if( ! uniformsArray ) {
+					uniformsArray = uniforms[ arrayName ] = [];
+				}
+				var uniformsArrayIndex = uniformsArray[ arrayIndex ];
+				if( ! uniformsArrayIndex ) {
+					uniformsArrayIndex = uniformsArray[ arrayIndex ] = {};
+				}
+				uniformsArrayIndex[ arrayProperty ] = location;
+
+				continue;
+			}
+
+			matches = arrayRe.exec(name)
+			if( matches ) {
 
-			var suffixPos = name.lastIndexOf( '[0]' );
-			if ( suffixPos !== - 1 && suffixPos === name.length - 3 ) {
+				var arrayName = matches[1];
 
-				uniforms[ name.substr( 0, suffixPos ) ] = location;
+				uniforms[ arrayName ] = location;
 
+				continue;
 			}
 
 			uniforms[ name ] = location;

+ 4 - 4
utils/build/includes/common.json

@@ -117,6 +117,7 @@
 	"src/renderers/shaders/ShaderChunk/aomap_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/begin_vertex.glsl",
 	"src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl",
+	"src/renderers/shaders/ShaderChunk/bsdfs.glsl",
 	"src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/color_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl",
@@ -131,20 +132,19 @@
 	"src/renderers/shaders/ShaderChunk/envmap_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl",
-	"src/renderers/shaders/ShaderChunk/envmap_physical_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/envmap_vertex.glsl",
 	"src/renderers/shaders/ShaderChunk/fog_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl",
-	"src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl",
-	"src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl",
-	"src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_pars.glsl",
+	"src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_phong_pars_vertex.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_phong_vertex.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl",
+	"src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl",
+	"src/renderers/shaders/ShaderChunk/lights_template.glsl",
 	"src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl",