浏览代码

SAOPass: Improve performance, fix visuals. (#26599)

* SAOPass: Improve performance, fix visuals.

* Examples: Update screenshot.
Michael Herzog 1 年之前
父节点
当前提交
b37b76b2a3

+ 23 - 98
examples/jsm/postprocessing/SAOPass.js

@@ -6,14 +6,13 @@ import {
 	DstAlphaFactor,
 	DstAlphaFactor,
 	DstColorFactor,
 	DstColorFactor,
 	HalfFloatType,
 	HalfFloatType,
-	MeshDepthMaterial,
 	MeshNormalMaterial,
 	MeshNormalMaterial,
 	NearestFilter,
 	NearestFilter,
 	NoBlending,
 	NoBlending,
-	RGBADepthPacking,
 	ShaderMaterial,
 	ShaderMaterial,
 	UniformsUtils,
 	UniformsUtils,
-	UnsignedShortType,
+	DepthStencilFormat,
+	UnsignedInt248Type,
 	Vector2,
 	Vector2,
 	WebGLRenderTarget,
 	WebGLRenderTarget,
 	ZeroFactor
 	ZeroFactor
@@ -23,7 +22,6 @@ import { SAOShader } from '../shaders/SAOShader.js';
 import { DepthLimitedBlurShader } from '../shaders/DepthLimitedBlurShader.js';
 import { DepthLimitedBlurShader } from '../shaders/DepthLimitedBlurShader.js';
 import { BlurShaderUtils } from '../shaders/DepthLimitedBlurShader.js';
 import { BlurShaderUtils } from '../shaders/DepthLimitedBlurShader.js';
 import { CopyShader } from '../shaders/CopyShader.js';
 import { CopyShader } from '../shaders/CopyShader.js';
-import { UnpackDepthRGBAShader } from '../shaders/UnpackDepthRGBAShader.js';
 
 
 /**
 /**
  * SAO implementation inspired from bhouston previous SAO work
  * SAO implementation inspired from bhouston previous SAO work
@@ -31,7 +29,7 @@ import { UnpackDepthRGBAShader } from '../shaders/UnpackDepthRGBAShader.js';
 
 
 class SAOPass extends Pass {
 class SAOPass extends Pass {
 
 
-	constructor( scene, camera, useDepthTexture = false, useNormals = false, resolution = new Vector2( 256, 256 ) ) {
+	constructor( scene, camera, resolution = new Vector2( 256, 256 ) ) {
 
 
 		super();
 		super();
 
 
@@ -41,9 +39,6 @@ class SAOPass extends Pass {
 		this.clear = true;
 		this.clear = true;
 		this.needsSwap = false;
 		this.needsSwap = false;
 
 
-		this.supportsDepthTextureExtension = useDepthTexture;
-		this.supportsNormalTexture = useNormals;
-
 		this.originalClearColor = new Color();
 		this.originalClearColor = new Color();
 		this._oldClearColor = new Color();
 		this._oldClearColor = new Color();
 		this.oldClearAlpha = 1;
 		this.oldClearAlpha = 1;
@@ -65,30 +60,17 @@ class SAOPass extends Pass {
 
 
 		this.saoRenderTarget = new WebGLRenderTarget( this.resolution.x, this.resolution.y, { type: HalfFloatType } );
 		this.saoRenderTarget = new WebGLRenderTarget( this.resolution.x, this.resolution.y, { type: HalfFloatType } );
 		this.blurIntermediateRenderTarget = this.saoRenderTarget.clone();
 		this.blurIntermediateRenderTarget = this.saoRenderTarget.clone();
-		this.beautyRenderTarget = this.saoRenderTarget.clone();
+
+		const depthTexture = new DepthTexture();
+		depthTexture.format = DepthStencilFormat;
+		depthTexture.type = UnsignedInt248Type;
 
 
 		this.normalRenderTarget = new WebGLRenderTarget( this.resolution.x, this.resolution.y, {
 		this.normalRenderTarget = new WebGLRenderTarget( this.resolution.x, this.resolution.y, {
 			minFilter: NearestFilter,
 			minFilter: NearestFilter,
 			magFilter: NearestFilter,
 			magFilter: NearestFilter,
-			type: HalfFloatType
+			type: HalfFloatType,
+			depthTexture: depthTexture
 		} );
 		} );
-		this.depthRenderTarget = this.normalRenderTarget.clone();
-
-		let depthTexture;
-
-		if ( this.supportsDepthTextureExtension ) {
-
-			depthTexture = new DepthTexture();
-			depthTexture.type = UnsignedShortType;
-
-			this.beautyRenderTarget.depthTexture = depthTexture;
-			this.beautyRenderTarget.depthBuffer = true;
-
-		}
-
-		this.depthMaterial = new MeshDepthMaterial();
-		this.depthMaterial.depthPacking = RGBADepthPacking;
-		this.depthMaterial.blending = NoBlending;
 
 
 		this.normalMaterial = new MeshNormalMaterial();
 		this.normalMaterial = new MeshNormalMaterial();
 		this.normalMaterial.blending = NoBlending;
 		this.normalMaterial.blending = NoBlending;
@@ -100,10 +82,8 @@ class SAOPass extends Pass {
 			uniforms: UniformsUtils.clone( SAOShader.uniforms )
 			uniforms: UniformsUtils.clone( SAOShader.uniforms )
 		} );
 		} );
 		this.saoMaterial.extensions.derivatives = true;
 		this.saoMaterial.extensions.derivatives = true;
-		this.saoMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
-		this.saoMaterial.defines[ 'NORMAL_TEXTURE' ] = this.supportsNormalTexture ? 1 : 0;
 		this.saoMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
 		this.saoMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
-		this.saoMaterial.uniforms[ 'tDepth' ].value = ( this.supportsDepthTextureExtension ) ? depthTexture : this.depthRenderTarget.texture;
+		this.saoMaterial.uniforms[ 'tDepth' ].value = depthTexture;
 		this.saoMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
 		this.saoMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
 		this.saoMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
 		this.saoMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
 		this.saoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
 		this.saoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
@@ -116,10 +96,10 @@ class SAOPass extends Pass {
 			vertexShader: DepthLimitedBlurShader.vertexShader,
 			vertexShader: DepthLimitedBlurShader.vertexShader,
 			fragmentShader: DepthLimitedBlurShader.fragmentShader
 			fragmentShader: DepthLimitedBlurShader.fragmentShader
 		} );
 		} );
-		this.vBlurMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
+		this.vBlurMaterial.defines[ 'DEPTH_PACKING' ] = 0;
 		this.vBlurMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
 		this.vBlurMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
 		this.vBlurMaterial.uniforms[ 'tDiffuse' ].value = this.saoRenderTarget.texture;
 		this.vBlurMaterial.uniforms[ 'tDiffuse' ].value = this.saoRenderTarget.texture;
-		this.vBlurMaterial.uniforms[ 'tDepth' ].value = ( this.supportsDepthTextureExtension ) ? depthTexture : this.depthRenderTarget.texture;
+		this.vBlurMaterial.uniforms[ 'tDepth' ].value = depthTexture;
 		this.vBlurMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
 		this.vBlurMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
 		this.vBlurMaterial.blending = NoBlending;
 		this.vBlurMaterial.blending = NoBlending;
 
 
@@ -129,10 +109,10 @@ class SAOPass extends Pass {
 			vertexShader: DepthLimitedBlurShader.vertexShader,
 			vertexShader: DepthLimitedBlurShader.vertexShader,
 			fragmentShader: DepthLimitedBlurShader.fragmentShader
 			fragmentShader: DepthLimitedBlurShader.fragmentShader
 		} );
 		} );
-		this.hBlurMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
+		this.hBlurMaterial.defines[ 'DEPTH_PACKING' ] = 0;
 		this.hBlurMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
 		this.hBlurMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
 		this.hBlurMaterial.uniforms[ 'tDiffuse' ].value = this.blurIntermediateRenderTarget.texture;
 		this.hBlurMaterial.uniforms[ 'tDiffuse' ].value = this.blurIntermediateRenderTarget.texture;
-		this.hBlurMaterial.uniforms[ 'tDepth' ].value = ( this.supportsDepthTextureExtension ) ? depthTexture : this.depthRenderTarget.texture;
+		this.hBlurMaterial.uniforms[ 'tDepth' ].value = depthTexture;
 		this.hBlurMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
 		this.hBlurMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
 		this.hBlurMaterial.blending = NoBlending;
 		this.hBlurMaterial.blending = NoBlending;
 
 
@@ -153,13 +133,6 @@ class SAOPass extends Pass {
 		this.materialCopy.blendDstAlpha = ZeroFactor;
 		this.materialCopy.blendDstAlpha = ZeroFactor;
 		this.materialCopy.blendEquationAlpha = AddEquation;
 		this.materialCopy.blendEquationAlpha = AddEquation;
 
 
-		this.depthCopy = new ShaderMaterial( {
-			uniforms: UniformsUtils.clone( UnpackDepthRGBAShader.uniforms ),
-			vertexShader: UnpackDepthRGBAShader.vertexShader,
-			fragmentShader: UnpackDepthRGBAShader.fragmentShader,
-			blending: NoBlending
-		} );
-
 		this.fsQuad = new FullScreenQuad( null );
 		this.fsQuad = new FullScreenQuad( null );
 
 
 	}
 	}
@@ -176,20 +149,11 @@ class SAOPass extends Pass {
 
 
 		}
 		}
 
 
-		if ( this.params.output === 1 ) {
-
-			return;
-
-		}
-
 		renderer.getClearColor( this._oldClearColor );
 		renderer.getClearColor( this._oldClearColor );
 		this.oldClearAlpha = renderer.getClearAlpha();
 		this.oldClearAlpha = renderer.getClearAlpha();
 		const oldAutoClear = renderer.autoClear;
 		const oldAutoClear = renderer.autoClear;
 		renderer.autoClear = false;
 		renderer.autoClear = false;
 
 
-		renderer.setRenderTarget( this.depthRenderTarget );
-		renderer.clear();
-
 		this.saoMaterial.uniforms[ 'bias' ].value = this.params.saoBias;
 		this.saoMaterial.uniforms[ 'bias' ].value = this.params.saoBias;
 		this.saoMaterial.uniforms[ 'intensity' ].value = this.params.saoIntensity;
 		this.saoMaterial.uniforms[ 'intensity' ].value = this.params.saoIntensity;
 		this.saoMaterial.uniforms[ 'scale' ].value = this.params.saoScale;
 		this.saoMaterial.uniforms[ 'scale' ].value = this.params.saoScale;
@@ -218,26 +182,8 @@ class SAOPass extends Pass {
 
 
 		}
 		}
 
 
-		// Rendering scene to depth texture
-		renderer.setClearColor( 0x000000 );
-		renderer.setRenderTarget( this.beautyRenderTarget );
-		renderer.clear();
-		renderer.render( this.scene, this.camera );
-
-		// Re-render scene if depth texture extension is not supported
-		if ( ! this.supportsDepthTextureExtension ) {
-
-			// Clear rule : far clipping plane in both RGBA and Basic encoding
-			this.renderOverride( renderer, this.depthMaterial, this.depthRenderTarget, 0x000000, 1.0 );
-
-		}
-
-		if ( this.supportsNormalTexture ) {
-
-			// Clear rule : default normal is facing the camera
-			this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 );
-
-		}
+		// render normal and depth
+		this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 );
 
 
 		// Rendering SAO texture
 		// Rendering SAO texture
 		this.renderPass( renderer, this.saoMaterial, this.saoRenderTarget, 0xffffff, 1.0 );
 		this.renderPass( renderer, this.saoMaterial, this.saoRenderTarget, 0xffffff, 1.0 );
@@ -250,24 +196,10 @@ class SAOPass extends Pass {
 
 
 		}
 		}
 
 
-		let outputMaterial = this.materialCopy;
-		// Setting up SAO rendering
-		if ( this.params.output === 3 ) {
-
-			if ( this.supportsDepthTextureExtension ) {
-
-				this.materialCopy.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.depthTexture;
-				this.materialCopy.needsUpdate = true;
+		const outputMaterial = this.materialCopy;
 
 
-			} else {
-
-				this.depthCopy.uniforms[ 'tDiffuse' ].value = this.depthRenderTarget.texture;
-				this.depthCopy.needsUpdate = true;
-				outputMaterial = this.depthCopy;
-
-			}
-
-		} else if ( this.params.output === 4 ) {
+		// Setting up SAO rendering
+		if ( this.params.output === SAOPass.OUTPUT.Normal ) {
 
 
 			this.materialCopy.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
 			this.materialCopy.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
 			this.materialCopy.needsUpdate = true;
 			this.materialCopy.needsUpdate = true;
@@ -279,8 +211,8 @@ class SAOPass extends Pass {
 
 
 		}
 		}
 
 
-		// Blending depends on output, only want a CustomBlending when showing SAO
-		if ( this.params.output === 0 ) {
+		// Blending depends on output
+		if ( this.params.output === SAOPass.OUTPUT.Default ) {
 
 
 			outputMaterial.blending = CustomBlending;
 			outputMaterial.blending = CustomBlending;
 
 
@@ -359,11 +291,9 @@ class SAOPass extends Pass {
 
 
 	setSize( width, height ) {
 	setSize( width, height ) {
 
 
-		this.beautyRenderTarget.setSize( width, height );
 		this.saoRenderTarget.setSize( width, height );
 		this.saoRenderTarget.setSize( width, height );
 		this.blurIntermediateRenderTarget.setSize( width, height );
 		this.blurIntermediateRenderTarget.setSize( width, height );
 		this.normalRenderTarget.setSize( width, height );
 		this.normalRenderTarget.setSize( width, height );
-		this.depthRenderTarget.setSize( width, height );
 
 
 		this.saoMaterial.uniforms[ 'size' ].value.set( width, height );
 		this.saoMaterial.uniforms[ 'size' ].value.set( width, height );
 		this.saoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
 		this.saoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
@@ -382,9 +312,7 @@ class SAOPass extends Pass {
 
 
 		this.saoRenderTarget.dispose();
 		this.saoRenderTarget.dispose();
 		this.blurIntermediateRenderTarget.dispose();
 		this.blurIntermediateRenderTarget.dispose();
-		this.beautyRenderTarget.dispose();
 		this.normalRenderTarget.dispose();
 		this.normalRenderTarget.dispose();
-		this.depthRenderTarget.dispose();
 
 
 		this.depthMaterial.dispose();
 		this.depthMaterial.dispose();
 		this.normalMaterial.dispose();
 		this.normalMaterial.dispose();
@@ -392,7 +320,6 @@ class SAOPass extends Pass {
 		this.vBlurMaterial.dispose();
 		this.vBlurMaterial.dispose();
 		this.hBlurMaterial.dispose();
 		this.hBlurMaterial.dispose();
 		this.materialCopy.dispose();
 		this.materialCopy.dispose();
-		this.depthCopy.dispose();
 
 
 		this.fsQuad.dispose();
 		this.fsQuad.dispose();
 
 
@@ -401,11 +328,9 @@ class SAOPass extends Pass {
 }
 }
 
 
 SAOPass.OUTPUT = {
 SAOPass.OUTPUT = {
-	'Beauty': 1,
 	'Default': 0,
 	'Default': 0,
-	'SAO': 2,
-	'Depth': 3,
-	'Normal': 4
+	'SAO': 1,
+	'Normal': 2
 };
 };
 
 
 export { SAOPass };
 export { SAOPass };

+ 0 - 13
examples/jsm/shaders/SAOShader.js

@@ -11,9 +11,7 @@ const SAOShader = {
 	defines: {
 	defines: {
 		'NUM_SAMPLES': 7,
 		'NUM_SAMPLES': 7,
 		'NUM_RINGS': 4,
 		'NUM_RINGS': 4,
-		'NORMAL_TEXTURE': 0,
 		'DIFFUSE_TEXTURE': 0,
 		'DIFFUSE_TEXTURE': 0,
-		'DEPTH_PACKING': 1,
 		'PERSPECTIVE_CAMERA': 1
 		'PERSPECTIVE_CAMERA': 1
 	},
 	},
 	uniforms: {
 	uniforms: {
@@ -56,10 +54,7 @@ const SAOShader = {
 		#endif
 		#endif
 
 
 		uniform sampler2D tDepth;
 		uniform sampler2D tDepth;
-
-		#if NORMAL_TEXTURE == 1
 		uniform sampler2D tNormal;
 		uniform sampler2D tNormal;
-		#endif
 
 
 		uniform float cameraNear;
 		uniform float cameraNear;
 		uniform float cameraFar;
 		uniform float cameraFar;
@@ -87,11 +82,7 @@ const SAOShader = {
 		}
 		}
 
 
 		float getDepth( const in vec2 screenPosition ) {
 		float getDepth( const in vec2 screenPosition ) {
-			#if DEPTH_PACKING == 1
-			return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );
-			#else
 			return texture2D( tDepth, screenPosition ).x;
 			return texture2D( tDepth, screenPosition ).x;
-			#endif
 		}
 		}
 
 
 		float getViewZ( const in float depth ) {
 		float getViewZ( const in float depth ) {
@@ -111,11 +102,7 @@ const SAOShader = {
 		}
 		}
 
 
 		vec3 getViewNormal( const in vec3 viewPosition, const in vec2 screenPosition ) {
 		vec3 getViewNormal( const in vec3 viewPosition, const in vec2 screenPosition ) {
-			#if NORMAL_TEXTURE == 1
 			return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );
 			return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );
-			#else
-			return normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) );
-			#endif
 		}
 		}
 
 
 		float scaleDividedByCameraFar;
 		float scaleDividedByCameraFar;

二进制
examples/screenshots/webgl_postprocessing_sao.jpg


+ 7 - 10
examples/webgl_postprocessing_sao.html

@@ -50,13 +50,11 @@
 				container = document.createElement( 'div' );
 				container = document.createElement( 'div' );
 				document.body.appendChild( container );
 				document.body.appendChild( container );
 
 
-				const width = window.innerWidth || 1;
-				const height = window.innerHeight || 1;
-				const devicePixelRatio = window.devicePixelRatio || 1;
+				const width = window.innerWidth;
+				const height = window.innerHeight;
 
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setClearColor( 0x000000 );
-				renderer.setPixelRatio( devicePixelRatio );
+				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( width, height );
 				renderer.setSize( width, height );
 				document.body.appendChild( renderer.domElement );
 				document.body.appendChild( renderer.domElement );
 
 
@@ -117,7 +115,7 @@
 				composer = new EffectComposer( renderer );
 				composer = new EffectComposer( renderer );
 				renderPass = new RenderPass( scene, camera );
 				renderPass = new RenderPass( scene, camera );
 				composer.addPass( renderPass );
 				composer.addPass( renderPass );
-				saoPass = new SAOPass( scene, camera, false, true );
+				saoPass = new SAOPass( scene, camera );
 				composer.addPass( saoPass );
 				composer.addPass( saoPass );
 				const outputPass = new OutputPass();
 				const outputPass = new OutputPass();
 				composer.addPass( outputPass );
 				composer.addPass( outputPass );
@@ -125,10 +123,8 @@
 				// Init gui
 				// Init gui
 				const gui = new GUI();
 				const gui = new GUI();
 				gui.add( saoPass.params, 'output', {
 				gui.add( saoPass.params, 'output', {
-					'Beauty': SAOPass.OUTPUT.Beauty,
-					'Beauty+SAO': SAOPass.OUTPUT.Default,
-					'SAO': SAOPass.OUTPUT.SAO,
-					'Depth': SAOPass.OUTPUT.Depth,
+					'Default': SAOPass.OUTPUT.Default,
+					'SAO Only': SAOPass.OUTPUT.SAO,
 					'Normal': SAOPass.OUTPUT.Normal
 					'Normal': SAOPass.OUTPUT.Normal
 				} ).onChange( function ( value ) {
 				} ).onChange( function ( value ) {
 
 
@@ -144,6 +140,7 @@
 				gui.add( saoPass.params, 'saoBlurRadius', 0, 200 );
 				gui.add( saoPass.params, 'saoBlurRadius', 0, 200 );
 				gui.add( saoPass.params, 'saoBlurStdDev', 0.5, 150 );
 				gui.add( saoPass.params, 'saoBlurStdDev', 0.5, 150 );
 				gui.add( saoPass.params, 'saoBlurDepthCutoff', 0.0, 0.1 );
 				gui.add( saoPass.params, 'saoBlurDepthCutoff', 0.0, 0.1 );
+				gui.add( saoPass, 'enabled' );
 
 
 				window.addEventListener( 'resize', onWindowResize );
 				window.addEventListener( 'resize', onWindowResize );