diff --git a/dependencies/CopyShader.js b/dependencies/CopyShader.js new file mode 100644 index 0000000000000000000000000000000000000000..9843a42fc4c2d2429ea217fc193dd58b1e68f0f8 --- /dev/null +++ b/dependencies/CopyShader.js @@ -0,0 +1,46 @@ +/** + * @author alteredq / http://alteredqualia.com/ + * + * Full-screen textured quad shader + */ + +THREE.CopyShader = { + + uniforms: { + + "tDiffuse": { value: null }, + "opacity": { value: 1.0 } + + }, + + vertexShader: [ + + "varying vec2 vUv;", + + "void main() {", + + "vUv = uv;", + "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + + "}" + + ].join( "\n" ), + + fragmentShader: [ + + "uniform float opacity;", + + "uniform sampler2D tDiffuse;", + + "varying vec2 vUv;", + + "void main() {", + + "vec4 texel = texture2D( tDiffuse, vUv );", + "gl_FragColor = opacity * texel;", + + "}" + + ].join( "\n" ) + +}; diff --git a/dependencies/Detector.js b/dependencies/Detector.js new file mode 100644 index 0000000000000000000000000000000000000000..95a2724cc94cb45c236e257625ccf0887f7cc335 --- /dev/null +++ b/dependencies/Detector.js @@ -0,0 +1,78 @@ +/** + * @author alteredq / http://alteredqualia.com/ + * @author mr.doob / http://mrdoob.com/ + */ + +var Detector = { + + canvas: !! window.CanvasRenderingContext2D, + webgl: ( function () { + + try { + + var canvas = document.createElement( 'canvas' ); return !! ( window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ) ); + + } catch ( e ) { + + return false; + + } + + } )(), + workers: !! window.Worker, + fileapi: window.File && window.FileReader && window.FileList && window.Blob, + + getWebGLErrorMessage: function () { + + var element = document.createElement( 'div' ); + element.id = 'webgl-error-message'; + element.style.fontFamily = 'monospace'; + element.style.fontSize = '13px'; + element.style.fontWeight = 'normal'; + element.style.textAlign = 'center'; + element.style.background = '#fff'; + element.style.color = '#000'; + element.style.padding = '1.5em'; + element.style.width = '400px'; + element.style.margin = '5em auto 0'; + + if ( ! this.webgl ) { + + element.innerHTML = window.WebGLRenderingContext ? [ + 'Your graphics card does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br />', + 'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.' + ].join( '\n' ) : [ + 'Your browser does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br/>', + 'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.' + ].join( '\n' ); + + } + + return element; + + }, + + addGetWebGLMessage: function ( parameters ) { + + var parent, id, element; + + parameters = parameters || {}; + + parent = parameters.parent !== undefined ? parameters.parent : document.body; + id = parameters.id !== undefined ? parameters.id : 'oldie'; + + element = Detector.getWebGLErrorMessage(); + element.id = id; + + parent.appendChild( element ); + + } + +}; + +// browserify support +if ( typeof module === 'object' ) { + + module.exports = Detector; + +} diff --git a/dependencies/EffectComposer.js b/dependencies/EffectComposer.js new file mode 100644 index 0000000000000000000000000000000000000000..ac0048c4b8719a67aabbc2e68050f403b03551b0 --- /dev/null +++ b/dependencies/EffectComposer.js @@ -0,0 +1,175 @@ +/** + * @author alteredq / http://alteredqualia.com/ + */ + +THREE.EffectComposer = function ( renderer, renderTarget ) { + + this.renderer = renderer; + + if ( renderTarget === undefined ) { + + var parameters = { + minFilter: THREE.LinearFilter, + magFilter: THREE.LinearFilter, + format: THREE.RGBAFormat, + stencilBuffer: false + }; + var size = renderer.getSize(); + renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters ); + + } + + this.renderTarget1 = renderTarget; + this.renderTarget2 = renderTarget.clone(); + + this.writeBuffer = this.renderTarget1; + this.readBuffer = this.renderTarget2; + + this.passes = []; + + if ( THREE.CopyShader === undefined ) + console.error( "THREE.EffectComposer relies on THREE.CopyShader" ); + + this.copyPass = new THREE.ShaderPass( THREE.CopyShader ); + +}; + +Object.assign( THREE.EffectComposer.prototype, { + + swapBuffers: function() { + + var tmp = this.readBuffer; + this.readBuffer = this.writeBuffer; + this.writeBuffer = tmp; + + }, + + addPass: function ( pass ) { + + this.passes.push( pass ); + + var size = this.renderer.getSize(); + pass.setSize( size.width, size.height ); + + }, + + insertPass: function ( pass, index ) { + + this.passes.splice( index, 0, pass ); + + }, + + render: function ( delta ) { + + var maskActive = false; + + var pass, i, il = this.passes.length; + + for ( i = 0; i < il; i ++ ) { + + pass = this.passes[ i ]; + + if ( pass.enabled === false ) continue; + + pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); + + if ( pass.needsSwap ) { + + if ( maskActive ) { + + var context = this.renderer.context; + + context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); + + this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); + + context.stencilFunc( context.EQUAL, 1, 0xffffffff ); + + } + + this.swapBuffers(); + + } + + if ( THREE.MaskPass !== undefined ) { + + if ( pass instanceof THREE.MaskPass ) { + + maskActive = true; + + } else if ( pass instanceof THREE.ClearMaskPass ) { + + maskActive = false; + + } + + } + + } + + }, + + reset: function ( renderTarget ) { + + if ( renderTarget === undefined ) { + + var size = this.renderer.getSize(); + + renderTarget = this.renderTarget1.clone(); + renderTarget.setSize( size.width, size.height ); + + } + + this.renderTarget1.dispose(); + this.renderTarget2.dispose(); + this.renderTarget1 = renderTarget; + this.renderTarget2 = renderTarget.clone(); + + this.writeBuffer = this.renderTarget1; + this.readBuffer = this.renderTarget2; + + }, + + setSize: function ( width, height ) { + + this.renderTarget1.setSize( width, height ); + this.renderTarget2.setSize( width, height ); + + for ( var i = 0; i < this.passes.length; i ++ ) { + + this.passes[i].setSize( width, height ); + + } + + } + +} ); + + +THREE.Pass = function () { + + // if set to true, the pass is processed by the composer + this.enabled = true; + + // if set to true, the pass indicates to swap read and write buffer after rendering + this.needsSwap = true; + + // if set to true, the pass clears its buffer before rendering + this.clear = false; + + // if set to true, the result of the pass is rendered to screen + this.renderToScreen = false; + +}; + +Object.assign( THREE.Pass.prototype, { + + setSize: function( width, height ) {}, + + render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { + + console.error( "THREE.Pass: .render() must be implemented in derived pass." ); + + } + +} ); diff --git a/dependencies/MaskPass.js b/dependencies/MaskPass.js new file mode 100644 index 0000000000000000000000000000000000000000..7c382aa103ff5d38e4ff14099f17774960089a02 --- /dev/null +++ b/dependencies/MaskPass.js @@ -0,0 +1,98 @@ +/** + * @author alteredq / http://alteredqualia.com/ + */ + +THREE.MaskPass = function ( scene, camera ) { + + THREE.Pass.call( this ); + + this.scene = scene; + this.camera = camera; + + this.clear = true; + this.needsSwap = false; + + this.inverse = false; + +}; + +THREE.MaskPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { + + constructor: THREE.MaskPass, + + render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { + + var context = renderer.context; + var state = renderer.state; + + // don't update color or depth + + state.buffers.color.setMask( false ); + state.buffers.depth.setMask( false ); + + // lock buffers + + state.buffers.color.setLocked( true ); + state.buffers.depth.setLocked( true ); + + // set up stencil + + var writeValue, clearValue; + + if ( this.inverse ) { + + writeValue = 0; + clearValue = 1; + + } else { + + writeValue = 1; + clearValue = 0; + + } + + state.buffers.stencil.setTest( true ); + state.buffers.stencil.setOp( context.REPLACE, context.REPLACE, context.REPLACE ); + state.buffers.stencil.setFunc( context.ALWAYS, writeValue, 0xffffffff ); + state.buffers.stencil.setClear( clearValue ); + + // draw into the stencil buffer + + renderer.render( this.scene, this.camera, readBuffer, this.clear ); + renderer.render( this.scene, this.camera, writeBuffer, this.clear ); + + // unlock color and depth buffer for subsequent rendering + + state.buffers.color.setLocked( false ); + state.buffers.depth.setLocked( false ); + + // only render where stencil is set to 1 + + state.buffers.stencil.setFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1 + state.buffers.stencil.setOp( context.KEEP, context.KEEP, context.KEEP ); + + } + +} ); + + +THREE.ClearMaskPass = function () { + + THREE.Pass.call( this ); + + this.needsSwap = false; + +}; + +THREE.ClearMaskPass.prototype = Object.create( THREE.Pass.prototype ); + +Object.assign( THREE.ClearMaskPass.prototype, { + + render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { + + renderer.state.buffers.stencil.setTest( false ); + + } + +} ); + diff --git a/dependencies/RenderPass.js b/dependencies/RenderPass.js new file mode 100644 index 0000000000000000000000000000000000000000..2711be7b552514de61a2fb408c28ea3a06df7ce8 --- /dev/null +++ b/dependencies/RenderPass.js @@ -0,0 +1,63 @@ +/** + * @author alteredq / http://alteredqualia.com/ + */ + +THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) { + + THREE.Pass.call( this ); + + this.scene = scene; + this.camera = camera; + + this.overrideMaterial = overrideMaterial; + + this.clearColor = clearColor; + this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0; + + this.clear = true; + this.clearDepth = false; + this.needsSwap = false; + +}; + +THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { + + constructor: THREE.RenderPass, + + render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { + + var oldAutoClear = renderer.autoClear; + renderer.autoClear = false; + + this.scene.overrideMaterial = this.overrideMaterial; + + var oldClearColor, oldClearAlpha; + + if ( this.clearColor ) { + + oldClearColor = renderer.getClearColor().getHex(); + oldClearAlpha = renderer.getClearAlpha(); + + renderer.setClearColor( this.clearColor, this.clearAlpha ); + + } + + if ( this.clearDepth ) { + + renderer.clearDepth(); + + } + + renderer.render( this.scene, this.camera, this.renderToScreen ? null : readBuffer, this.clear ); + + if ( this.clearColor ) { + + renderer.setClearColor( oldClearColor, oldClearAlpha ); + + } + + this.scene.overrideMaterial = null; + renderer.autoClear = oldAutoClear; + } + +} ); diff --git a/dependencies/SSAOShader.js b/dependencies/SSAOShader.js new file mode 100644 index 0000000000000000000000000000000000000000..c786f6075bda9db5722d6fd229f5887b6f7725a1 --- /dev/null +++ b/dependencies/SSAOShader.js @@ -0,0 +1,233 @@ +/** + * @author alteredq / http://alteredqualia.com/ + * + * Screen-space ambient occlusion shader + * - ported from + * SSAO GLSL shader v1.2 + * assembled by Martins Upitis (martinsh) (http://devlog-martinsh.blogspot.com) + * original technique is made by ArKano22 (http://www.gamedev.net/topic/550699-ssao-no-halo-artifacts/) + * - modifications + * - modified to use RGBA packed depth texture (use clear color 1,1,1,1 for depth pass) + * - refactoring and optimizations + */ + +THREE.SSAOShader = { + + uniforms: { + + "tDiffuse": { value: null }, + "tDepth": { value: null }, + "size": { value: new THREE.Vector2( 512, 512 ) }, + "cameraNear": { value: 1 }, + "cameraFar": { value: 100 }, + "onlyAO": { value: 0 }, + "aoClamp": { value: 0.5 }, + "lumInfluence": { value: 0.5 } + + }, + + vertexShader: [ + + "varying vec2 vUv;", + + "void main() {", + + "vUv = uv;", + + "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + + "}" + + ].join( "\n" ), + + fragmentShader: [ + + "uniform float cameraNear;", + "uniform float cameraFar;", + "#ifdef USE_LOGDEPTHBUF", + "uniform float logDepthBufFC;", + "#endif", + + "uniform bool onlyAO;", // use only ambient occlusion pass? + + "uniform vec2 size;", // texture width, height + "uniform float aoClamp;", // depth clamp - reduces haloing at screen edges + + "uniform float lumInfluence;", // how much luminance affects occlusion + + "uniform sampler2D tDiffuse;", + "uniform sampler2D tDepth;", + + "varying vec2 vUv;", + + // "#define PI 3.14159265", + "#define DL 2.399963229728653", // PI * ( 3.0 - sqrt( 5.0 ) ) + "#define EULER 2.718281828459045", + + // user variables + + "const int samples = 8;", // ao sample count + "const float radius = 5.0;", // ao radius + + "const bool useNoise = false;", // use noise instead of pattern for sample dithering + "const float noiseAmount = 0.0003;", // dithering amount + + "const float diffArea = 0.4;", // self-shadowing reduction + "const float gDisplace = 0.4;", // gauss bell center + + + // RGBA depth + + "#include <packing>", + + // generating noise / pattern texture for dithering + + "vec2 rand( const vec2 coord ) {", + + "vec2 noise;", + + "if ( useNoise ) {", + + "float nx = dot ( coord, vec2( 12.9898, 78.233 ) );", + "float ny = dot ( coord, vec2( 12.9898, 78.233 ) * 2.0 );", + + "noise = clamp( fract ( 43758.5453 * sin( vec2( nx, ny ) ) ), 0.0, 1.0 );", + + "} else {", + + "float ff = fract( 1.0 - coord.s * ( size.x / 2.0 ) );", + "float gg = fract( coord.t * ( size.y / 2.0 ) );", + + "noise = vec2( 0.25, 0.75 ) * vec2( ff ) + vec2( 0.75, 0.25 ) * gg;", + + "}", + + "return ( noise * 2.0 - 1.0 ) * noiseAmount;", + + "}", + + "float readDepth( const in vec2 coord ) {", + + "float cameraFarPlusNear = cameraFar + cameraNear;", + "float cameraFarMinusNear = cameraFar - cameraNear;", + "float cameraCoef = 2.0 * cameraNear;", + + "#ifdef USE_LOGDEPTHBUF", + + "float logz = unpackRGBAToDepth( texture2D( tDepth, coord ) );", + "float w = pow(2.0, (logz / logDepthBufFC)) - 1.0;", + "float z = (logz / w) + 1.0;", + + "#else", + + "float z = unpackRGBAToDepth( texture2D( tDepth, coord ) );", + + "#endif", + + "return cameraCoef / ( cameraFarPlusNear - z * cameraFarMinusNear );", + + + "}", + + "float compareDepths( const in float depth1, const in float depth2, inout int far ) {", + + "float garea = 2.0;", // gauss bell width + "float diff = ( depth1 - depth2 ) * 100.0;", // depth difference (0-100) + + // reduce left bell width to avoid self-shadowing + + "if ( diff < gDisplace ) {", + + "garea = diffArea;", + + "} else {", + + "far = 1;", + + "}", + + "float dd = diff - gDisplace;", + "float gauss = pow( EULER, -2.0 * dd * dd / ( garea * garea ) );", + "return gauss;", + + "}", + + "float calcAO( float depth, float dw, float dh ) {", + + "float dd = radius - depth * radius;", + "vec2 vv = vec2( dw, dh );", + + "vec2 coord1 = vUv + dd * vv;", + "vec2 coord2 = vUv - dd * vv;", + + "float temp1 = 0.0;", + "float temp2 = 0.0;", + + "int far = 0;", + "temp1 = compareDepths( depth, readDepth( coord1 ), far );", + + // DEPTH EXTRAPOLATION + + "if ( far > 0 ) {", + + "temp2 = compareDepths( readDepth( coord2 ), depth, far );", + "temp1 += ( 1.0 - temp1 ) * temp2;", + + "}", + + "return temp1;", + + "}", + + "void main() {", + + "vec2 noise = rand( vUv );", + "float depth = readDepth( vUv );", + + "float tt = clamp( depth, aoClamp, 1.0 );", + + "float w = ( 1.0 / size.x ) / tt + ( noise.x * ( 1.0 - noise.x ) );", + "float h = ( 1.0 / size.y ) / tt + ( noise.y * ( 1.0 - noise.y ) );", + + "float ao = 0.0;", + + "float dz = 1.0 / float( samples );", + "float z = 1.0 - dz / 2.0;", + "float l = 0.0;", + + "for ( int i = 0; i <= samples; i ++ ) {", + + "float r = sqrt( 1.0 - z );", + + "float pw = cos( l ) * r;", + "float ph = sin( l ) * r;", + "ao += calcAO( depth, pw * w, ph * h );", + "z = z - dz;", + "l = l + DL;", + + "}", + + "ao /= float( samples );", + "ao = 1.0 - ao;", + + "vec3 color = texture2D( tDiffuse, vUv ).rgb;", + + "vec3 lumcoeff = vec3( 0.299, 0.587, 0.114 );", + "float lum = dot( color.rgb, lumcoeff );", + "vec3 luminance = vec3( lum );", + + "vec3 final = vec3( color * mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // mix( color * ao, white, luminance ) + + "if ( onlyAO ) {", + + "final = vec3( mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );", // ambient occlusion only + + "}", + + "gl_FragColor = vec4( final, 1.0 );", + + "}" + + ].join( "\n" ) + +}; diff --git a/dependencies/ShaderPass.js b/dependencies/ShaderPass.js new file mode 100644 index 0000000000000000000000000000000000000000..d42d20692a992fc96075f34fc5dac385cfbaa0da --- /dev/null +++ b/dependencies/ShaderPass.js @@ -0,0 +1,67 @@ +/** + * @author alteredq / http://alteredqualia.com/ + */ + +THREE.ShaderPass = function ( shader, textureID ) { + + THREE.Pass.call( this ); + + this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse"; + + if ( shader instanceof THREE.ShaderMaterial ) { + + this.uniforms = shader.uniforms; + + this.material = shader; + + } else if ( shader ) { + + this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); + + this.material = new THREE.ShaderMaterial( { + + defines: shader.defines || {}, + uniforms: this.uniforms, + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader + + } ); + + } + + this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); + this.scene = new THREE.Scene(); + + this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null ); + this.quad.frustumCulled = false; // Avoid getting clipped + this.scene.add( this.quad ); + +}; + +THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { + + constructor: THREE.ShaderPass, + + render: function( renderer, writeBuffer, readBuffer, delta, maskActive ) { + + if ( this.uniforms[ this.textureID ] ) { + + this.uniforms[ this.textureID ].value = readBuffer.texture; + + } + + this.quad.material = this.material; + + if ( this.renderToScreen ) { + + renderer.render( this.scene, this.camera ); + + } else { + + renderer.render( this.scene, this.camera, writeBuffer, this.clear ); + + } + + } + +} ); diff --git a/index.html b/index.html index 8c5d62ef6022895880c6fedbc2f41bc4d6c738eb..063155efbc964950404636b498cec18c22242e5b 100644 --- a/index.html +++ b/index.html @@ -334,6 +334,14 @@ <script type="text/javascript" src="dependencies/earcut.js"></script> <script type="text/javascript" src="dependencies/numeric-1.2.6.js"></script> + <script type="text/javascript" src="dependencies/EffectComposer.js"></script> + <script type="text/javascript" src="dependencies/MaskPass.js"></script> + <script type="text/javascript" src="dependencies/ShaderPass.js"></script> + <script type="text/javascript" src="dependencies/CopyShader.js"></script> + <script type="text/javascript" src="dependencies/SSAOShader.js"></script> + <script type="text/javascript" src="dependencies/Detector.js"></script> + <script type="text/javascript" src="dependencies/RenderPass.js"></script> + <script type="text/javascript" src="js/dynamic/GLBoilerplate.js"></script> <script type="text/javascript" src="js/dynamic/GPUMath.js"></script> <script type="text/javascript" src="js/controls.js"></script> diff --git a/js/globals.js b/js/globals.js index 60916573e7b7cbca191c07ab3b77b10c03d9c146..3a6e0696cd08dde94af6fdddd9bbc8e0ab37d160 100644 --- a/js/globals.js +++ b/js/globals.js @@ -15,7 +15,7 @@ function initGlobals(){ color2: "dddddd", edgesVisible: true, meshVisible: true, - ambientOcclusion: false, + ambientOcclusion: true, //flags fixedHasChanged: false, diff --git a/js/threeView.js b/js/threeView.js index ac1ce4ecbf414cbe763d5e5e4d7435cd16fcd5f7..1b10007e874f24ca03c235e62bf6b3f81a478884 100644 --- a/js/threeView.js +++ b/js/threeView.js @@ -10,6 +10,9 @@ function initThreeView(globals) { var renderer = new THREE.WebGLRenderer({antialias: true}); var controls; + var depthMaterial, effectComposer, depthRenderTarget; + var ssaoPass; + var animationRunning = false; var pauseFlag = false; @@ -58,6 +61,32 @@ function initThreeView(globals) { controls.noPan = true; controls.staticMoving = true; controls.dynamicDampingFactor = 0.3; + + var renderPass = new THREE.RenderPass( scene, camera ); + + // Setup depth pass + depthMaterial = new THREE.MeshDepthMaterial(); + depthMaterial.depthPacking = THREE.RGBADepthPacking; + depthMaterial.blending = THREE.NoBlending; + + var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter }; + depthRenderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, pars ); + + // Setup SSAO pass + ssaoPass = new THREE.ShaderPass( THREE.SSAOShader ); + ssaoPass.renderToScreen = true; + //ssaoPass.uniforms[ "tDiffuse" ].value will be set by ShaderPass + ssaoPass.uniforms[ "tDepth" ].value = depthRenderTarget.texture; + ssaoPass.uniforms[ 'size' ].value.set( window.innerWidth, window.innerHeight ); + ssaoPass.uniforms[ 'cameraNear' ].value = camera.near; + ssaoPass.uniforms[ 'cameraFar' ].value = camera.far; + ssaoPass.uniforms[ 'onlyAO' ].value = 0; + ssaoPass.uniforms[ 'aoClamp' ].value = 0.7; + ssaoPass.uniforms[ 'lumInfluence' ].value = 0.8; + // Add pass to effect composer + effectComposer = new THREE.EffectComposer( renderer ); + effectComposer.addPass( renderPass ); + effectComposer.addPass( ssaoPass ); } function render() { @@ -85,7 +114,16 @@ function initThreeView(globals) { } function _render(){ - renderer.render(scene, camera); + if (globals.ambientOcclusion) { + // Render depth into depthRenderTarget + scene.overrideMaterial = depthMaterial; + renderer.render(scene, camera, depthRenderTarget, true); + // Render renderPass and SSAO shaderPass + scene.overrideMaterial = null; + effectComposer.render(); + } else { + renderer.render(scene, camera); + } } function _loop(callback){ @@ -102,18 +140,6 @@ function initThreeView(globals) { }); } - function sceneAddPattern(object) { - patternWrapper.add(object); - } - - function sceneRemovePattern(object) { - patternWrapper.remove(object); - } - - function sceneClearPattern() { - patternWrapper.children = []; - } - function sceneAddModel(object){//beams and nodes modelWrapper.add(object); } @@ -132,6 +158,13 @@ function initThreeView(globals) { renderer.setSize(window.innerWidth, window.innerHeight); + 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 ); + render(); }