提交 4a976331 编写于 作者: A alteredq

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.
上级 3fa6cd47
......@@ -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;",
"}",
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册