OSDN Git Service

2e255d98e8abdd57f6b2304796d4f122b5d1472d
[webglgame/webgl_framework.git] / webglFramework / Thirdparty / three.js-master / examples / webgl_postprocessing_ssao.html
1 <!DOCTYPE html>
2
3 <!--Reference:
4 SSAO algo: http://devlog-martinsh.blogspot.tw/2011/12/ssao-shader-update-v12.html?showComment=1398158188712#c1563204765906693531
5 log depth http://outerra.blogspot.tw/2013/07/logarithmic-depth-buffer-optimizations.html
6 convert the exponential depth to a linear value: http://www.ozone3d.net/blogs/lab/20090206/how-to-linearize-the-depth-value/
7 Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere-->
8
9 <html lang="en">
10         <head>
11                 <title>three.js webgl - postprocessing - Screen Space Ambient Occlusion</title>
12                 <meta charset="utf-8">
13                 <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
14                 <style>
15                         body {
16                                 background-color: #000000;
17                                 margin: 0px;
18                                 overflow: hidden;
19                                 font-family:Monospace;
20                                 font-size:13px;
21                                 text-align:center;
22                                 font-weight: bold;
23                         }
24
25                         a {
26                                 color:#00ff78;
27                         }
28
29                         #info {
30                                 color: #fff;
31                                 position: absolute;
32                                 top: 0px;
33                                 width: 100%;
34                                 padding: 5px;
35                         }
36                         .dg.ac {
37                                 z-index: 1 !important; /* FIX DAT.GUI */
38                         }
39                 </style>
40         </head>
41         <body>
42                 <script src="../build/three.js"></script>
43
44                 <script src="js/shaders/SSAOShader.js"></script>
45                 <script src="js/shaders/CopyShader.js"></script>
46
47                 <script src="js/postprocessing/EffectComposer.js"></script>
48                 <script src="js/postprocessing/RenderPass.js"></script>
49                 <script src="js/postprocessing/ShaderPass.js"></script>
50                 <script src="js/postprocessing/MaskPass.js"></script>
51
52                 <script src="js/Detector.js"></script>
53                 <script src="js/libs/stats.min.js"></script>
54                 <script src='js/libs/dat.gui.min.js'></script>
55
56                 <div id="info">
57                         <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl screen space ambient occlusion example<br/>
58                         shader by <a href="http://alteredqualia.com">alteredq</a>
59                 </div>
60
61                 <script>
62
63                         if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
64
65                         var container, stats;
66                         var camera, scene, renderer;
67                         var depthMaterial, effectComposer, depthRenderTarget;
68                         var ssaoPass;
69                         var group;
70                         var postprocessing = { enabled: true, ao_only: false, radius: 32 };
71
72                         init();
73                         animate();
74
75                         function init() {
76
77                                 container = document.createElement( 'div' );
78                                 document.body.appendChild( container );
79
80                                 renderer = new THREE.WebGLRenderer( { antialias: false } );
81                                 renderer.setSize( window.innerWidth, window.innerHeight );
82                                 document.body.appendChild( renderer.domElement );
83
84                                 camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 100, 700 );
85                                 camera.position.z = 500;
86
87                                 scene = new THREE.Scene();
88                                 scene.background = new THREE.Color( 0xa0a0a0 );
89
90                                 group = new THREE.Object3D();
91                                 scene.add( group );
92
93                                 var geometry = new THREE.BoxGeometry( 10, 10, 10 );
94                                 for ( var i = 0; i < 200; i ++ ) {
95
96                                         var material = new THREE.MeshBasicMaterial();
97                                         material.color.r = Math.random();
98                                         material.color.g = Math.random();
99                                         material.color.b = Math.random();
100
101                                         var mesh = new THREE.Mesh( geometry, material );
102                                         mesh.position.x = Math.random() * 400 - 200;
103                                         mesh.position.y = Math.random() * 400 - 200;
104                                         mesh.position.z = Math.random() * 400 - 200;
105                                         mesh.rotation.x = Math.random();
106                                         mesh.rotation.y = Math.random();
107                                         mesh.rotation.z = Math.random();
108
109                                         mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 10 + 1;
110                                         group.add( mesh );
111
112                                 }
113
114                                 stats = new Stats();
115                                 container.appendChild( stats.dom );
116
117                                 // Init postprocessing
118                                 initPostprocessing();
119
120                                 // Init gui
121                                 var gui = new dat.GUI();
122                                 gui.add( postprocessing, "enabled" );
123                                 gui.add( postprocessing, "ao_only", false ).onChange( renderModeChange );
124                                 gui.add( postprocessing, "radius" ).min( 0 ).max( 64 ).onChange( radiusChange );
125
126                                 window.addEventListener( 'resize', onWindowResize, false );
127
128                         }
129
130                         function radiusChange( value ) {
131
132                                 ssaoPass.uniforms[ 'radius' ].value = value;
133
134                         }
135
136                         function renderModeChange( value ) {
137
138                                 ssaoPass.uniforms[ 'onlyAO' ].value = value;
139
140                         }
141
142                         function onWindowResize() {
143
144                                 var width = window.innerWidth;
145                                 var height = window.innerHeight;
146
147                                 camera.aspect = width / height;
148                                 camera.updateProjectionMatrix();
149                                 renderer.setSize( width, height );
150
151                                 // Resize renderTargets
152                                 ssaoPass.uniforms[ 'size' ].value.set( width, height );
153
154                                 var pixelRatio = renderer.getPixelRatio();
155                                 var newWidth  = Math.floor( width / pixelRatio ) || 1;
156                                 var newHeight = Math.floor( height / pixelRatio ) || 1;
157                                 depthRenderTarget.setSize( newWidth, newHeight );
158                                 effectComposer.setSize( newWidth, newHeight );
159
160                         }
161
162                         function initPostprocessing() {
163
164                                 // Setup render pass
165                                 var renderPass = new THREE.RenderPass( scene, camera );
166
167                                 // Setup depth pass
168                                 depthMaterial = new THREE.MeshDepthMaterial();
169                                 depthMaterial.depthPacking = THREE.RGBADepthPacking;
170                                 depthMaterial.blending = THREE.NoBlending;
171
172                                 var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter };
173                                 depthRenderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, pars );
174                                 depthRenderTarget.texture.name = "SSAOShader.rt";
175
176                                 // Setup SSAO pass
177                                 ssaoPass = new THREE.ShaderPass( THREE.SSAOShader );
178                                 ssaoPass.renderToScreen = true;
179                                 //ssaoPass.uniforms[ "tDiffuse" ].value will be set by ShaderPass
180                                 ssaoPass.uniforms[ "tDepth" ].value = depthRenderTarget.texture;
181                                 ssaoPass.uniforms[ 'size' ].value.set( window.innerWidth, window.innerHeight );
182                                 ssaoPass.uniforms[ 'cameraNear' ].value = camera.near;
183                                 ssaoPass.uniforms[ 'cameraFar' ].value = camera.far;
184
185                                 // Add pass to effect composer
186                                 effectComposer = new THREE.EffectComposer( renderer );
187                                 effectComposer.addPass( renderPass );
188                                 effectComposer.addPass( ssaoPass );
189
190                         }
191
192                         function animate() {
193
194                                 requestAnimationFrame( animate );
195
196                                 stats.begin();
197                                 render();
198                                 stats.end();
199
200                         }
201
202                         function render() {
203
204                                 var timer = performance.now();
205                                 group.rotation.x = timer * 0.0002;
206                                 group.rotation.y = timer * 0.0001;
207
208                                 if ( postprocessing.enabled ) {
209
210                                         // Render depth into depthRenderTarget
211                                         scene.overrideMaterial = depthMaterial;
212                                         renderer.render( scene, camera, depthRenderTarget, true );
213
214                                         // Render renderPass and SSAO shaderPass
215                                         scene.overrideMaterial = null;
216                                         effectComposer.render();
217
218                                 } else {
219
220                                         renderer.render( scene, camera );
221
222                                 }
223
224                         }
225
226                 </script>
227         </body>
228 </html>