webgl_postprocessing_ssao.html 6.4 KB
Newer Older
D
Daosheng Mu 已提交
1 2
<!DOCTYPE html>

M
Mr.doob 已提交
3
<!--Reference:
D
Daosheng Mu 已提交
4 5 6 7 8 9
SSAO algo: http://devlog-martinsh.blogspot.tw/2011/12/ssao-shader-update-v12.html?showComment=1398158188712#c1563204765906693531
log depth http://outerra.blogspot.tw/2013/07/logarithmic-depth-buffer-optimizations.html
convert the exponential depth to a linear value: http://www.ozone3d.net/blogs/lab/20090206/how-to-linearize-the-depth-value/
Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere-->

<html lang="en">
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
	<head>
		<title>three.js webgl - postprocessing - Screen Space Ambient Occlusion</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				background-color: #000000;
				margin: 0px;
				overflow: hidden;
				font-family:Monospace;
				font-size:13px;
				text-align:center;
				font-weight: bold;
			}

			a {
M
Mr.doob 已提交
26
				color:#00ff78;
27 28 29
			}

			#info {
M
Mr.doob 已提交
30 31
				color: #fff;
				position: absolute;
32
				top: 0px;
M
Mr.doob 已提交
33
				width: 100%;
34
				padding: 5px;
M
Mr.doob 已提交
35 36 37
			}
			.dg.ac {
				z-index: 1 !important; /* FIX DAT.GUI */
38 39 40 41
			}
		</style>
	</head>
	<body>
W
WestLangley 已提交
42
		<script src="../build/three.js"></script>
43

44
		<script src="js/shaders/SSAOShader.js"></script>
D
Daosheng Mu 已提交
45
		<script src="js/shaders/CopyShader.js"></script>
46 47

		<script src="js/postprocessing/EffectComposer.js"></script>
48 49
		<script src="js/postprocessing/RenderPass.js"></script>
		<script src="js/postprocessing/ShaderPass.js"></script>
D
Daosheng Mu 已提交
50
		<script src="js/postprocessing/MaskPass.js"></script>
51

52 53 54 55 56
		<script src="js/Detector.js"></script>
		<script src="js/libs/stats.min.js"></script>
		<script src='js/libs/dat.gui.min.js'></script>

		<div id="info">
57
			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl screen space ambient occlusion example<br/>
M
Mr.doob 已提交
58
			shader by <a href="http://alteredqualia.com">alteredq</a>
59 60 61 62 63
		</div>

		<script>

			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
M
Mr.doob 已提交
64 65

			var container, stats;
D
Daosheng Mu 已提交
66 67
			var camera, scene, renderer;
			var depthMaterial, effectComposer, depthRenderTarget;
68
			var ssaoPass;
69
			var group;
70
			var postprocessing = { enabled: true, ao_only: false, radius: 32 };
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

			init();
			animate();

			function init() {

				container = document.createElement( 'div' );
				document.body.appendChild( container );

				renderer = new THREE.WebGLRenderer( { antialias: false } );
				renderer.setSize( window.innerWidth, window.innerHeight );
				document.body.appendChild( renderer.domElement );

				camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 100, 700 );
				camera.position.z = 500;

				scene = new THREE.Scene();
88
				scene.background = new THREE.Color( 0xa0a0a0 );
89 90 91

				group = new THREE.Object3D();
				scene.add( group );
M
Mr.doob 已提交
92

93
				var geometry = new THREE.BoxGeometry( 10, 10, 10 );
94
				for ( var i = 0; i < 200; i ++ ) {
M
Mr.doob 已提交
95

96 97 98 99
					var material = new THREE.MeshBasicMaterial();
					material.color.r = Math.random();
					material.color.g = Math.random();
					material.color.b = Math.random();
M
Mr.doob 已提交
100

101 102 103 104 105 106 107 108 109 110
					var mesh = new THREE.Mesh( geometry, material );
					mesh.position.x = Math.random() * 400 - 200;
					mesh.position.y = Math.random() * 400 - 200;
					mesh.position.z = Math.random() * 400 - 200;
					mesh.rotation.x = Math.random();
					mesh.rotation.y = Math.random();
					mesh.rotation.z = Math.random();

					mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 10 + 1;
					group.add( mesh );
M
Mr.doob 已提交
111

112
				}
M
Mr.doob 已提交
113

114
				stats = new Stats();
M
Mr.doob 已提交
115
				container.appendChild( stats.dom );
116

M
Mr.doob 已提交
117
				// Init postprocessing
118
				initPostprocessing();
M
Mr.doob 已提交
119

120 121
				// Init gui
				var gui = new dat.GUI();
122 123 124
				gui.add( postprocessing, "enabled" );
				gui.add( postprocessing, "ao_only", false ).onChange( renderModeChange );
				gui.add( postprocessing, "radius" ).min( 0 ).max( 64 ).onChange( radiusChange );
125 126

				window.addEventListener( 'resize', onWindowResize, false );
M
Mr.doob 已提交
127

128 129
			}

130
			function radiusChange( value ) {
M
Mr.doob 已提交
131

132
				ssaoPass.uniforms[ 'radius' ].value = value;
M
Mr.doob 已提交
133

134
			}
M
Mr.doob 已提交
135

136
			function renderModeChange( value ) {
M
Mr.doob 已提交
137

138
				ssaoPass.uniforms[ 'onlyAO' ].value = value;
M
Mr.doob 已提交
139

140
			}
M
Mr.doob 已提交
141

142 143
			function onWindowResize() {

144 145 146 147
				var width = window.innerWidth;
				var height = window.innerHeight;

				camera.aspect = width / height;
148
				camera.updateProjectionMatrix();
149
				renderer.setSize( width, height );
150

D
Daosheng Mu 已提交
151
				// Resize renderTargets
152 153 154 155 156 157 158
				ssaoPass.uniforms[ 'size' ].value.set( width, height );

				var pixelRatio = renderer.getPixelRatio();
				var newWidth  = Math.floor( width / pixelRatio ) || 1;
				var newHeight = Math.floor( height / pixelRatio ) || 1;
				depthRenderTarget.setSize( newWidth, newHeight );
				effectComposer.setSize( newWidth, newHeight );
M
Mr.doob 已提交
159

160 161 162
			}

			function initPostprocessing() {
163 164 165 166 167

				// Setup render pass
				var renderPass = new THREE.RenderPass( scene, camera );

				// Setup depth pass
168 169 170
				depthMaterial = new THREE.MeshDepthMaterial();
				depthMaterial.depthPacking = THREE.RGBADepthPacking;
				depthMaterial.blending = THREE.NoBlending;
M
Mr.doob 已提交
171

M
Mr.doob 已提交
172
				var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter };
173
				depthRenderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, pars );
M
Mr.doob 已提交
174
				depthRenderTarget.texture.name = "SSAOShader.rt";
M
Mr.doob 已提交
175

176 177 178
				// Setup SSAO pass
				ssaoPass = new THREE.ShaderPass( THREE.SSAOShader );
				ssaoPass.renderToScreen = true;
M
Mr.doob 已提交
179
				//ssaoPass.uniforms[ "tDiffuse" ].value will be set by ShaderPass
180
				ssaoPass.uniforms[ "tDepth" ].value = depthRenderTarget.texture;
181 182 183
				ssaoPass.uniforms[ 'size' ].value.set( window.innerWidth, window.innerHeight );
				ssaoPass.uniforms[ 'cameraNear' ].value = camera.near;
				ssaoPass.uniforms[ 'cameraFar' ].value = camera.far;
M
Mr.doob 已提交
184

185 186 187 188
				// Add pass to effect composer
				effectComposer = new THREE.EffectComposer( renderer );
				effectComposer.addPass( renderPass );
				effectComposer.addPass( ssaoPass );
M
Mr.doob 已提交
189

190
			}
M
Mr.doob 已提交
191

192
			function animate() {
M
Mr.doob 已提交
193

194 195
				requestAnimationFrame( animate );

B
Ben Houston 已提交
196
				stats.begin();
197
				render();
B
Ben Houston 已提交
198
				stats.end();
M
Mr.doob 已提交
199

200 201
			}

M
Mr.doob 已提交
202
			function render() {
M
Mr.doob 已提交
203

204 205 206 207 208
				var timer = performance.now();
				group.rotation.x = timer * 0.0002;
				group.rotation.y = timer * 0.0001;

				if ( postprocessing.enabled ) {
M
Mr.doob 已提交
209 210

					// Render depth into depthRenderTarget
211
					scene.overrideMaterial = depthMaterial;
212
					renderer.render( scene, camera, depthRenderTarget, true );
213

214 215 216
					// Render renderPass and SSAO shaderPass
					scene.overrideMaterial = null;
					effectComposer.render();
M
Mr.doob 已提交
217

218
				} else {
M
Mr.doob 已提交
219

220
					renderer.render( scene, camera );
M
Mr.doob 已提交
221

222
				}
M
Mr.doob 已提交
223

224
			}
M
Mr.doob 已提交
225

226 227
		</script>
	</body>
M
Mr.doob 已提交
228
</html>