Преглед на файлове

WebGLDeferredRenderer: trying to fix AreaLights.

The problem this tries to address is - how to incorporate surface normals into diffuse term area light calculations. The original approach completely ignored surface normals, which resulted in both light shining on backfaces and lit surfaces not showing any shading. This made prettier empty box with very soft look but anything inside the box had completely flat diffuse term.

Not yet fully solved. I tried myriad variants, all methods I could come up with had some problems. This one for example breaks down when the light emitter area intersects object triangle :S.

Also fixed handling of vertex colors for emissive term and tried a bit closer match with shininess strength between area lights and other light types, though this is tricky, seems it would require some non-linear mapping.
alteredq преди 12 години
родител
ревизия
4a976331d8
променени са 2 файла, в които са добавени 30 реда и са изтрити 12 реда
  1. 16 6
      examples/js/ShaderDeferred.js
  2. 14 6
      examples/webgl_lights_deferred_arealights.html

+ 16 - 6
examples/js/ShaderDeferred.js

@@ -292,7 +292,15 @@ THREE.ShaderDeferred = {
 
 				// emissive color
 
-				"gl_FragColor.w = vec3_to_float( compressionScale * emissive * diffuseMapColor );",
+				"#ifdef USE_COLOR",
+
+					"gl_FragColor.w = vec3_to_float( compressionScale * emissive * diffuseMapColor * vColor );",
+
+				"#else",
+
+					"gl_FragColor.w = vec3_to_float( compressionScale * emissive * diffuseMapColor );",
+
+				"#endif",
 
 			"}"
 
@@ -919,13 +927,15 @@ THREE.ShaderDeferred = {
 				"vec3 nearestPointInside = vec3( lightPositionVS ) + ( lightRightVS * nearest2D.x + lightUpVS * nearest2D.y );",
 
 				"vec3 lightDir = normalize( nearestPointInside - vertexPositionVS.xyz );",
-				"float NdotL = dot( lightNormalVS, -lightDir );",
+				"float NdotL = max( dot( lightNormalVS, -lightDir ), 0.0 );",
+				"float NdotL2 = max( dot( normal, lightDir ), 0.0 );",
 
-				"if ( NdotL != 0.0 && sideOfPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS ) ) {",
+				//"if ( NdotL2 * NdotL > 0.0 && sideOfPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS ) ) {",
+				"if ( NdotL2 * NdotL > 0.0 ) {",
 
 					// diffuse
 
-					"vec3 diffuse = vec3( NdotL );",
+					"vec3 diffuse = vec3( sqrt( NdotL * NdotL2 ) );",
 
 					// specular
 
@@ -941,8 +951,8 @@ THREE.ShaderDeferred = {
 						"vec3 dirSpec = E - vec3( lightPositionVS );",
 						"vec2 dirSpec2D = vec2( dot( dirSpec, lightRightVS ), dot( dirSpec, lightUpVS ) );",
 						"vec2 nearestSpec2D = vec2( clamp( dirSpec2D.x, -w, w ), clamp( dirSpec2D.y, -h, h ) );",
-						"float specFactor = 1.0 - clamp( length( nearestSpec2D - dirSpec2D ) * shininess, 0.0, 1.0 );",
-						"specular = specularColor * specFactor * specAngle;",
+						"float specFactor = 1.0 - clamp( length( nearestSpec2D - dirSpec2D ) * 0.05 * shininess, 0.0, 1.0 );",
+						"specular = specularColor * specFactor * specAngle * diffuse;",
 
 					"}",
 

+ 14 - 6
examples/webgl_lights_deferred_arealights.html

@@ -156,7 +156,15 @@
 			function createAreaEmitter( light ) {
 
 				var geometry = new THREE.CubeGeometry( 1, 1, 1 );
-				var material = new THREE.MeshBasicMaterial( { color: light.color.getHex() } );
+				var material = new THREE.MeshBasicMaterial( { color: light.color.getHex(), vertexColors: THREE.FaceColors } );
+
+				var backColor = 0x222222;
+
+				geometry.faces[ 5 ].color.setHex( backColor );
+				geometry.faces[ 4 ].color.setHex( backColor );
+				geometry.faces[ 2 ].color.setHex( backColor );
+				geometry.faces[ 1 ].color.setHex( backColor );
+				geometry.faces[ 0 ].color.setHex( backColor );
 
 				var emitter = new THREE.Mesh( geometry, material );
 
@@ -182,7 +190,7 @@
 			function initLights() {
 
 				areaLight1 = new THREE.AreaLight( 0xffffff, 1 );
-				areaLight1.position.set( 0.0001, 10.0001, -19.5001 );
+				areaLight1.position.set( 0.0001, 10.0001, -18.5001 );
 				areaLight1.rotation.set( -0.74719, 0.0001, 0.0001 );
 				areaLight1.width = 10;
 				areaLight1.height = 1;
@@ -227,7 +235,7 @@
 				var loader = new THREE.BinaryLoader();
 				loader.load( "obj/box/box.js", function ( geometry, materials ) {
 
-					var material = new THREE.MeshPhongMaterial( { color: 0xffaa55, specular: 0x888888, shininess: 10 } );
+					var material = new THREE.MeshPhongMaterial( { color: 0xffaa55, specular: 0x888888, shininess: 200 } );
 					var object = new THREE.Mesh( geometry, material );
 					object.scale.multiplyScalar( 2 );
 					scene.add( object );
@@ -362,13 +370,13 @@
 
 				var time = Date.now();
 
-				areaLight1.position.x = Math.sin( Date.now() * 0.001 ) * 10;
+				areaLight1.position.x = Math.sin( Date.now() * 0.001 ) * 9;
 				areaLight1.position.y = Math.sin( Date.now() * 0.0013 ) * 5 + 5;
 
-				areaLight2.position.y = Math.sin( Date.now() * 0.0011 ) * 5 + 5;
+				areaLight2.position.y = Math.sin( Date.now() * 0.0011 ) * 3 + 5;
 				areaLight2.position.z = Math.sin( Date.now() * 0.00113 ) * 10;
 
-				areaLight3.position.y = Math.sin( Date.now() * 0.00111 ) * 5 + 5;
+				areaLight3.position.y = Math.sin( Date.now() * 0.00111 ) * 3 + 5;
 				areaLight3.position.z = Math.sin( Date.now() * 0.001113 ) * 10;
 
 				// render