浏览代码

refactor shaders to use diffuseColor and outgoingLight instead of gl_FragColor.

Ben Houston 10 年之前
父节点
当前提交
cc7634efa2

+ 15 - 32
examples/js/ShaderSkin.js

@@ -159,12 +159,13 @@ THREE.ShaderSkin = {
 
 			"void main() {",
 
-				"gl_FragColor = vec4( vec3( 1.0 ), opacity );",
+			"   vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );",	// outgoing light does not have an alpha, the surface does
+			"	vec4 diffuseColor = vec4( diffuse, opacity );",
 
 				"vec4 colDiffuse = texture2D( tDiffuse, vUv );",
 				"colDiffuse.rgb *= colDiffuse.rgb;",
 
-				"gl_FragColor = gl_FragColor * colDiffuse;",
+				"diffuseColor = diffuseColor * colDiffuse;",
 
 				"vec3 normal = normalize( vNormal );",
 				"vec3 viewPosition = normalize( vViewPosition );",
@@ -190,12 +191,11 @@ THREE.ShaderSkin = {
 
 				// point lights
 
-				"vec3 specularTotal = vec3( 0.0 );",
+				"vec3 totalSpecularLight = vec3( 0.0 );",
+				"vec3 totalDiffuseLight = vec3( 0.0 );",
 
 				"#if MAX_POINT_LIGHTS > 0",
 
-					"vec3 pointTotal = vec3( 0.0 );",
-
 					"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
 
 						"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
@@ -215,8 +215,8 @@ THREE.ShaderSkin = {
 
 						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
 
-						"pointTotal    += lDistance * diffuse * pointLightColor[ i ] * pointDiffuseWeight;",
-						"specularTotal += lDistance * specular * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
+						"totalDiffuseLight    += lDistance * pointLightColor[ i ] * pointDiffuseWeight;",
+						"totalSpecularLight += lDistance * specular * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
 
 					"}",
 
@@ -226,8 +226,6 @@ THREE.ShaderSkin = {
 
 				"#if MAX_DIR_LIGHTS > 0",
 
-					"vec3 dirTotal = vec3( 0.0 );",
-
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
 						"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
@@ -240,8 +238,8 @@ THREE.ShaderSkin = {
 
 						"float dirSpecularWeight =  KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
 
-						"dirTotal 	   += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;",
-						"specularTotal += specular * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;",
+						"totalDiffuseLight 	   += directionalLightColor[ i ] * dirDiffuseWeight;",
+						"totalSpecularLight += specular * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;",
 
 					"}",
 
@@ -251,8 +249,6 @@ THREE.ShaderSkin = {
 
 				"#if MAX_HEMI_LIGHTS > 0",
 
-					"vec3 hemiTotal = vec3( 0.0 );",
-
 					"for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
 
 						"vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );",
@@ -261,7 +257,7 @@ THREE.ShaderSkin = {
 						"float dotProduct = dot( normal, lVector );",
 						"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
 
-						"hemiTotal += diffuse * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+						"totalDiffuseLight += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
 
 						// specular (sky light)
 
@@ -273,34 +269,21 @@ THREE.ShaderSkin = {
 						"vec3 lVectorGround = -lVector;",
 						"hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewPosition, uRoughness, uSpecularBrightness );",
 
-						"specularTotal += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;",
+						"totalSpecularLight += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;",
 
 					"}",
 
 				"#endif",
 
-				// all lights contribution summation
-
-				"vec3 totalLight = vec3( 0.0 );",
-
-				"#if MAX_DIR_LIGHTS > 0",
-					"totalLight += dirTotal;",
-				"#endif",
-
-				"#if MAX_POINT_LIGHTS > 0",
-					"totalLight += pointTotal;",
-				"#endif",
-
-				"#if MAX_HEMI_LIGHTS > 0",
-					"totalLight += hemiTotal;",
-				"#endif",
-
-				"gl_FragColor.xyz = gl_FragColor.xyz * ( totalLight + ambientLightColor * ambient ) + specularTotal;",
+				"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight;",
 
 				THREE.ShaderChunk[ "shadowmap_fragment" ],
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 				THREE.ShaderChunk[ "fog_fragment" ],
 
+			"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+
+
 			"}"
 
 		].join("\n"),

+ 18 - 40
examples/js/ShaderTerrain.js

@@ -118,7 +118,8 @@ THREE.ShaderTerrain = {
 
 			"void main() {",
 
-				"gl_FragColor = vec4( vec3( 1.0 ), opacity );",
+			"   vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );",	// outgoing light does not have an alpha, the surface does
+			"	vec4 diffuseColor = vec4( diffuse, opacity );",
 
 				"vec3 specularTex = vec3( 1.0 );",
 
@@ -141,15 +142,15 @@ THREE.ShaderTerrain = {
 
 					"#endif",
 
-					"gl_FragColor = gl_FragColor * mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );",
+					"diffuseColor *= mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );",
 
 				" } else if( enableDiffuse1 ) {",
 
-					"gl_FragColor = gl_FragColor * texture2D( tDiffuse1, uvOverlay );",
+					"diffuseColor *= texture2D( tDiffuse1, uvOverlay );",
 
 				"} else if( enableDiffuse2 ) {",
 
-					"gl_FragColor = gl_FragColor * texture2D( tDiffuse2, uvOverlay );",
+					"diffuseColor *= texture2D( tDiffuse2, uvOverlay );",
 
 				"}",
 
@@ -162,13 +163,13 @@ THREE.ShaderTerrain = {
 				"vec3 normal = normalize( finalNormal );",
 				"vec3 viewPosition = normalize( vViewPosition );",
 
+				"vec3 totalDiffuseLight = vec3( 0.0 );",
+				"vec3 totalSpecularLight = vec3( 0.0 );",
+
 				// point lights
 
 				"#if MAX_POINT_LIGHTS > 0",
 
-					"vec3 pointDiffuse = vec3( 0.0 );",
-					"vec3 pointSpecular = vec3( 0.0 );",
-
 					"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
 
 						"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
@@ -188,8 +189,8 @@ THREE.ShaderTerrain = {
 
 						"float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
 
-						"pointDiffuse += pointDistance * pointLightColor[ i ] * diffuse * pointDiffuseWeight;",
-						"pointSpecular += pointDistance * pointLightColor[ i ] * specular * pointSpecularWeight * pointDiffuseWeight;",
+						"totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
+						"totalSpecularLight += pointDistance * pointLightColor[ i ] * specular * pointSpecularWeight * pointDiffuseWeight;",
 
 					"}",
 
@@ -214,8 +215,8 @@ THREE.ShaderTerrain = {
 
 						"float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );",
 
-						"dirDiffuse += directionalLightColor[ i ] * diffuse * dirDiffuseWeight;",
-						"dirSpecular += directionalLightColor[ i ] * specular * dirSpecularWeight * dirDiffuseWeight;",
+						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
+						"totalSpecularLight += directionalLightColor[ i ] * specular * dirSpecularWeight * dirDiffuseWeight;",
 
 					"}",
 
@@ -238,7 +239,7 @@ THREE.ShaderTerrain = {
 						"float dotProduct = dot( normal, lVector );",
 						"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
 
-						"hemiDiffuse += diffuse * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+						"totalDiffuseLight += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
 
 						// specular (sky light)
 
@@ -256,45 +257,22 @@ THREE.ShaderTerrain = {
 						"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
 						"hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",
 
-						"hemiSpecular += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;",
+						"totalSpecularLight += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;",
 
 					"}",
 
 				"#endif",
 
-				// all lights contribution summation
-
-				"vec3 totalDiffuse = vec3( 0.0 );",
-				"vec3 totalSpecular = vec3( 0.0 );",
-
-				"#if MAX_DIR_LIGHTS > 0",
-
-					"totalDiffuse += dirDiffuse;",
-					"totalSpecular += dirSpecular;",
-
-				"#endif",
-
-				"#if MAX_HEMI_LIGHTS > 0",
-
-					"totalDiffuse += hemiDiffuse;",
-					"totalSpecular += hemiSpecular;",
-
-				"#endif",
-
-				"#if MAX_POINT_LIGHTS > 0",
-
-					"totalDiffuse += pointDiffuse;",
-					"totalSpecular += pointSpecular;",
-
-				"#endif",
-
 				//"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient) + totalSpecular;",
-				"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient + totalSpecular );",
+				"outgoingLight.rgb += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient + totalSpecularLight );",
 
 				THREE.ShaderChunk[ "shadowmap_fragment" ],
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 				THREE.ShaderChunk[ "fog_fragment" ],
 
+			"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+
+
 			"}"
 
 		].join("\n"),

+ 23 - 61
examples/js/shaders/NormalDisplacementShader.js

@@ -135,7 +135,8 @@ THREE.NormalDisplacementShader = {
 		"void main() {",
 			THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 
-		"	gl_FragColor = vec4( vec3( 1.0 ), opacity );",
+		"   vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );",	// outgoing light does not have an alpha, the surface does
+		"	vec4 diffuseColor = vec4( diffuse, opacity );",
 
 		"	vec3 specularTex = vec3( 1.0 );",
 
@@ -150,11 +151,11 @@ THREE.NormalDisplacementShader = {
 		"			vec4 texelColor = texture2D( tDiffuse, vUv );",
 		"			texelColor.xyz *= texelColor.xyz;",
 
-		"			gl_FragColor = gl_FragColor * texelColor;",
+		"			diffuseColor *= texelColor;",
 
 		"		#else",
 
-		"			gl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );",
+		"			diffuseColor *= texture2D( tDiffuse, vUv );",
 
 		"		#endif",
 
@@ -167,11 +168,11 @@ THREE.NormalDisplacementShader = {
 		"			vec4 aoColor = texture2D( tAO, vUv );",
 		"			aoColor.xyz *= aoColor.xyz;",
 
-		"			gl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;",
+		"			diffuseColor.rgb *= aoColor.xyz;",
 
 		"		#else",
 
-		"			gl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;",
+		"			diffuseColor.rgb *= texture2D( tAO, vUv ).xyz;",
 
 		"		#endif",
 
@@ -194,13 +195,13 @@ THREE.NormalDisplacementShader = {
 		"	vec3 normal = normalize( finalNormal );",
 		"	vec3 viewPosition = normalize( vViewPosition );",
 
+		"	vec3 totalDiffuseLight = vec3( 0.0 );",
+		"	vec3 totalSpecularLight = vec3( 0.0 );",
+
 			// point lights
 
 		"	#if MAX_POINT_LIGHTS > 0",
 
-		"		vec3 pointDiffuse = vec3( 0.0 );",
-		"		vec3 pointSpecular = vec3( 0.0 );",
-
 		"		for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
 
 		"			vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
@@ -227,7 +228,7 @@ THREE.NormalDisplacementShader = {
 
 		"			#endif",
 
-		"			pointDiffuse += pointDistance * pointLightColor[ i ] * diffuse * pointDiffuseWeight;",
+		"			totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
 
 					// specular
 
@@ -238,7 +239,7 @@ THREE.NormalDisplacementShader = {
 		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 		"			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( pointVector, pointHalfVector ), 0.0 ), 5.0 );",
-		"			pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;",
+		"			totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;",
 
 		"		}",
 
@@ -248,9 +249,6 @@ THREE.NormalDisplacementShader = {
 
 		"	#if MAX_SPOT_LIGHTS > 0",
 
-		"		vec3 spotDiffuse = vec3( 0.0 );",
-		"		vec3 spotSpecular = vec3( 0.0 );",
-
 		"		for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
 
 		"			vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
@@ -283,7 +281,7 @@ THREE.NormalDisplacementShader = {
 
 		"				#endif",
 
-		"				spotDiffuse += spotDistance * spotLightColor[ i ] * diffuse * spotDiffuseWeight * spotEffect;",
+		"				totalDiffuseLight += spotDistance * spotLightColor[ i ] * spotDiffuseWeight * spotEffect;",
 
 						// specular
 
@@ -294,7 +292,7 @@ THREE.NormalDisplacementShader = {
 		"				float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 		"				vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( spotVector, spotHalfVector ), 0.0 ), 5.0 );",
-		"				spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;",
+		"				totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;",
 
 		"			}",
 
@@ -306,9 +304,6 @@ THREE.NormalDisplacementShader = {
 
 		"	#if MAX_DIR_LIGHTS > 0",
 
-		"		vec3 dirDiffuse = vec3( 0.0 );",
-		"		vec3 dirSpecular = vec3( 0.0 );",
-
 		"		for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
 		"			vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
@@ -329,7 +324,7 @@ THREE.NormalDisplacementShader = {
 
 		"			#endif",
 
-		"			dirDiffuse += directionalLightColor[ i ] * diffuse * dirDiffuseWeight;",
+		"			totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
 
 					// specular
 
@@ -340,7 +335,7 @@ THREE.NormalDisplacementShader = {
 		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
 
 		"			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );",
-		"			dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
+		"			totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
 
 		"		}",
 
@@ -350,9 +345,6 @@ THREE.NormalDisplacementShader = {
 
 		"	#if MAX_HEMI_LIGHTS > 0",
 
-		"		vec3 hemiDiffuse = vec3( 0.0 );",
-		"		vec3 hemiSpecular = vec3( 0.0 );" ,
-
 		"		for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
 
 		"			vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );",
@@ -365,7 +357,7 @@ THREE.NormalDisplacementShader = {
 
 		"			vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
 
-		"			hemiDiffuse += diffuse * hemiColor;",
+		"			totalDiffuseLight += hemiColor;",
 
 					// specular (sky light)
 
@@ -388,52 +380,19 @@ THREE.NormalDisplacementShader = {
 
 		"			vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );",
 		"			vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );",
-		"			hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",
+		"			totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",
 
 		"		}",
 
-		"	#endif",
-
-			// all lights contribution summation
-
-		"	vec3 totalDiffuse = vec3( 0.0 );",
-		"	vec3 totalSpecular = vec3( 0.0 );",
-
-		"	#if MAX_DIR_LIGHTS > 0",
-
-		"		totalDiffuse += dirDiffuse;",
-		"		totalSpecular += dirSpecular;",
-
-		"	#endif",
-
-		"	#if MAX_HEMI_LIGHTS > 0",
-
-		"		totalDiffuse += hemiDiffuse;",
-		"		totalSpecular += hemiSpecular;",
-
-		"	#endif",
-
-		"	#if MAX_POINT_LIGHTS > 0",
-
-		"		totalDiffuse += pointDiffuse;",
-		"		totalSpecular += pointSpecular;",
-
-		"	#endif",
-
-		"	#if MAX_SPOT_LIGHTS > 0",
-
-		"		totalDiffuse += spotDiffuse;",
-		"		totalSpecular += spotSpecular;",
-
 		"	#endif",
 
 		"	#ifdef METAL",
 
-		"		gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient + totalSpecular );",
+		"		outgoingLight.xyz += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient + totalSpecularLight );",
 
 		"	#else",
 
-		"		gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient ) + totalSpecular;",
+		"		outgoingLight.xyz += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight;",
 
 		"	#endif",
 
@@ -459,7 +418,7 @@ THREE.NormalDisplacementShader = {
 
 		"		#endif",
 
-		"		gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * reflectivity );",
+		"		outgoingLight.xyz = mix( outgoingLight.xyz, cubeColor.xyz, specularTex.r * reflectivity );",
 
 		"	}",
 
@@ -467,6 +426,9 @@ THREE.NormalDisplacementShader = {
 			THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 			THREE.ShaderChunk[ "fog_fragment" ],
 
+		"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+
+
 		"}"
 
 	].join("\n"),

+ 4 - 4
examples/webgl_materials2.html

@@ -69,10 +69,10 @@
 
 				shininess = 15;
 
-				materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0xffaa00, shininess: shininess, metal: true, shading: shading } ) );
-				materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0xaaff00, shininess: shininess, metal: true, shading: shading } ) );
-				materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0x00ffaa, shininess: shininess, metal: true, shading: shading } ) );
-				materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x000000, ambient: 0x000000, specular: 0x00aaff, shininess: shininess, metal: true, shading: shading } ) );
+				materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0xffaa00, shininess: shininess, metal: true, shading: shading } ) );
+				materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0xaaff00, shininess: shininess, metal: true, shading: shading } ) );
+				materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0x00ffaa, shininess: shininess, metal: true, shading: shading } ) );
+				materials.push( new THREE.MeshPhongMaterial( { map: imgTexture2, bumpMap: imgTexture2, bumpScale: bumpScale, color: 0x666666, ambient: 0x000000, specular: 0x00aaff, shininess: shininess, metal: true, shading: shading } ) );
 
 				// Spheres geometry
 

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

@@ -1,5 +1,5 @@
 #ifdef USE_ALPHAMAP
 
-	gl_FragColor.a *= texture2D( alphaMap, vUv ).g;
+	diffuseColor.a *= texture2D( alphaMap, vUv ).g;
 
 #endif

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

@@ -1,5 +1,5 @@
 #ifdef ALPHATEST
 
-	if ( gl_FragColor.a < ALPHATEST ) discard;
+	if ( diffuseColor.a < ALPHATEST ) discard;
 
 #endif

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

@@ -1,5 +1,5 @@
 #ifdef USE_COLOR
 
-	gl_FragColor = gl_FragColor * vec4( vColor, 1.0 );
+	diffuseColor.rgb *= vColor;
 
 #endif

+ 3 - 3
src/renderers/shaders/ShaderChunk/envmap_fragment.glsl

@@ -53,15 +53,15 @@
 
 	#ifdef ENVMAP_BLENDING_MULTIPLY
 
-		gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );
+		outgoingLight.xyz = mix( outgoingLight.xyz, outgoingLight.xyz * envColor.xyz, specularStrength * reflectivity );
 
 	#elif defined( ENVMAP_BLENDING_MIX )
 
-		gl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );
+		outgoingLight.xyz = mix( outgoingLight.xyz, envColor.xyz, specularStrength * reflectivity );
 
 	#elif defined( ENVMAP_BLENDING_ADD )
 
-		gl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;
+		outgoingLight.xyz += envColor.xyz * specularStrength * reflectivity;
 
 	#endif
 

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

@@ -22,6 +22,6 @@
 
 	#endif
 	
-	gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+	outgoingLight = mix( outgoingLight, fogColor, fogFactor );
 
 #endif

+ 1 - 9
src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl

@@ -1,13 +1,5 @@
 #ifdef USE_LIGHTMAP
 
-	#if defined( PHONG )
-
-		gl_FragColor += diffuseColor * texture2D( lightMap, vUv2 );
-
-	#else 
-		
-		gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );
-
-	#endif
+	outgoingLight += diffuseColor.xyz * texture2D( lightMap, vUv2 ).xyz;
 
 #endif

+ 13 - 53
src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl

@@ -17,10 +17,10 @@ vec3 viewPosition = normalize( vViewPosition );
 
 #endif
 
-#if MAX_POINT_LIGHTS > 0
+vec3 totalDiffuseLight = vec3( 0.0 );
+vec3 totalSpecularLight = vec3( 0.0 );
 
-	vec3 pointDiffuse = vec3( 0.0 );
-	vec3 pointSpecular = vec3( 0.0 );
+#if MAX_POINT_LIGHTS > 0
 
 	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
 
@@ -50,7 +50,7 @@ vec3 viewPosition = normalize( vViewPosition );
 
 		#endif
 
-		pointDiffuse += pointLightColor[ i ] * pointDiffuseWeight * lDistance;
+		totalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * lDistance;
 
 				// specular
 
@@ -61,7 +61,7 @@ vec3 viewPosition = normalize( vViewPosition );
 		float specularNormalization = ( shininess + 2.0 ) / 8.0;
 
 		vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 );
-		pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;
+		totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;
 
 	}
 
@@ -69,9 +69,6 @@ vec3 viewPosition = normalize( vViewPosition );
 
 #if MAX_SPOT_LIGHTS > 0
 
-	vec3 spotDiffuse = vec3( 0.0 );
-	vec3 spotSpecular = vec3( 0.0 );
-
 	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {
 
 		vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );
@@ -106,7 +103,7 @@ vec3 viewPosition = normalize( vViewPosition );
 
 			#endif
 
-			spotDiffuse += spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;
+			totalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;
 
 			// specular
 
@@ -117,7 +114,7 @@ vec3 viewPosition = normalize( vViewPosition );
 			float specularNormalization = ( shininess + 2.0 ) / 8.0;
 
 			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 );
-			spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;
+			totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;
 
 		}
 
@@ -127,9 +124,6 @@ vec3 viewPosition = normalize( vViewPosition );
 
 #if MAX_DIR_LIGHTS > 0
 
-	vec3 dirDiffuse = vec3( 0.0 );
-	vec3 dirSpecular = vec3( 0.0 );
-
 	for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
 
 		vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );
@@ -152,7 +146,7 @@ vec3 viewPosition = normalize( vViewPosition );
 
 		#endif
 
-		dirDiffuse += directionalLightColor[ i ] * dirDiffuseWeight;
+		totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;
 
 		// specular
 
@@ -184,7 +178,7 @@ vec3 viewPosition = normalize( vViewPosition );
 		// 		dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;
 
 		vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );
-		dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;
+		totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;
 
 
 	}
@@ -193,9 +187,6 @@ vec3 viewPosition = normalize( vViewPosition );
 
 #if MAX_HEMI_LIGHTS > 0
 
-	vec3 hemiDiffuse = vec3( 0.0 );
-	vec3 hemiSpecular = vec3( 0.0 );
-
 	for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {
 
 		vec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );
@@ -208,7 +199,7 @@ vec3 viewPosition = normalize( vViewPosition );
 
 		vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );
 
-		hemiDiffuse += hemiColor;
+		totalDiffuseLight += hemiColor;
 
 		// specular (sky light)
 
@@ -230,49 +221,18 @@ vec3 viewPosition = normalize( vViewPosition );
 
 		vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );
 		vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 );
-		hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );
+		totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );
 
 	}
 
 #endif
 
-vec3 totalDiffuse = vec3( 0.0 );
-vec3 totalSpecular = vec3( 0.0 );
-
-#if MAX_DIR_LIGHTS > 0
-
-	totalDiffuse += dirDiffuse;
-	totalSpecular += dirSpecular;
-
-#endif
-
-#if MAX_HEMI_LIGHTS > 0
-
-	totalDiffuse += hemiDiffuse;
-	totalSpecular += hemiSpecular;
-
-#endif
-
-#if MAX_POINT_LIGHTS > 0
-
-	totalDiffuse += pointDiffuse;
-	totalSpecular += pointSpecular;
-
-#endif
-
-#if MAX_SPOT_LIGHTS > 0
-
-	totalDiffuse += spotDiffuse;
-	totalSpecular += spotSpecular;
-
-#endif
-
 #ifdef METAL
 
-	gl_FragColor.xyz = diffuseColor * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );
+	outgoingLight += diffuseColor.rgb * ( emissive + totalDiffuseLight + ambientLightColor * ambient + totalSpecularLight );
 
 #else
 
-	gl_FragColor.xyz = diffuseColor * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;
+	outgoingLight += diffuseColor.rgb * ( emissive + totalDiffuseLight + ambientLightColor * ambient ) + totalSpecularLight;
 
 #endif

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

@@ -1,5 +1,5 @@
 #ifdef GAMMA_OUTPUT
 
-	gl_FragColor.xyz = sqrt( gl_FragColor.xyz );
+	outgoingLight.xyz = sqrt( outgoingLight.xyz );
 
 #endif

+ 2 - 8
src/renderers/shaders/ShaderChunk/map_fragment.glsl

@@ -4,16 +4,10 @@
 
 	#ifdef GAMMA_INPUT
 
-		texelColor.xyz *= texelColor.xyz;
+		texelColor.rgb *= texelColor.rgb;
 
 	#endif
 
-	gl_FragColor = gl_FragColor * texelColor;
-	
-	#if defined( PHONG )
-
-		diffuseColor *= texelColor.xyz;
-
-	#endif
+	diffuseColor.rgb *= texelColor.rgb;
 
 #endif

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

@@ -1,5 +1,5 @@
 #ifdef USE_MAP
 
-	gl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );
+	diffuseColor *= texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );
 
 #endif

+ 3 - 3
src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl

@@ -197,11 +197,11 @@
 
 			#ifdef SHADOWMAP_CASCADE
 
-				if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];
+				if ( inFrustum && inFrustumCount == 1 ) outgoingLight *= frustumColors[ i ];
 
 			#else
 
-				if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];
+				if ( inFrustum ) outgoingLight *= frustumColors[ i ];
 
 			#endif
 
@@ -215,6 +215,6 @@
 
 	#endif
 
-	gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;
+	outgoingLight = outgoingLight * shadowColor;
 
 #endif

+ 33 - 16
src/renderers/shaders/ShaderLib.js

@@ -1,4 +1,4 @@
-/**
+ /**
  * Webgl Shader Library for three.js
  *
  * @author alteredq / http://alteredqualia.com/
@@ -75,22 +75,28 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	gl_FragColor = vec4( diffuse, opacity );",
+			"   vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );",	// outgoing light does not have an alpha, the surface does
+			"	vec4 diffuseColor = vec4( diffuse, opacity );",
 
 				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 				THREE.ShaderChunk[ "map_fragment" ],
+				THREE.ShaderChunk[ "color_fragment" ],
 				THREE.ShaderChunk[ "alphamap_fragment" ],
 				THREE.ShaderChunk[ "alphatest_fragment" ],
 				THREE.ShaderChunk[ "specularmap_fragment" ],
-				THREE.ShaderChunk[ "lightmap_fragment" ],
-				THREE.ShaderChunk[ "color_fragment" ],
+
+			"	outgoingLight.rgb = diffuseColor.rgb;", // simple shader
+
+				THREE.ShaderChunk[ "lightmap_fragment" ],		// TODO: Light map on an otherwise unlit surface doesn't make sense.
 				THREE.ShaderChunk[ "envmap_fragment" ],
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
+				THREE.ShaderChunk[ "shadowmap_fragment" ],		// TODO: Shadows on an otherwise unlit surface doesn't make sense.
 
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 
 				THREE.ShaderChunk[ "fog_fragment" ],
 
+			"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+
 			"}"
 
 		].join("\n")
@@ -185,10 +191,12 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	gl_FragColor = vec4( vec3( 1.0 ), opacity );",
+			"   vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );",	// outgoing light does not have an alpha, the surface does
+			"	vec4 diffuseColor = vec4( 1.0, 1.0, 1.0, opacity );",
 	
 				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 				THREE.ShaderChunk[ "map_fragment" ],
+				THREE.ShaderChunk[ "color_fragment" ],
 				THREE.ShaderChunk[ "alphamap_fragment" ],
 				THREE.ShaderChunk[ "alphatest_fragment" ],
 				THREE.ShaderChunk[ "specularmap_fragment" ],
@@ -199,18 +207,17 @@ THREE.ShaderLib = {
 					//"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;",
 
 			"		if ( gl_FrontFacing )",
-			"			gl_FragColor.xyz *= vLightFront;",
+			"			outgoingLight += diffuseColor.rgb * vLightFront;",
 			"		else",
-			"			gl_FragColor.xyz *= vLightBack;",
+			"			outgoingLight += diffuseColor.rgb * vLightBack;",
 
 			"	#else",
 
-			"		gl_FragColor.xyz *= vLightFront;",
+			"		outgoingLight += diffuseColor.rgb * vLightFront;",
 
 			"	#endif",
 
 				THREE.ShaderChunk[ "lightmap_fragment" ],
-				THREE.ShaderChunk[ "color_fragment" ],
 				THREE.ShaderChunk[ "envmap_fragment" ],
 				THREE.ShaderChunk[ "shadowmap_fragment" ],
 
@@ -218,6 +225,8 @@ THREE.ShaderLib = {
 
 				THREE.ShaderChunk[ "fog_fragment" ],
 
+			"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+
 			"}"
 
 		].join("\n")
@@ -318,11 +327,12 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	gl_FragColor = vec4( vec3( 1.0 ), opacity );",
-			"   vec3 diffuseColor = diffuse;",
+			"   vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );",	// outgoing light does not have an alpha, the surface does
+			"	vec4 diffuseColor = vec4( diffuse, opacity );",
 
 				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 				THREE.ShaderChunk[ "map_fragment" ],
+				THREE.ShaderChunk[ "color_fragment" ],
 				THREE.ShaderChunk[ "alphamap_fragment" ],
 				THREE.ShaderChunk[ "alphatest_fragment" ],
 				THREE.ShaderChunk[ "specularmap_fragment" ],
@@ -330,7 +340,6 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "lights_phong_fragment" ],
 
 				THREE.ShaderChunk[ "lightmap_fragment" ],
-				THREE.ShaderChunk[ "color_fragment" ],
 				THREE.ShaderChunk[ "envmap_fragment" ],
 				THREE.ShaderChunk[ "shadowmap_fragment" ],
 
@@ -338,6 +347,8 @@ THREE.ShaderLib = {
 
 				THREE.ShaderChunk[ "fog_fragment" ],
 
+			"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+
 			"}"
 
 		].join("\n")
@@ -397,7 +408,8 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	gl_FragColor = vec4( psColor, opacity );",
+			"   vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );",	// outgoing light does not have an alpha, the surface does
+			"	vec4 diffuseColor = vec4( psColor, opacity );",
 
 				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 				THREE.ShaderChunk[ "map_particle_fragment" ],
@@ -406,6 +418,8 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "shadowmap_fragment" ],
 				THREE.ShaderChunk[ "fog_fragment" ],
 
+			"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+
 			"}"
 
 		].join("\n")
@@ -474,12 +488,15 @@ THREE.ShaderLib = {
 
 			"	}",
 
-			"	gl_FragColor = vec4( diffuse, opacity );",
+			"   vec3 outgoingLight = vec3( 0.0, 0.0, 0.0 );",	// outgoing light does not have an alpha, the surface does
+			"	vec4 diffuseColor = vec4( diffuse, opacity );",
 
 				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 				THREE.ShaderChunk[ "color_fragment" ],
 				THREE.ShaderChunk[ "fog_fragment" ],
 
+			"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+
 			"}"
 
 		].join("\n")
@@ -534,7 +551,7 @@ THREE.ShaderLib = {
 			"	#endif",
 
 			"	float color = 1.0 - smoothstep( mNear, mFar, depth );",
-			"	gl_FragColor = vec4( vec3( color ), opacity );",
+			"	gl_FragColor = vec4( vec3( color ), opacity );",   // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
 
 			"}"