Browse Source

WebGLDeferredRenderer: fixed light terms combination and z-fighting glitches.

Phew, took ages to figure these out.
alteredq 12 năm trước cách đây
mục cha
commit
263960c8f8

+ 2 - 2
examples/js/ShaderDeferred.js

@@ -410,7 +410,7 @@ THREE.ShaderDeferred = {
 				// combine
 
 				"vec3 light = lightIntensity * lightColor;",
-				"gl_FragColor = vec4( albedo * light * diffuse, attenuation ) + vec4( light * specular, attenuation );",
+				"gl_FragColor = vec4( light * ( albedo * diffuse + specular ), attenuation );",
 
 			"}"
 
@@ -554,7 +554,7 @@ THREE.ShaderDeferred = {
 				// combine
 
 				"vec3 light = lightIntensity * lightColor;",
-				"gl_FragColor = vec4( albedo * light * diffuse, 1.0 ) + vec4( light * specular, 1.0 );",
+				"gl_FragColor = vec4( light * ( albedo * diffuse + specular ), 1.0 );",
 
 			"}"
 

+ 21 - 19
examples/js/renderers/WebGLDeferredRenderer.js

@@ -71,7 +71,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		uniforms:       THREE.UniformsUtils.clone( normalDepthShader.uniforms ),
 		vertexShader:   normalDepthShader.vertexShader,
-		fragmentShader: normalDepthShader.fragmentShader
+		fragmentShader: normalDepthShader.fragmentShader,
+		blending:		THREE.NoBlending
 
 	} );
 
@@ -231,8 +232,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 				fragmentShader: normalDepthShader.fragmentShader,
 				shading:		originalMaterial.shading,
 				defines:		defines,
-				blending:		THREE.NoBlending,
-				depthWrite:		false
+				blending:		THREE.NoBlending
 
 			} );
 
@@ -632,30 +632,37 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		compColor.render();
 
+		// just touch foreground pixels (stencil == 1)
+		// both in normalDepth and light passes
+
+		gl.stencilFunc( gl.EQUAL, 1, 0xffffffff );
+		gl.stencilOp( gl.KEEP, gl.KEEP, gl.KEEP );
+
 		// 2) g-buffer normals + depth pass
 
 		scene.traverse( setMaterialNormalDepth );
 
-		// do not touch shared depth buffer in this pass
-		// (no depth clearing, no depth writing,
-		//  just write color pixel if depth is the same)
+		// must use clean slate depth buffer
+		// otherwise there are z-fighting glitches
+		// not enough precision between two geometry passes
+		// just to use EQUAL depth test
 
-		this.renderer.autoClearDepth = false;
+		this.renderer.autoClearDepth = true;
 		this.renderer.autoClearStencil = false;
-		gl.depthFunc( gl.EQUAL );
-
-		// just touch foreground pixels (stencil == 1)
-		// both in normalDepth and light passes
-
-		gl.stencilFunc( gl.EQUAL, 1, 0xffffffff );
-		gl.stencilOp( gl.KEEP, gl.KEEP, gl.KEEP );
 
 		compNormalDepth.render();
 
 		// 3) light pass
 
+		// do not clear depth buffer in this pass
+		// depth from geometry pass is used for light culling
+		// (write light proxy color pixel if behind scene pixel)
+
+		this.renderer.autoClearDepth = false;
 		this.renderer.autoUpdateScene = true;
 
+		gl.depthFunc( gl.GEQUAL );
+
 		camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
 
 		for ( var i = 0, il = lightSceneProxy.children.length; i < il; i ++ ) {
@@ -672,11 +679,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-		// still no touching shared depth buffer
-		// (write light proxy color pixel if behind scene pixel)
-
-		gl.depthFunc( gl.GEQUAL );
-
 		compLight.render();
 
 		// 4) composite pass

+ 1 - 1
examples/webgl_lights_deferred_pointlights.html

@@ -240,7 +240,7 @@
 					mapHeight.anisotropy = 4;
 					mapHeight.format = THREE.RGBFormat;
 
-					var material = new THREE.MeshPhongMaterial( { map: mapColor, bumpMap: mapHeight, bumpScale: 2.5, shininess: 75, specular: 0x090909, wrapAround: true, metal: true } );
+					var material = new THREE.MeshPhongMaterial( { map: mapColor, bumpMap: mapHeight, bumpScale: 2.5, shininess: 75, specular: 0x333333, wrapAround: true, metal: true } );
 
 					var object = new THREE.Mesh( geometry, material );
 					object.scale.multiplyScalar( 8 );