瀏覽代碼

WebGLDeferredRenderer: merged normal and depth passes into a single pass.

alteredq 12 年之前
父節點
當前提交
62d71401fd
共有 2 個文件被更改,包括 81 次插入162 次删除
  1. 24 64
      examples/js/ShaderDeferred.js
  2. 57 98
      examples/js/renderers/WebGLDeferredRenderer.js

+ 24 - 64
examples/js/ShaderDeferred.js

@@ -125,42 +125,7 @@ THREE.ShaderDeferred = {
 
 	},
 
-	"clipDepth" : {
-
-		uniforms: { },
-
-		fragmentShader : [
-
-			"varying vec4 clipPos;",
-
-			"void main() {",
-
-				"gl_FragColor = vec4( clipPos.z / clipPos.w, 1.0, 1.0, 1.0 );",
-
-			"}"
-
-		].join("\n"),
-
-		vertexShader : [
-
-			"varying vec4 clipPos;",
-
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-
-			"void main() {",
-
-				THREE.ShaderChunk[ "morphtarget_vertex" ],
-				THREE.ShaderChunk[ "default_vertex" ],
-
-				"clipPos = gl_Position;",
-
-			"}"
-
-		].join("\n")
-
-	},
-
-	"normals" : {
+	"normalDepth" : {
 
 		uniforms: {
 
@@ -184,6 +149,7 @@ THREE.ShaderDeferred = {
 			"#endif",
 
 			"varying vec3 normalView;",
+			"varying vec4 clipPos;",
 
 			"void main() {",
 
@@ -195,7 +161,8 @@ THREE.ShaderDeferred = {
 
 				"#endif",
 
-				"gl_FragColor = vec4( vec3( normal * 0.5 + 0.5 ), 1.0 );",
+				"gl_FragColor.xyz = normal * 0.5 + 0.5;",
+				"gl_FragColor.w = clipPos.z / clipPos.w;",
 
 			"}"
 
@@ -204,6 +171,7 @@ THREE.ShaderDeferred = {
 		vertexShader : [
 
 			"varying vec3 normalView;",
+			"varying vec4 clipPos;",
 
 			"#ifdef USE_BUMPMAP",
 
@@ -245,6 +213,8 @@ THREE.ShaderDeferred = {
 
 				"#endif",
 
+				"clipPos = gl_Position;",
+
 			"}"
 
 		].join("\n")
@@ -295,9 +265,8 @@ THREE.ShaderDeferred = {
 
 		uniforms: {
 
-			samplerNormals: { type: "t", value: null },
-			samplerDepth: 	{ type: "t", value: null },
-			samplerColor: 	{ type: "t", value: null },
+			samplerNormalDepth: { type: "t", value: null },
+			samplerColor: 		{ type: "t", value: null },
 			matView: 		{ type: "m4", value: new THREE.Matrix4() },
 			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
 			viewWidth: 		{ type: "f", value: 800 },
@@ -315,8 +284,7 @@ THREE.ShaderDeferred = {
 			"varying vec4 clipPos;",
 
 			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerDepth;",
-			"uniform sampler2D samplerNormals;",
+			"uniform sampler2D samplerNormalDepth;",
 
 			"uniform float lightRadius;",
 			"uniform float lightIntensity;",
@@ -342,17 +310,10 @@ THREE.ShaderDeferred = {
 
 				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
 
-				"float z = texture2D( samplerDepth, texCoord ).x;",
-				"float lightZ = clipPos.z / clipPos.w;",
-
-				/*
-				"if ( z == 0.0 ) {",
+				"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
 
-					"gl_FragColor = vec4( vec3( 0.0 ), 1.0 );",
-					"return;",
-
-				"}",
-				*/
+				"float z = normalDepth.w;",
+				"float lightZ = clipPos.z / clipPos.w;",
 
 				"if ( z == 0.0 || lightZ > z ) discard;",
 
@@ -381,7 +342,7 @@ THREE.ShaderDeferred = {
 
 				// normal
 
-				"vec3 normal = texture2D( samplerNormals, texCoord ).xyz * 2.0 - 1.0;",
+				"vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
 
 				// color
 
@@ -462,9 +423,8 @@ THREE.ShaderDeferred = {
 
 		uniforms: {
 
-			samplerNormals: { type: "t", value: null },
-			samplerDepth: 	{ type: "t", value: null },
-			samplerColor: 	{ type: "t", value: null },
+			samplerNormalDepth: { type: "t", value: null },
+			samplerColor: 		{ type: "t", value: null },
 			matView: 		{ type: "m4", value: new THREE.Matrix4() },
 			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
 			viewWidth: 		{ type: "f", value: 800 },
@@ -481,8 +441,7 @@ THREE.ShaderDeferred = {
 			"varying vec4 clipPos;",
 
 			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerDepth;",
-			"uniform sampler2D samplerNormals;",
+			"uniform sampler2D samplerNormalDepth;",
 
 			"uniform float lightRadius;",
 			"uniform float lightIntensity;",
@@ -508,7 +467,8 @@ THREE.ShaderDeferred = {
 
 				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
 
-				"float z = texture2D( samplerDepth, texCoord ).x;",
+				"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
+				"float z = normalDepth.w;",
 
 				"if ( z == 0.0 ) discard;",
 
@@ -525,7 +485,7 @@ THREE.ShaderDeferred = {
 
 				// normal
 
-				"vec3 normal = texture2D( samplerNormals, texCoord ).xyz * 2.0 - 1.0;",
+				"vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
 
 				// color
 
@@ -605,8 +565,8 @@ THREE.ShaderDeferred = {
 
 		uniforms: {
 
-			samplerDepth: 	{ type: "t", value: null },
-			samplerColor: 	{ type: "t", value: null },
+			samplerNormalDepth: 	{ type: "t", value: null },
+			samplerColor: 			{ type: "t", value: null },
 			viewWidth: 		{ type: "f", value: 800 },
 			viewHeight: 	{ type: "f", value: 600 },
 
@@ -614,7 +574,7 @@ THREE.ShaderDeferred = {
 
 		fragmentShader : [
 
-			"uniform sampler2D samplerDepth;",
+			"uniform sampler2D samplerNormalDepth;",
 			"uniform sampler2D samplerColor;",
 
 			"uniform float viewHeight;",
@@ -635,7 +595,7 @@ THREE.ShaderDeferred = {
 
 				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
 
-				"float z = texture2D( samplerDepth, texCoord ).x;",
+				"float z = texture2D( samplerNormalDepth, texCoord ).w;",
 
 				"if ( z == 0.0 ) discard;",
 

+ 57 - 98
examples/js/renderers/WebGLDeferredRenderer.js

@@ -23,7 +23,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		this.renderer = new THREE.WebGLRenderer( { alpha: false } );
 		this.renderer.setSize( width, height );
-		this.renderer.setClearColorHex( 0x000000, 1 );
+		this.renderer.setClearColorHex( 0x000000, 0 );
 
 		this.renderer.autoClear = false;
 
@@ -39,8 +39,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	var black = new THREE.Color( 0x000000 );
 
 	var colorShader = THREE.ShaderDeferred[ "color" ];
-	var normalShader = THREE.ShaderDeferred[ "normals" ];
-	var clipDepthShader = THREE.ShaderDeferred[ "clipDepth" ];
+	var normalDepthShader = THREE.ShaderDeferred[ "normalDepth" ];
 
 	//
 
@@ -64,19 +63,11 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 	//
 
-	var defaultNormalMaterial = new THREE.ShaderMaterial( {
+	var defaultNormalDepthMaterial = new THREE.ShaderMaterial( {
 
-		uniforms:       THREE.UniformsUtils.clone( normalShader.uniforms ),
-		vertexShader:   normalShader.vertexShader,
-		fragmentShader: normalShader.fragmentShader
-
-	} );
-
-	var defaultDepthMaterial = new THREE.ShaderMaterial( {
-
-		uniforms:       THREE.UniformsUtils.clone( clipDepthShader.uniforms ),
-		vertexShader:   clipDepthShader.vertexShader,
-		fragmentShader: clipDepthShader.fragmentShader
+		uniforms:       THREE.UniformsUtils.clone( normalDepthShader.uniforms ),
+		vertexShader:   normalDepthShader.vertexShader,
+		fragmentShader: normalDepthShader.fragmentShader
 
 	} );
 
@@ -87,8 +78,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		if ( object.material instanceof THREE.MeshFaceMaterial ) {
 
 			var colorMaterials = [];
-			var depthMaterials = [];
-			var normalMaterials = [];
+			var normalDepthMaterials = [];
 
 			var materials = object.material.materials;
 
@@ -97,22 +87,19 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 				var deferredMaterials = createDeferredMaterials( materials[ i ] );
 
 				colorMaterials.push( deferredMaterials.colorMaterial );
-				depthMaterials.push( deferredMaterials.depthMaterial );
-				normalMaterials.push( deferredMaterials.normalMaterial );
+				normalDepthMaterials.push( deferredMaterials.normalDepthMaterial );
 
 			}
 
 			object.properties.colorMaterial = new THREE.MeshFaceMaterial( colorMaterials );
-			object.properties.depthMaterial = new THREE.MeshFaceMaterial( depthMaterials );
-			object.properties.normalMaterial = new THREE.MeshFaceMaterial( normalMaterials );
+			object.properties.normalDepthMaterial = new THREE.MeshFaceMaterial( normalDepthMaterials );
 
 		} else {
 
 			var deferredMaterials = createDeferredMaterials( object.material );
 
 			object.properties.colorMaterial = deferredMaterials.colorMaterial;
-			object.properties.depthMaterial = deferredMaterials.depthMaterial;
-			object.properties.normalMaterial = deferredMaterials.normalMaterial;
+			object.properties.normalDepthMaterial = deferredMaterials.normalDepthMaterial;
 
 		}
 
@@ -185,32 +172,34 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		deferredMaterials.colorMaterial = material;
 
-		// normal material
+		// normal + depth material
 		// -----------------
 		//	vertex normals
 		//	morph normals
 		//	bump map
 		//	bump scale
+		//  clip depth
 
 		if ( originalMaterial.morphTargets || originalMaterial.bumpMap ) {
 
-			var uniforms = THREE.UniformsUtils.clone( normalShader.uniforms );
+			var uniforms = THREE.UniformsUtils.clone( normalDepthShader.uniforms );
 			var defines = { "USE_BUMPMAP": !!originalMaterial.bumpMap };
 
-			var normalMaterial = new THREE.ShaderMaterial( {
+			var normalDepthMaterial = new THREE.ShaderMaterial( {
 
 				uniforms:       uniforms,
-				vertexShader:   normalShader.vertexShader,
-				fragmentShader: normalShader.fragmentShader,
+				vertexShader:   normalDepthShader.vertexShader,
+				fragmentShader: normalDepthShader.fragmentShader,
 				shading:		originalMaterial.shading,
-				defines:		defines
+				defines:		defines,
+				blending:		THREE.NoBlending
 
 			} );
 
 			if ( originalMaterial.morphTargets ) {
 
-				normalMaterial.morphTargets = originalMaterial.morphTargets;
-				normalMaterial.morphNormals = originalMaterial.morphNormals;
+				normalDepthMaterial.morphTargets = originalMaterial.morphTargets;
+				normalDepthMaterial.morphNormals = originalMaterial.morphNormals;
 
 			}
 
@@ -226,33 +215,11 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 			}
 
-			deferredMaterials.normalMaterial = normalMaterial;
+			deferredMaterials.normalDepthMaterial = normalDepthMaterial;
 
 		} else {
 
-			deferredMaterials.normalMaterial = defaultNormalMaterial;
-
-		}
-
-		// depth material
-
-		if ( originalMaterial.morphTargets ) {
-
-			var depthMaterial = new THREE.ShaderMaterial( {
-
-				uniforms:       THREE.UniformsUtils.clone( clipDepthShader.uniforms ),
-				vertexShader:   clipDepthShader.vertexShader,
-				fragmentShader: clipDepthShader.fragmentShader
-
-			} );
-
-			depthMaterial.morphTargets = originalMaterial.morphTargets;
-
-			deferredMaterials.depthMaterial = depthMaterial;
-
-		} else {
-
-			deferredMaterials.depthMaterial = defaultDepthMaterial;
+			deferredMaterials.normalDepthMaterial = defaultNormalDepthMaterial;
 
 		}
 
@@ -286,8 +253,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
 
 		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		materialLight.uniforms[ 'samplerNormals' ].value = compNormal.renderTarget2;
-		materialLight.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
+		materialLight.uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
 
 		// create light proxy mesh
 
@@ -328,8 +294,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
 
 		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		materialLight.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
-		materialLight.uniforms[ 'samplerNormals' ].value = compNormal.renderTarget2;
+		materialLight.uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
 
 		// create light proxy mesh
 
@@ -354,7 +319,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 			vertexShader:   emissiveLightShader.vertexShader,
 			fragmentShader: emissiveLightShader.fragmentShader,
 			depthTest:		false,
-			depthWrite:		false
+			depthWrite:		false,
+			blending:		THREE.NoBlending
 
 		} );
 
@@ -363,7 +329,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
 
 		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		materialLight.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
+		materialLight.uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
 
 		// create light proxy mesh
 
@@ -408,15 +374,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 	};
 
-	var setMaterialDepth = function ( object ) {
-
-		if ( object.material ) object.material = object.properties.depthMaterial;
-
-	};
-
-	var setMaterialNormal = function ( object ) {
+	var setMaterialNormalDepth = function ( object ) {
 
-		if ( object.material ) object.material = object.properties.normalMaterial;
+		if ( object.material ) object.material = object.properties.normalDepthMaterial;
 
 	};
 
@@ -430,8 +390,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		scaledHeight = Math.floor( scale * height );
 
 		compColor.setSize( scaledWidth, scaledHeight );
-		compNormal.setSize( scaledWidth, scaledHeight );
-		compDepth.setSize( scaledWidth, scaledHeight );
+		compNormalDepth.setSize( scaledWidth, scaledHeight );
 		compLight.setSize( scaledWidth, scaledHeight );
 		compFinal.setSize( scaledWidth, scaledHeight );
 
@@ -443,11 +402,10 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 			uniforms[ "viewHeight" ].value = scaledHeight;
 
 			uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-			uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
 
-			if ( uniforms[ 'samplerNormals' ] ) {
+			if ( uniforms[ 'samplerNormalDepth' ] ) {
 
-				uniforms[ 'samplerNormals' ].value = compNormal.renderTarget2;
+				uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
 
 			}
 
@@ -479,19 +437,19 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		lightSceneFullscreen = scene.properties.lightSceneFullscreen;
 
 		passColor.camera = camera;
-		passNormal.camera = camera;
-		passDepth.camera = camera;
+		passNormalDepth.camera = camera;
 		passLightProxy.camera = camera;
 		passLightFullscreen.camera = THREE.EffectComposer.camera;
 
 		passColor.scene = scene;
-		passNormal.scene = scene;
-		passDepth.scene = scene;
+		passNormalDepth.scene = scene;
 		passLightFullscreen.scene = lightSceneFullscreen;
 		passLightProxy.scene = lightSceneProxy;
 
 		scene.traverse( initDeferredProperties );
 
+		// update scene graph only once per frame
+
 		this.renderer.autoUpdateScene = false;
 		scene.updateMatrixWorld();
 
@@ -500,15 +458,10 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		scene.traverse( setMaterialColor );
 		compColor.render();
 
-		// g-buffer depth
-
-		scene.traverse( setMaterialDepth );
-		compDepth.render();
+		// g-buffer normals + depth
 
-		// g-buffer normals
-
-		scene.traverse( setMaterialNormal );
-		compNormal.render();
+		scene.traverse( setMaterialNormalDepth );
+		compNormalDepth.render();
 
 		this.renderer.autoUpdateScene = true;
 
@@ -555,32 +508,36 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		// g-buffers
 
 		var rtColor   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatNearest );
-		var rtNormal  = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatLinear );
-		var rtDepth   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatLinear );
+		var rtNormalDepth = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatLinear );
 		var rtLight   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatLinear );
 		var rtFinal   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsUByte );
 
 		rtColor.generateMipmaps = false;
-		rtNormal.generateMipmaps = false;
-		rtDepth.generateMipmaps = false;
+		rtNormalDepth.generateMipmaps = false;
 		rtLight.generateMipmaps = false;
 		rtFinal.generateMipmaps = false;
 
-		// composers
+		// color composer
 
 		passColor = new THREE.RenderPass();
+		passColor.clear = true;
+
 		compColor = new THREE.EffectComposer( _this.renderer, rtColor );
 		compColor.addPass( passColor );
 
-		passNormal = new THREE.RenderPass();
-		compNormal = new THREE.EffectComposer( _this.renderer, rtNormal );
-		compNormal.addPass( passNormal );
+		// normal + depth composer
 
-		passDepth = new THREE.RenderPass();
-		compDepth = new THREE.EffectComposer( _this.renderer, rtDepth );
-		compDepth.addPass( passDepth );
+		passNormalDepth = new THREE.RenderPass();
+		passNormalDepth.clear = true;
+
+		compNormalDepth = new THREE.EffectComposer( _this.renderer, rtNormalDepth );
+		compNormalDepth.addPass( passNormalDepth );
+
+		// light composer
 
 		passLightFullscreen = new THREE.RenderPass();
+		passLightFullscreen.clear = true;
+
 		passLightProxy = new THREE.RenderPass();
 		passLightProxy.clear = false;
 
@@ -588,11 +545,13 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		compLight.addPass( passLightFullscreen );
 		compLight.addPass( passLightProxy );
 
-		// composite
+		// final composer
 
 		compositePass = new THREE.ShaderPass( compositeShader );
 		compositePass.uniforms[ 'samplerLight' ].value = compLight.renderTarget2;
 		compositePass.uniforms[ 'multiply' ].value = multiply;
+		compositePass.material.blending = THREE.NoBlending;
+		compositePass.clear = true;
 
 		// FXAA