Skip to content

Commit b37b76b

Browse files
authored
SAOPass: Improve performance, fix visuals. (#26599)
* SAOPass: Improve performance, fix visuals. * Examples: Update screenshot.
1 parent f7341c3 commit b37b76b

File tree

4 files changed

+30
-121
lines changed

4 files changed

+30
-121
lines changed

examples/jsm/postprocessing/SAOPass.js

Lines changed: 23 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ import {
66
DstAlphaFactor,
77
DstColorFactor,
88
HalfFloatType,
9-
MeshDepthMaterial,
109
MeshNormalMaterial,
1110
NearestFilter,
1211
NoBlending,
13-
RGBADepthPacking,
1412
ShaderMaterial,
1513
UniformsUtils,
16-
UnsignedShortType,
14+
DepthStencilFormat,
15+
UnsignedInt248Type,
1716
Vector2,
1817
WebGLRenderTarget,
1918
ZeroFactor
@@ -23,15 +22,14 @@ import { SAOShader } from '../shaders/SAOShader.js';
2322
import { DepthLimitedBlurShader } from '../shaders/DepthLimitedBlurShader.js';
2423
import { BlurShaderUtils } from '../shaders/DepthLimitedBlurShader.js';
2524
import { CopyShader } from '../shaders/CopyShader.js';
26-
import { UnpackDepthRGBAShader } from '../shaders/UnpackDepthRGBAShader.js';
2725

2826
/**
2927
* SAO implementation inspired from bhouston previous SAO work
3028
*/
3129

3230
class SAOPass extends Pass {
3331

34-
constructor( scene, camera, useDepthTexture = false, useNormals = false, resolution = new Vector2( 256, 256 ) ) {
32+
constructor( scene, camera, resolution = new Vector2( 256, 256 ) ) {
3533

3634
super();
3735

@@ -41,9 +39,6 @@ class SAOPass extends Pass {
4139
this.clear = true;
4240
this.needsSwap = false;
4341

44-
this.supportsDepthTextureExtension = useDepthTexture;
45-
this.supportsNormalTexture = useNormals;
46-
4742
this.originalClearColor = new Color();
4843
this._oldClearColor = new Color();
4944
this.oldClearAlpha = 1;
@@ -65,30 +60,17 @@ class SAOPass extends Pass {
6560

6661
this.saoRenderTarget = new WebGLRenderTarget( this.resolution.x, this.resolution.y, { type: HalfFloatType } );
6762
this.blurIntermediateRenderTarget = this.saoRenderTarget.clone();
68-
this.beautyRenderTarget = this.saoRenderTarget.clone();
63+
64+
const depthTexture = new DepthTexture();
65+
depthTexture.format = DepthStencilFormat;
66+
depthTexture.type = UnsignedInt248Type;
6967

7068
this.normalRenderTarget = new WebGLRenderTarget( this.resolution.x, this.resolution.y, {
7169
minFilter: NearestFilter,
7270
magFilter: NearestFilter,
73-
type: HalfFloatType
71+
type: HalfFloatType,
72+
depthTexture: depthTexture
7473
} );
75-
this.depthRenderTarget = this.normalRenderTarget.clone();
76-
77-
let depthTexture;
78-
79-
if ( this.supportsDepthTextureExtension ) {
80-
81-
depthTexture = new DepthTexture();
82-
depthTexture.type = UnsignedShortType;
83-
84-
this.beautyRenderTarget.depthTexture = depthTexture;
85-
this.beautyRenderTarget.depthBuffer = true;
86-
87-
}
88-
89-
this.depthMaterial = new MeshDepthMaterial();
90-
this.depthMaterial.depthPacking = RGBADepthPacking;
91-
this.depthMaterial.blending = NoBlending;
9274

9375
this.normalMaterial = new MeshNormalMaterial();
9476
this.normalMaterial.blending = NoBlending;
@@ -100,10 +82,8 @@ class SAOPass extends Pass {
10082
uniforms: UniformsUtils.clone( SAOShader.uniforms )
10183
} );
10284
this.saoMaterial.extensions.derivatives = true;
103-
this.saoMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
104-
this.saoMaterial.defines[ 'NORMAL_TEXTURE' ] = this.supportsNormalTexture ? 1 : 0;
10585
this.saoMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
106-
this.saoMaterial.uniforms[ 'tDepth' ].value = ( this.supportsDepthTextureExtension ) ? depthTexture : this.depthRenderTarget.texture;
86+
this.saoMaterial.uniforms[ 'tDepth' ].value = depthTexture;
10787
this.saoMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
10888
this.saoMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
10989
this.saoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
@@ -116,10 +96,10 @@ class SAOPass extends Pass {
11696
vertexShader: DepthLimitedBlurShader.vertexShader,
11797
fragmentShader: DepthLimitedBlurShader.fragmentShader
11898
} );
119-
this.vBlurMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
99+
this.vBlurMaterial.defines[ 'DEPTH_PACKING' ] = 0;
120100
this.vBlurMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
121101
this.vBlurMaterial.uniforms[ 'tDiffuse' ].value = this.saoRenderTarget.texture;
122-
this.vBlurMaterial.uniforms[ 'tDepth' ].value = ( this.supportsDepthTextureExtension ) ? depthTexture : this.depthRenderTarget.texture;
102+
this.vBlurMaterial.uniforms[ 'tDepth' ].value = depthTexture;
123103
this.vBlurMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
124104
this.vBlurMaterial.blending = NoBlending;
125105

@@ -129,10 +109,10 @@ class SAOPass extends Pass {
129109
vertexShader: DepthLimitedBlurShader.vertexShader,
130110
fragmentShader: DepthLimitedBlurShader.fragmentShader
131111
} );
132-
this.hBlurMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
112+
this.hBlurMaterial.defines[ 'DEPTH_PACKING' ] = 0;
133113
this.hBlurMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
134114
this.hBlurMaterial.uniforms[ 'tDiffuse' ].value = this.blurIntermediateRenderTarget.texture;
135-
this.hBlurMaterial.uniforms[ 'tDepth' ].value = ( this.supportsDepthTextureExtension ) ? depthTexture : this.depthRenderTarget.texture;
115+
this.hBlurMaterial.uniforms[ 'tDepth' ].value = depthTexture;
136116
this.hBlurMaterial.uniforms[ 'size' ].value.set( this.resolution.x, this.resolution.y );
137117
this.hBlurMaterial.blending = NoBlending;
138118

@@ -153,13 +133,6 @@ class SAOPass extends Pass {
153133
this.materialCopy.blendDstAlpha = ZeroFactor;
154134
this.materialCopy.blendEquationAlpha = AddEquation;
155135

156-
this.depthCopy = new ShaderMaterial( {
157-
uniforms: UniformsUtils.clone( UnpackDepthRGBAShader.uniforms ),
158-
vertexShader: UnpackDepthRGBAShader.vertexShader,
159-
fragmentShader: UnpackDepthRGBAShader.fragmentShader,
160-
blending: NoBlending
161-
} );
162-
163136
this.fsQuad = new FullScreenQuad( null );
164137

165138
}
@@ -176,20 +149,11 @@ class SAOPass extends Pass {
176149

177150
}
178151

179-
if ( this.params.output === 1 ) {
180-
181-
return;
182-
183-
}
184-
185152
renderer.getClearColor( this._oldClearColor );
186153
this.oldClearAlpha = renderer.getClearAlpha();
187154
const oldAutoClear = renderer.autoClear;
188155
renderer.autoClear = false;
189156

190-
renderer.setRenderTarget( this.depthRenderTarget );
191-
renderer.clear();
192-
193157
this.saoMaterial.uniforms[ 'bias' ].value = this.params.saoBias;
194158
this.saoMaterial.uniforms[ 'intensity' ].value = this.params.saoIntensity;
195159
this.saoMaterial.uniforms[ 'scale' ].value = this.params.saoScale;
@@ -218,26 +182,8 @@ class SAOPass extends Pass {
218182

219183
}
220184

221-
// Rendering scene to depth texture
222-
renderer.setClearColor( 0x000000 );
223-
renderer.setRenderTarget( this.beautyRenderTarget );
224-
renderer.clear();
225-
renderer.render( this.scene, this.camera );
226-
227-
// Re-render scene if depth texture extension is not supported
228-
if ( ! this.supportsDepthTextureExtension ) {
229-
230-
// Clear rule : far clipping plane in both RGBA and Basic encoding
231-
this.renderOverride( renderer, this.depthMaterial, this.depthRenderTarget, 0x000000, 1.0 );
232-
233-
}
234-
235-
if ( this.supportsNormalTexture ) {
236-
237-
// Clear rule : default normal is facing the camera
238-
this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 );
239-
240-
}
185+
// render normal and depth
186+
this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 );
241187

242188
// Rendering SAO texture
243189
this.renderPass( renderer, this.saoMaterial, this.saoRenderTarget, 0xffffff, 1.0 );
@@ -250,24 +196,10 @@ class SAOPass extends Pass {
250196

251197
}
252198

253-
let outputMaterial = this.materialCopy;
254-
// Setting up SAO rendering
255-
if ( this.params.output === 3 ) {
256-
257-
if ( this.supportsDepthTextureExtension ) {
258-
259-
this.materialCopy.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.depthTexture;
260-
this.materialCopy.needsUpdate = true;
199+
const outputMaterial = this.materialCopy;
261200

262-
} else {
263-
264-
this.depthCopy.uniforms[ 'tDiffuse' ].value = this.depthRenderTarget.texture;
265-
this.depthCopy.needsUpdate = true;
266-
outputMaterial = this.depthCopy;
267-
268-
}
269-
270-
} else if ( this.params.output === 4 ) {
201+
// Setting up SAO rendering
202+
if ( this.params.output === SAOPass.OUTPUT.Normal ) {
271203

272204
this.materialCopy.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
273205
this.materialCopy.needsUpdate = true;
@@ -279,8 +211,8 @@ class SAOPass extends Pass {
279211

280212
}
281213

282-
// Blending depends on output, only want a CustomBlending when showing SAO
283-
if ( this.params.output === 0 ) {
214+
// Blending depends on output
215+
if ( this.params.output === SAOPass.OUTPUT.Default ) {
284216

285217
outputMaterial.blending = CustomBlending;
286218

@@ -359,11 +291,9 @@ class SAOPass extends Pass {
359291

360292
setSize( width, height ) {
361293

362-
this.beautyRenderTarget.setSize( width, height );
363294
this.saoRenderTarget.setSize( width, height );
364295
this.blurIntermediateRenderTarget.setSize( width, height );
365296
this.normalRenderTarget.setSize( width, height );
366-
this.depthRenderTarget.setSize( width, height );
367297

368298
this.saoMaterial.uniforms[ 'size' ].value.set( width, height );
369299
this.saoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
@@ -382,17 +312,14 @@ class SAOPass extends Pass {
382312

383313
this.saoRenderTarget.dispose();
384314
this.blurIntermediateRenderTarget.dispose();
385-
this.beautyRenderTarget.dispose();
386315
this.normalRenderTarget.dispose();
387-
this.depthRenderTarget.dispose();
388316

389317
this.depthMaterial.dispose();
390318
this.normalMaterial.dispose();
391319
this.saoMaterial.dispose();
392320
this.vBlurMaterial.dispose();
393321
this.hBlurMaterial.dispose();
394322
this.materialCopy.dispose();
395-
this.depthCopy.dispose();
396323

397324
this.fsQuad.dispose();
398325

@@ -401,11 +328,9 @@ class SAOPass extends Pass {
401328
}
402329

403330
SAOPass.OUTPUT = {
404-
'Beauty': 1,
405331
'Default': 0,
406-
'SAO': 2,
407-
'Depth': 3,
408-
'Normal': 4
332+
'SAO': 1,
333+
'Normal': 2
409334
};
410335

411336
export { SAOPass };

examples/jsm/shaders/SAOShader.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ const SAOShader = {
1111
defines: {
1212
'NUM_SAMPLES': 7,
1313
'NUM_RINGS': 4,
14-
'NORMAL_TEXTURE': 0,
1514
'DIFFUSE_TEXTURE': 0,
16-
'DEPTH_PACKING': 1,
1715
'PERSPECTIVE_CAMERA': 1
1816
},
1917
uniforms: {
@@ -56,10 +54,7 @@ const SAOShader = {
5654
#endif
5755
5856
uniform sampler2D tDepth;
59-
60-
#if NORMAL_TEXTURE == 1
6157
uniform sampler2D tNormal;
62-
#endif
6358
6459
uniform float cameraNear;
6560
uniform float cameraFar;
@@ -87,11 +82,7 @@ const SAOShader = {
8782
}
8883
8984
float getDepth( const in vec2 screenPosition ) {
90-
#if DEPTH_PACKING == 1
91-
return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );
92-
#else
9385
return texture2D( tDepth, screenPosition ).x;
94-
#endif
9586
}
9687
9788
float getViewZ( const in float depth ) {
@@ -111,11 +102,7 @@ const SAOShader = {
111102
}
112103
113104
vec3 getViewNormal( const in vec3 viewPosition, const in vec2 screenPosition ) {
114-
#if NORMAL_TEXTURE == 1
115105
return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );
116-
#else
117-
return normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) );
118-
#endif
119106
}
120107
121108
float scaleDividedByCameraFar;
30 Bytes
Loading

examples/webgl_postprocessing_sao.html

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,11 @@
5050
container = document.createElement( 'div' );
5151
document.body.appendChild( container );
5252

53-
const width = window.innerWidth || 1;
54-
const height = window.innerHeight || 1;
55-
const devicePixelRatio = window.devicePixelRatio || 1;
53+
const width = window.innerWidth;
54+
const height = window.innerHeight;
5655

5756
renderer = new THREE.WebGLRenderer( { antialias: true } );
58-
renderer.setClearColor( 0x000000 );
59-
renderer.setPixelRatio( devicePixelRatio );
57+
renderer.setPixelRatio( window.devicePixelRatio );
6058
renderer.setSize( width, height );
6159
document.body.appendChild( renderer.domElement );
6260

@@ -117,18 +115,16 @@
117115
composer = new EffectComposer( renderer );
118116
renderPass = new RenderPass( scene, camera );
119117
composer.addPass( renderPass );
120-
saoPass = new SAOPass( scene, camera, false, true );
118+
saoPass = new SAOPass( scene, camera );
121119
composer.addPass( saoPass );
122120
const outputPass = new OutputPass();
123121
composer.addPass( outputPass );
124122

125123
// Init gui
126124
const gui = new GUI();
127125
gui.add( saoPass.params, 'output', {
128-
'Beauty': SAOPass.OUTPUT.Beauty,
129-
'Beauty+SAO': SAOPass.OUTPUT.Default,
130-
'SAO': SAOPass.OUTPUT.SAO,
131-
'Depth': SAOPass.OUTPUT.Depth,
126+
'Default': SAOPass.OUTPUT.Default,
127+
'SAO Only': SAOPass.OUTPUT.SAO,
132128
'Normal': SAOPass.OUTPUT.Normal
133129
} ).onChange( function ( value ) {
134130

@@ -144,6 +140,7 @@
144140
gui.add( saoPass.params, 'saoBlurRadius', 0, 200 );
145141
gui.add( saoPass.params, 'saoBlurStdDev', 0.5, 150 );
146142
gui.add( saoPass.params, 'saoBlurDepthCutoff', 0.0, 0.1 );
143+
gui.add( saoPass, 'enabled' );
147144

148145
window.addEventListener( 'resize', onWindowResize );
149146

0 commit comments

Comments
 (0)