浏览代码

Merge branch 'phong_diffuseColor' of https://github.com/bhouston/three.js into dev

Conflicts:
	examples/js/shaders/NormalDisplacementShader.js
Mr.doob 10 年之前
父节点
当前提交
e83bf8a30d

+ 36 - 66
examples/js/ShaderSkin.js

@@ -159,12 +159,13 @@ THREE.ShaderSkin = {
 
 			"void main() {",
 
-				"gl_FragColor = vec4( vec3( 1.0 ), opacity );",
+				"vec3 outgoingLight = vec3( 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 );",
@@ -212,8 +212,8 @@ THREE.ShaderSkin = {
 
 						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
 
-						"pointTotal    += attenuation * diffuse * pointLightColor[ i ] * pointDiffuseWeight;",
-						"specularTotal += attenuation * specular * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
+						"totalDiffuseLight += attenuation * pointLightColor[ i ] * pointDiffuseWeight;",
+						"totalSpecularLight += attenuation * specular * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
 
 					"}",
 
@@ -223,8 +223,6 @@ THREE.ShaderSkin = {
 
 				"#if MAX_DIR_LIGHTS > 0",
 
-					"vec3 dirTotal = vec3( 0.0 );",
-
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
 						"vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );",
@@ -233,10 +231,10 @@ THREE.ShaderSkin = {
 						"float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );",
 						"vec3 dirDiffuseWeight = mix( vec3 ( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), uWrapRGB );",
 
-						"float dirSpecularWeight =  KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"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;",
 
 					"}",
 
@@ -246,8 +244,6 @@ THREE.ShaderSkin = {
 
 				"#if MAX_HEMI_LIGHTS > 0",
 
-					"vec3 hemiTotal = vec3( 0.0 );",
-
 					"for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
 
 						"vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );",
@@ -255,7 +251,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)
 
@@ -267,34 +263,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 * diffuse ) + specularTotal;",
+				"outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + 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"),
@@ -468,9 +451,9 @@ THREE.ShaderSkin = {
 
 			"void main() {",
 
-				"gl_FragColor = vec4( 1.0 );",
+				"vec3 outgoingLight = vec3( 0.0 );",	// outgoing light does not have an alpha, the surface does
+				"vec4 diffuseColor = vec4( diffuse, opacity );",
 
-				"vec4 mColor = vec4( diffuse, opacity );",
 				"vec4 mSpecular = vec4( specular, opacity );",
 
 				"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
@@ -480,7 +463,7 @@ THREE.ShaderSkin = {
 				"vec4 colDiffuse = texture2D( tDiffuse, vUv );",
 				"colDiffuse *= colDiffuse;",
 
-				"gl_FragColor = gl_FragColor * colDiffuse;",
+				"diffuseColor *= colDiffuse;",
 
 				"mat3 tsb = mat3( vTangent, vBinormal, vNormal );",
 				"vec3 finalNormal = tsb * normalTex;",
@@ -490,12 +473,11 @@ THREE.ShaderSkin = {
 
 				// point lights
 
-				"vec3 specularTotal = vec3( 0.0 );",
+				"vec3 totalDiffuseLight = vec3( 0.0 );",
+				"vec3 totalSpecularLight = vec3( 0.0 );",
 
 				"#if MAX_POINT_LIGHTS > 0",
 
-					"vec4 pointTotal = vec4( vec3( 0.0 ), 1.0 );",
-
 					"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
 
 						"vec3 pointVector = normalize( vPointLight[ i ].xyz );",
@@ -503,10 +485,10 @@ THREE.ShaderSkin = {
 
 						"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
 
-						"pointTotal  += pointDistance * vec4( pointLightColor[ i ], 1.0 ) * ( mColor * pointDiffuseWeight );",
+						"totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
 
 						"if ( passID == 1 )",
-							"specularTotal += pointDistance * mSpecular.xyz * pointLightColor[ i ] * KS_Skin_Specular( normal, pointVector, viewPosition, uRoughness, uSpecularBrightness );",
+							"totalSpecularLight += pointDistance * mSpecular.xyz * pointLightColor[ i ] * KS_Skin_Specular( normal, pointVector, viewPosition, uRoughness, uSpecularBrightness );",
 
 					"}",
 
@@ -516,40 +498,27 @@ THREE.ShaderSkin = {
 
 				"#if MAX_DIR_LIGHTS > 0",
 
-					"vec4 dirTotal = vec4( vec3( 0.0 ), 1.0 );",
-
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
 						"vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );",
 
 						"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
 
-						"dirTotal  += vec4( directionalLightColor[ i ], 1.0 ) * ( mColor * dirDiffuseWeight );",
+						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
 
 						"if ( passID == 1 )",
-							"specularTotal += mSpecular.xyz * directionalLightColor[ i ] * KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
+							"totalSpecularLight += mSpecular.xyz * directionalLightColor[ i ] * KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
 
 					"}",
 
 				"#endif",
 
-				// all lights contribution summation
 
-				"vec4 totalLight = vec4( vec3( 0.0 ), opacity );",
-
-				"#if MAX_DIR_LIGHTS > 0",
-					"totalLight += dirTotal;",
-				"#endif",
-
-				"#if MAX_POINT_LIGHTS > 0",
-					"totalLight += pointTotal;",
-				"#endif",
-
-				"gl_FragColor = gl_FragColor * totalLight;",
+				"outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalSpecularLight );",
 
 				"if ( passID == 0 ) {",
 
-					"gl_FragColor = vec4( sqrt( gl_FragColor.xyz ), gl_FragColor.w );",
+					"outgoingLight = sqrt( outgoingLight );",
 
 				"} else if ( passID == 1 ) {",
 
@@ -557,11 +526,11 @@ THREE.ShaderSkin = {
 
 					"#ifdef VERSION1",
 
-						"vec3 nonblurColor = sqrt( gl_FragColor.xyz );",
+						"vec3 nonblurColor = sqrt(outgoingLight );",
 
 					"#else",
 
-						"vec3 nonblurColor = gl_FragColor.xyz;",
+						"vec3 nonblurColor = outgoingLight;",
 
 					"#endif",
 
@@ -578,20 +547,19 @@ THREE.ShaderSkin = {
 					//"gl_FragColor = vec4( vec3( 0.25, 0.6, 0.8 ) * nonblurColor + vec3( 0.15, 0.25, 0.2 ) * blur1Color + vec3( 0.15, 0.15, 0.0 ) * blur2Color + vec3( 0.45, 0.0, 0.0 ) * blur3Color, gl_FragColor.w );",
 
 
-					"gl_FragColor = vec4( vec3( 0.22,  0.437, 0.635 ) * nonblurColor + ",
+					"outgoingLight = vec3( vec3( 0.22,  0.437, 0.635 ) * nonblurColor + ",
 										 "vec3( 0.101, 0.355, 0.365 ) * blur1Color + ",
 										 "vec3( 0.119, 0.208, 0.0 )   * blur2Color + ",
 										 "vec3( 0.114, 0.0,   0.0 )   * blur3Color + ",
-										 "vec3( 0.444, 0.0,   0.0 )   * blur4Color",
-										 ", gl_FragColor.w );",
+										 "vec3( 0.444, 0.0,   0.0 )   * blur4Color );",
 
-					"gl_FragColor.xyz *= pow( colDiffuse.xyz, vec3( 0.5 ) );",
+					"outgoingLight *= sqrt( colDiffuse.xyz );",
 
-					"gl_FragColor.xyz += ambientLightColor * diffuse * colDiffuse.xyz + specularTotal;",
+					"outgoingLight += ambientLightColor * diffuse * colDiffuse.xyz + totalSpecularLight;",
 
 					"#ifndef VERSION1",
 
-						"gl_FragColor.xyz = sqrt( gl_FragColor.xyz );",
+						"outgoingLight = sqrt( outgoingLight );",
 
 					"#endif",
 
@@ -599,6 +567,8 @@ THREE.ShaderSkin = {
 
 				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"),

+ 17 - 41
examples/js/ShaderTerrain.js

@@ -118,7 +118,8 @@ THREE.ShaderTerrain = {
 
 			"void main() {",
 
-				"gl_FragColor = vec4( vec3( 1.0 ), opacity );",
+				"vec3 outgoingLight = vec3( 0.0 );",	// outgoing light does not have an alpha, the surface does
+				"vec4 diffuseColor = vec4( diffuse, opacity );",
 
 				"vec3 specularTex = vec3( 1.0 );",
 
@@ -137,15 +138,15 @@ THREE.ShaderTerrain = {
 					"colDiffuse1.xyz = inputToLinear( colDiffuse1.xyz );",
 					"colDiffuse2.xyz = inputToLinear( colDiffuse2.xyz );",
 
-					"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 );",
 
 				"}",
 
@@ -158,13 +159,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 );",
@@ -181,8 +182,8 @@ THREE.ShaderTerrain = {
 
 						"float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
 
-						"pointDiffuse += attenuation * pointLightColor[ i ] * diffuse * pointDiffuseWeight;",
-						"pointSpecular += attenuation * pointLightColor[ i ] * specular * pointSpecularWeight * pointDiffuseWeight;",
+						"totalDiffuseLight += attenuation * pointLightColor[ i ] * pointDiffuseWeight;",
+						"totalSpecularLight += attenuation * pointLightColor[ i ] * specular * pointSpecularWeight * pointDiffuseWeight;",
 
 					"}",
 
@@ -205,8 +206,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;",
 
 					"}",
 
@@ -228,7 +229,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)
 
@@ -246,45 +247,20 @@ 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 * diffuse ) + totalSpecular;",
-				"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * diffuse + totalSpecular );",
+				"outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor + 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"),

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

@@ -134,7 +134,8 @@ THREE.NormalDisplacementShader = {
 		"void main() {",
 			THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 
-		"	gl_FragColor = vec4( vec3( 1.0 ), opacity );",
+		"	vec3 outgoingLight = vec3( 0.0 );",	// outgoing light does not have an alpha, the surface does
+		"	vec4 diffuseColor = vec4( diffuse, opacity );",
 
 		"	vec3 specularTex = vec3( 1.0 );",
 
@@ -149,11 +150,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",
 
@@ -166,11 +167,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",
 
@@ -193,13 +194,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 );",
@@ -226,7 +227,7 @@ THREE.NormalDisplacementShader = {
 
 		"			#endif",
 
-		"			pointDiffuse += pointDistance * pointLightColor[ i ] * diffuse * pointDiffuseWeight;",
+		"			totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
 
 					// specular
 
@@ -237,7 +238,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;",
 
 		"		}",
 
@@ -247,9 +248,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 );",
@@ -282,7 +280,7 @@ THREE.NormalDisplacementShader = {
 
 		"				#endif",
 
-		"				spotDiffuse += spotDistance * spotLightColor[ i ] * diffuse * spotDiffuseWeight * spotEffect;",
+		"				totalDiffuseLight += spotDistance * spotLightColor[ i ] * spotDiffuseWeight * spotEffect;",
 
 						// specular
 
@@ -293,7 +291,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;",
 
 		"			}",
 
@@ -305,9 +303,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 );",
@@ -328,7 +323,7 @@ THREE.NormalDisplacementShader = {
 
 		"			#endif",
 
-		"			dirDiffuse += directionalLightColor[ i ] * diffuse * dirDiffuseWeight;",
+		"			totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
 
 					// specular
 
@@ -339,7 +334,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;",
 
 		"		}",
 
@@ -349,9 +344,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 );",
@@ -364,7 +356,7 @@ THREE.NormalDisplacementShader = {
 
 		"			vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
 
-		"			hemiDiffuse += diffuse * hemiColor;",
+		"			totalDiffuseLight += hemiColor;",
 
 					// specular (sky light)
 
@@ -387,52 +379,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 * diffuse + totalSpecular );",
+		"		outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse + totalSpecularLight );",
 
 		"	#else",
 
-		"		gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;",
+		"		outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight;",
 
 		"	#endif",
 
@@ -458,7 +417,7 @@ THREE.NormalDisplacementShader = {
 
 		"		#endif",
 
-		"		gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * reflectivity );",
+		"		outgoingLight = mix( outgoingLight.xyz, cubeColor.xyz, specularTex.r * reflectivity );",
 
 		"	}",
 
@@ -466,6 +425,8 @@ 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"),

+ 1 - 1
examples/webgl_animation_skinning_morph.html

@@ -127,7 +127,7 @@
 
 				//
 
-				var light = new THREE.DirectionalLight( 0x497f13, 1 );
+				var light = new THREE.DirectionalLight( 0x493f13, 1 );
 				light.position.set( 0, -1, 0 );
 				scene.add( light );
 

+ 3 - 4
examples/webgl_materials_lightmap.html

@@ -100,14 +100,13 @@
 
 				// LIGHTS
 
-				var directionalLight = new THREE.DirectionalLight( 0xffffff, 1.475 );
+				var directionalLight = new THREE.DirectionalLight( 0x333333, 2 );
 				directionalLight.position.set( 100, 100, -100 );
 				scene.add( directionalLight );
 
 
-				var hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 1.25 );
-				hemiLight.color.setHSL( 0.6, 1, 0.75 );
-				hemiLight.groundColor.setHSL( 0.1, 0.8, 0.7 );
+				var hemiLight = new THREE.HemisphereLight( 0xaabbff, 0x040404, 1 );
+
 				hemiLight.position.y = 500;
 				scene.add( hemiLight );
 

+ 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

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

@@ -37,7 +37,7 @@
 		sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );
 		sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;
 		vec4 envColor = 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 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );
@@ -47,15 +47,15 @@
 
 	#ifdef ENVMAP_BLENDING_MULTIPLY
 
-		gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );
+		outgoingLight = mix( outgoingLight, outgoingLight. * envColor.xyz, specularStrength * reflectivity );
 
 	#elif defined( ENVMAP_BLENDING_MIX )
 
-		gl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );
+		outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );
 
 	#elif defined( ENVMAP_BLENDING_ADD )
 
-		gl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;
+		outgoingLight += envColor.xyz * specularStrength * reflectivity;
 
 	#endif
 

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

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

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

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

+ 17 - 57
src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl

@@ -28,10 +28,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 ++ ) {
 
@@ -42,7 +42,7 @@ vec3 viewPosition = normalize( vViewPosition );
 
 		lVector = normalize( lVector );
 
-				// diffuse
+		// diffuse
 
 		float dotProduct = dot( normal, lVector );
 
@@ -59,7 +59,7 @@ vec3 viewPosition = normalize( vViewPosition );
 
 		#endif
 
-		pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * attenuation;
+		totalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * attenuation;
 
 				// specular
 
@@ -70,7 +70,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 * attenuation * specularNormalization;
+		totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization;
 
 	}
 
@@ -78,9 +78,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 );
@@ -96,7 +93,7 @@ vec3 viewPosition = normalize( vViewPosition );
 
 			spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );
 
-					// diffuse
+			// diffuse
 
 			float dotProduct = dot( normal, lVector );
 
@@ -113,9 +110,9 @@ vec3 viewPosition = normalize( vViewPosition );
 
 			#endif
 
-			spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;
+			totalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect;
 
-					// specular
+			// specular
 
 			vec3 spotHalfVector = normalize( lVector + viewPosition );
 			float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );
@@ -124,7 +121,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 * attenuation * specularNormalization * spotEffect;
+			totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect;
 
 		}
 
@@ -134,14 +131,11 @@ 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 ++ ) {
 
 		vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );
 
-				// diffuse
+		// diffuse
 
 		float dotProduct = dot( normal, dirVector );
 
@@ -158,7 +152,7 @@ vec3 viewPosition = normalize( vViewPosition );
 
 		#endif
 
-		dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;
+		totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;
 
 		// specular
 
@@ -190,7 +184,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;
 
 
 	}
@@ -199,9 +193,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 ++ ) {
 
 		vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );
@@ -213,7 +204,7 @@ vec3 viewPosition = normalize( vViewPosition );
 
 		vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );
 
-		hemiDiffuse += diffuse * hemiColor;
+		totalDiffuseLight += hemiColor;
 
 		// specular (sky light)
 
@@ -235,49 +226,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 = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse + totalSpecular );
+	outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor * diffuse ) * specular + totalSpecularLight + emissive;
 
 #else
 
-	gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * diffuse ) + totalSpecular;
+	outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive;
 
 #endif

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

@@ -1,2 +1,2 @@
 
-	gl_FragColor.xyz = linearToOutput( gl_FragColor.xyz );
+	outgoingLight = linearToOutput( outgoingLight );

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

@@ -4,6 +4,6 @@
 
 	texelColor.xyz = inputToLinear( texelColor.xyz );
 
-	gl_FragColor = gl_FragColor * texelColor;
+	diffuseColor *= texelColor;
 
 #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 ) * offsetRepeat.zw + offsetRepeat.xy );
+	diffuseColor *= texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );
 
 #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
 
@@ -212,6 +212,6 @@
 	// NOTE: I am unsure if this is correct in linear space.  -bhouston, Dec 29, 2014
 	shadowColor = inputToLinear( shadowColor );
 
-	gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;
+	outgoingLight = outgoingLight * shadowColor;
 
 #endif

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

@@ -77,22 +77,28 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	gl_FragColor = vec4( diffuse, opacity );",
+			"	vec3 outgoingLight = vec3( 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 = 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")
@@ -188,10 +194,12 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	gl_FragColor = vec4( vec3( 1.0 ), opacity );",
+			"	vec3 outgoingLight = vec3( 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" ],
@@ -202,18 +210,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" ],
 
@@ -221,6 +228,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")
@@ -330,10 +339,12 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	gl_FragColor = vec4( vec3( 1.0 ), opacity );",
+			"	vec3 outgoingLight = vec3( 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" ],
@@ -341,7 +352,6 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "lights_phong_fragment" ],
 
 				THREE.ShaderChunk[ "lightmap_fragment" ],
-				THREE.ShaderChunk[ "color_fragment" ],
 				THREE.ShaderChunk[ "envmap_fragment" ],
 				THREE.ShaderChunk[ "shadowmap_fragment" ],
 
@@ -349,6 +359,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")
@@ -410,15 +422,21 @@ THREE.ShaderLib = {
 
 			"void main() {",
 
-			"	gl_FragColor = vec4( psColor, opacity );",
+			"	vec3 outgoingLight = vec3( 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" ],
-				THREE.ShaderChunk[ "alphatest_fragment" ],
 				THREE.ShaderChunk[ "color_fragment" ],
+				THREE.ShaderChunk[ "alphatest_fragment" ],
+
+			"	outgoingLight = diffuseColor.rgb;", // simple shader
+
 				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")
@@ -489,12 +507,15 @@ THREE.ShaderLib = {
 
 			"	}",
 
-			"	gl_FragColor = vec4( diffuse, opacity );",
+			"	vec3 outgoingLight = vec3( 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")
@@ -551,7 +572,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
 
 			"}"