|
@@ -1,190 +1,375 @@
|
|
|
-'use strict';
|
|
|
-
|
|
|
/**
|
|
|
- * Screen-space ambient occlusion pass.
|
|
|
- *
|
|
|
- * Has the following parameters
|
|
|
- * - radius
|
|
|
- * - Ambient occlusion shadow radius (numeric value).
|
|
|
- * - onlyAO
|
|
|
- * - Display only ambient occlusion result (boolean value).
|
|
|
- * - aoClamp
|
|
|
- * - Ambient occlusion clamp (numeric value).
|
|
|
- * - lumInfluence
|
|
|
- * - Pixel luminosity influence in AO calculation (numeric value).
|
|
|
- *
|
|
|
- * To output to screen set renderToScreens true
|
|
|
- *
|
|
|
- * @author alteredq / http://alteredqualia.com/
|
|
|
- * @author tentone
|
|
|
- * @class SSAOPass
|
|
|
+ * @author Mugen87 / https://github.com/Mugen87
|
|
|
*/
|
|
|
+
|
|
|
THREE.SSAOPass = function ( scene, camera, width, height ) {
|
|
|
|
|
|
+ THREE.Pass.call( this );
|
|
|
+
|
|
|
+ this.width = ( width !== undefined ) ? width : 512;
|
|
|
+ this.height = ( height !== undefined ) ? height : 512;
|
|
|
+
|
|
|
+ this.clear = true;
|
|
|
+
|
|
|
+ this.camera = camera;
|
|
|
+ this.scene = scene;
|
|
|
+
|
|
|
+ this.kernelRadius = 8;
|
|
|
+ this.kernelSize = 64;
|
|
|
+ this.kernel = [];
|
|
|
+ this.noiseTexture = null;
|
|
|
+ this.output = 0;
|
|
|
+
|
|
|
+ this.minDistance = 0.005;
|
|
|
+ this.maxDistance = 0.1;
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ this.generateSampleKernel();
|
|
|
+ this.generateRandomKernelRotations();
|
|
|
+
|
|
|
+ // beauty render target with depth buffer
|
|
|
+
|
|
|
+ var depthTexture = new THREE.DepthTexture();
|
|
|
+ depthTexture.type = THREE.UnsignedShortType;
|
|
|
+ depthTexture.minFilter = THREE.NearestFilter;
|
|
|
+ depthTexture.maxFilter = THREE.NearestFilter;
|
|
|
+
|
|
|
+ this.beautyRenderTarget = new THREE.WebGLRenderTarget( width, height, {
|
|
|
+ minFilter: THREE.LinearFilter,
|
|
|
+ magFilter: THREE.LinearFilter,
|
|
|
+ format: THREE.RGBAFormat,
|
|
|
+ depthTexture: depthTexture,
|
|
|
+ depthBuffer: true
|
|
|
+ } );
|
|
|
+
|
|
|
+ // normal render target
|
|
|
+
|
|
|
+ this.normalRenderTarget = new THREE.WebGLRenderTarget( width, height, {
|
|
|
+ minFilter: THREE.NearestFilter,
|
|
|
+ magFilter: THREE.NearestFilter,
|
|
|
+ format: THREE.RGBAFormat
|
|
|
+ } );
|
|
|
+
|
|
|
+ // ssao render target
|
|
|
+
|
|
|
+ this.ssaoRenderTarget = new THREE.WebGLRenderTarget( width, height, {
|
|
|
+ minFilter: THREE.LinearFilter,
|
|
|
+ magFilter: THREE.LinearFilter,
|
|
|
+ format: THREE.RGBAFormat
|
|
|
+ } );
|
|
|
+
|
|
|
+ this.blurRenderTarget = this.ssaoRenderTarget.clone();
|
|
|
+
|
|
|
+ // ssao material
|
|
|
+
|
|
|
if ( THREE.SSAOShader === undefined ) {
|
|
|
|
|
|
- console.warn( 'THREE.SSAOPass depends on THREE.SSAOShader' );
|
|
|
- return new THREE.ShaderPass();
|
|
|
+ console.error( 'THREE.SSAOPass: The pass relies on THREE.SSAOShader.' );
|
|
|
|
|
|
}
|
|
|
|
|
|
- THREE.ShaderPass.call( this, THREE.SSAOShader );
|
|
|
+ this.ssaoMaterial = new THREE.ShaderMaterial( {
|
|
|
+ defines: Object.assign( {}, THREE.SSAOShader.defines ),
|
|
|
+ uniforms: THREE.UniformsUtils.clone( THREE.SSAOShader.uniforms ),
|
|
|
+ vertexShader: THREE.SSAOShader.vertexShader,
|
|
|
+ fragmentShader: THREE.SSAOShader.fragmentShader,
|
|
|
+ blending: THREE.NoBlending
|
|
|
+ } );
|
|
|
|
|
|
- this.width = ( width !== undefined ) ? width : 512;
|
|
|
- this.height = ( height !== undefined ) ? height : 256;
|
|
|
+ this.ssaoMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
|
|
+ this.ssaoMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
|
|
|
+ this.ssaoMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
|
|
|
+ this.ssaoMaterial.uniforms[ 'tNoise' ].value = this.noiseTexture;
|
|
|
+ this.ssaoMaterial.uniforms[ 'kernel' ].value = this.kernel;
|
|
|
+ this.ssaoMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
|
|
+ this.ssaoMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
|
|
|
+ this.ssaoMaterial.uniforms[ 'resolution' ].value.set( width, height );
|
|
|
+ this.ssaoMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
|
|
|
+ this.ssaoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.getInverse( this.camera.projectionMatrix );
|
|
|
+
|
|
|
+ // normal material
|
|
|
+
|
|
|
+ this.normalMaterial = new THREE.MeshNormalMaterial();
|
|
|
+ this.normalMaterial.blending = THREE.NoBlending;
|
|
|
+
|
|
|
+ // blur material
|
|
|
+
|
|
|
+ this.blurMaterial = new THREE.ShaderMaterial( {
|
|
|
+ defines: Object.assign( {}, THREE.SSAOBlurShader.defines ),
|
|
|
+ uniforms: THREE.UniformsUtils.clone( THREE.SSAOBlurShader.uniforms ),
|
|
|
+ vertexShader: THREE.SSAOBlurShader.vertexShader,
|
|
|
+ fragmentShader: THREE.SSAOBlurShader.fragmentShader
|
|
|
+ } );
|
|
|
+ this.blurMaterial.uniforms[ 'tDiffuse' ].value = this.ssaoRenderTarget.texture;
|
|
|
+ this.blurMaterial.uniforms[ 'resolution' ].value.set( width, height );
|
|
|
|
|
|
- this.renderToScreen = false;
|
|
|
+ // material for rendering the depth
|
|
|
|
|
|
- this.camera2 = camera;
|
|
|
- this.scene2 = scene;
|
|
|
+ this.depthRenderMaterial = new THREE.ShaderMaterial( {
|
|
|
+ defines: Object.assign( {}, THREE.SSAODepthShader.defines ),
|
|
|
+ uniforms: THREE.UniformsUtils.clone( THREE.SSAODepthShader.uniforms ),
|
|
|
+ vertexShader: THREE.SSAODepthShader.vertexShader,
|
|
|
+ fragmentShader: THREE.SSAODepthShader.fragmentShader,
|
|
|
+ blending: THREE.NoBlending
|
|
|
+ } );
|
|
|
+ this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
|
|
|
+ this.depthRenderMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
|
|
|
+ this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
|
|
|
+
|
|
|
+ // material for rendering the content of a render target
|
|
|
+
|
|
|
+ this.copyMaterial = new THREE.ShaderMaterial( {
|
|
|
+ uniforms: THREE.UniformsUtils.clone( THREE.CopyShader.uniforms ),
|
|
|
+ vertexShader: THREE.CopyShader.vertexShader,
|
|
|
+ fragmentShader: THREE.CopyShader.fragmentShader,
|
|
|
+ transparent: true,
|
|
|
+ depthTest: false,
|
|
|
+ depthWrite: false,
|
|
|
+ blendSrc: THREE.DstColorFactor,
|
|
|
+ blendDst: THREE.ZeroFactor,
|
|
|
+ blendEquation: THREE.AddEquation,
|
|
|
+ blendSrcAlpha: THREE.DstAlphaFactor,
|
|
|
+ blendDstAlpha: THREE.ZeroFactor,
|
|
|
+ blendEquationAlpha: THREE.AddEquation
|
|
|
+ } );
|
|
|
|
|
|
- //Depth material
|
|
|
- this.depthMaterial = new THREE.MeshDepthMaterial();
|
|
|
- this.depthMaterial.depthPacking = THREE.RGBADepthPacking;
|
|
|
- this.depthMaterial.blending = THREE.NoBlending;
|
|
|
+ //
|
|
|
|
|
|
- //Depth render target
|
|
|
- this.depthRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter } );
|
|
|
- //this.depthRenderTarget.texture.name = 'SSAOShader.rt';
|
|
|
+ this.quadCamera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
|
|
+ this.quadScene = new THREE.Scene();
|
|
|
+ this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
|
|
|
+ this.quadScene.add( this.quad );
|
|
|
|
|
|
- //Shader uniforms
|
|
|
- this.uniforms[ 'tDepth' ].value = this.depthRenderTarget.texture;
|
|
|
- this.uniforms[ 'size' ].value.set( this.width, this.height );
|
|
|
- this.uniforms[ 'cameraNear' ].value = this.camera2.near;
|
|
|
- this.uniforms[ 'cameraFar' ].value = this.camera2.far;
|
|
|
+};
|
|
|
|
|
|
- this.uniforms[ 'radius' ].value = 4;
|
|
|
- this.uniforms[ 'onlyAO' ].value = false;
|
|
|
- this.uniforms[ 'aoClamp' ].value = 0.25;
|
|
|
- this.uniforms[ 'lumInfluence' ].value = 0.7;
|
|
|
+THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {
|
|
|
|
|
|
- //Setters and getters for uniforms
|
|
|
+ constructor: THREE.SSAOPass,
|
|
|
|
|
|
- Object.defineProperties( this, {
|
|
|
+ render: function ( renderer, writeBuffer /*, readBuffer, delta, maskActive */ ) {
|
|
|
|
|
|
- radius: {
|
|
|
- get: function () {
|
|
|
+ // render beauty and depth
|
|
|
|
|
|
- return this.uniforms[ 'radius' ].value;
|
|
|
+ renderer.setClearColor( 0x000000 );
|
|
|
+ renderer.render( this.scene, this.camera, this.beautyRenderTarget, true );
|
|
|
|
|
|
- },
|
|
|
- set: function ( value ) {
|
|
|
+ // render normals
|
|
|
|
|
|
- this.uniforms[ 'radius' ].value = value;
|
|
|
+ this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 );
|
|
|
|
|
|
- }
|
|
|
- },
|
|
|
+ // render SSAO
|
|
|
|
|
|
- onlyAO: {
|
|
|
- get: function () {
|
|
|
+ this.ssaoMaterial.uniforms[ 'kernelRadius' ].value = this.kernelRadius;
|
|
|
+ this.ssaoMaterial.uniforms[ 'minDistance' ].value = this.minDistance;
|
|
|
+ this.ssaoMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance;
|
|
|
+ this.renderPass( renderer, this.ssaoMaterial, this.ssaoRenderTarget );
|
|
|
|
|
|
- return this.uniforms[ 'onlyAO' ].value;
|
|
|
+ // render blur
|
|
|
|
|
|
- },
|
|
|
- set: function ( value ) {
|
|
|
+ this.renderPass( renderer, this.blurMaterial, this.blurRenderTarget );
|
|
|
|
|
|
- this.uniforms[ 'onlyAO' ].value = value;
|
|
|
+ // output result to screen
|
|
|
|
|
|
- }
|
|
|
- },
|
|
|
+ switch ( this.output ) {
|
|
|
|
|
|
- aoClamp: {
|
|
|
- get: function () {
|
|
|
+ case THREE.SSAOPass.OUTPUT.SSAO:
|
|
|
|
|
|
- return this.uniforms[ 'aoClamp' ].value;
|
|
|
+ this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssaoRenderTarget.texture;
|
|
|
+ this.copyMaterial.blending = THREE.NoBlending;
|
|
|
+ this.renderPass( renderer, this.copyMaterial, null, true );
|
|
|
|
|
|
- },
|
|
|
- set: function ( value ) {
|
|
|
+ break;
|
|
|
|
|
|
- this.uniforms[ 'aoClamp' ].value = value;
|
|
|
+ case THREE.SSAOPass.OUTPUT.Blur:
|
|
|
|
|
|
- }
|
|
|
- },
|
|
|
+ this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture;
|
|
|
+ this.copyMaterial.blending = THREE.NoBlending;
|
|
|
+ this.renderPass( renderer, this.copyMaterial, null, true );
|
|
|
|
|
|
- lumInfluence: {
|
|
|
- get: function () {
|
|
|
+ break;
|
|
|
|
|
|
- return this.uniforms[ 'lumInfluence' ].value;
|
|
|
+ case THREE.SSAOPass.OUTPUT.Beauty:
|
|
|
|
|
|
- },
|
|
|
- set: function ( value ) {
|
|
|
+ this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
|
|
+ this.copyMaterial.blending = THREE.NoBlending;
|
|
|
+ this.renderPass( renderer, this.copyMaterial, null, true );
|
|
|
|
|
|
- this.uniforms[ 'lumInfluence' ].value = value;
|
|
|
+ break;
|
|
|
|
|
|
- }
|
|
|
- },
|
|
|
+ case THREE.SSAOPass.OUTPUT.Depth:
|
|
|
|
|
|
- } );
|
|
|
+ this.renderPass( renderer, this.depthRenderMaterial, null, true );
|
|
|
|
|
|
-};
|
|
|
+ break;
|
|
|
|
|
|
-THREE.SSAOPass.prototype = Object.create( THREE.ShaderPass.prototype );
|
|
|
+ case THREE.SSAOPass.OUTPUT.Normal:
|
|
|
|
|
|
-/**
|
|
|
- * Render using this pass.
|
|
|
- *
|
|
|
- * @method render
|
|
|
- * @param {WebGLRenderer} renderer
|
|
|
- * @param {WebGLRenderTarget} writeBuffer Buffer to write output.
|
|
|
- * @param {WebGLRenderTarget} readBuffer Input buffer.
|
|
|
- * @param {Number} delta Delta time in milliseconds.
|
|
|
- * @param {Boolean} maskActive Not used in this pass.
|
|
|
- */
|
|
|
-THREE.SSAOPass.prototype.render = function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
|
|
|
+ this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
|
|
|
+ this.copyMaterial.blending = THREE.NoBlending;
|
|
|
+ this.renderPass( renderer, this.copyMaterial, null, true );
|
|
|
|
|
|
- //Render depth into depthRenderTarget
|
|
|
- this.scene2.overrideMaterial = this.depthMaterial;
|
|
|
+ break;
|
|
|
|
|
|
- renderer.render( this.scene2, this.camera2, this.depthRenderTarget, true );
|
|
|
+ case THREE.SSAOPass.OUTPUT.Default:
|
|
|
|
|
|
- this.scene2.overrideMaterial = null;
|
|
|
+ this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
|
|
|
+ this.copyMaterial.blending = THREE.NoBlending;
|
|
|
+ this.renderPass( renderer, this.copyMaterial, null, true );
|
|
|
|
|
|
+ this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture;
|
|
|
+ this.copyMaterial.blending = THREE.CustomBlending;
|
|
|
+ this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
|
|
|
|
|
|
- //SSAO shaderPass
|
|
|
- THREE.ShaderPass.prototype.render.call( this, renderer, writeBuffer, readBuffer, delta, maskActive );
|
|
|
+ break;
|
|
|
|
|
|
-};
|
|
|
+ default:
|
|
|
+ console.warn( 'THREE.SSAOPass: Unknown output type.' );
|
|
|
|
|
|
-/**
|
|
|
- * Change scene to be renderer by this render pass.
|
|
|
- *
|
|
|
- * @method setScene
|
|
|
- * @param {Scene} scene
|
|
|
- */
|
|
|
-THREE.SSAOPass.prototype.setScene = function ( scene ) {
|
|
|
+ }
|
|
|
|
|
|
- this.scene2 = scene;
|
|
|
+ },
|
|
|
|
|
|
-};
|
|
|
+ renderPass: function ( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
|
|
|
|
|
|
-/**
|
|
|
- * Set camera used by this render pass.
|
|
|
- *
|
|
|
- * @method setCamera
|
|
|
- * @param {Camera} camera
|
|
|
- */
|
|
|
-THREE.SSAOPass.prototype.setCamera = function ( camera ) {
|
|
|
+ // save original state
|
|
|
+ var originalClearColor = renderer.getClearColor();
|
|
|
+ var originalClearAlpha = renderer.getClearAlpha();
|
|
|
+ var originalAutoClear = renderer.autoClear;
|
|
|
|
|
|
- this.camera2 = camera;
|
|
|
+ // setup pass state
|
|
|
+ renderer.autoClear = false;
|
|
|
+ var clearNeeded = ( clearColor !== undefined ) && ( clearColor !== null );
|
|
|
+ if ( clearNeeded ) {
|
|
|
|
|
|
- this.uniforms[ 'cameraNear' ].value = this.camera2.near;
|
|
|
- this.uniforms[ 'cameraFar' ].value = this.camera2.far;
|
|
|
+ renderer.setClearColor( clearColor );
|
|
|
+ renderer.setClearAlpha( clearAlpha || 0.0 );
|
|
|
|
|
|
-};
|
|
|
+ }
|
|
|
|
|
|
-/**
|
|
|
- * Set resolution of this render pass.
|
|
|
- *
|
|
|
- * @method setSize
|
|
|
- * @param {Number} width
|
|
|
- * @param {Number} height
|
|
|
- */
|
|
|
-THREE.SSAOPass.prototype.setSize = function ( width, height ) {
|
|
|
+ this.quad.material = passMaterial;
|
|
|
+ renderer.render( this.quadScene, this.quadCamera, renderTarget, clearNeeded );
|
|
|
|
|
|
- this.width = width;
|
|
|
- this.height = height;
|
|
|
+ // restore original state
|
|
|
+ renderer.autoClear = originalAutoClear;
|
|
|
+ renderer.setClearColor( originalClearColor );
|
|
|
+ renderer.setClearAlpha( originalClearAlpha );
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ renderOverride: function ( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
|
|
|
+
|
|
|
+ var originalClearColor = renderer.getClearColor();
|
|
|
+ var originalClearAlpha = renderer.getClearAlpha();
|
|
|
+ var originalAutoClear = renderer.autoClear;
|
|
|
+
|
|
|
+ renderer.autoClear = false;
|
|
|
+
|
|
|
+ clearColor = overrideMaterial.clearColor || clearColor;
|
|
|
+ clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
|
|
|
+
|
|
|
+ var clearNeeded = ( clearColor !== undefined ) && ( clearColor !== null );
|
|
|
+
|
|
|
+ if ( clearNeeded ) {
|
|
|
+
|
|
|
+ renderer.setClearColor( clearColor );
|
|
|
+ renderer.setClearAlpha( clearAlpha || 0.0 );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ this.scene.overrideMaterial = overrideMaterial;
|
|
|
+ renderer.render( this.scene, this.camera, renderTarget, clearNeeded );
|
|
|
+ this.scene.overrideMaterial = null;
|
|
|
+
|
|
|
+ // restore original state
|
|
|
+
|
|
|
+ renderer.autoClear = originalAutoClear;
|
|
|
+ renderer.setClearColor( originalClearColor );
|
|
|
+ renderer.setClearAlpha( originalClearAlpha );
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ setSize: function ( width, height ) {
|
|
|
+
|
|
|
+ this.width = width;
|
|
|
+ this.height = height;
|
|
|
+
|
|
|
+ this.beautyRenderTarget.setSize( width, height );
|
|
|
+ this.ssaoRenderTarget.setSize( width, height );
|
|
|
+ this.normalRenderTarget.setSize( width, height );
|
|
|
+ this.blurRenderTarget.setSize( width, height );
|
|
|
+
|
|
|
+ this.ssaoMaterial.uniforms[ 'resolution' ].value.set( width, height );
|
|
|
+ this.ssaoMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
|
|
|
+ this.ssaoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.getInverse( this.camera.projectionMatrix );
|
|
|
+
|
|
|
+ this.blurMaterial.uniforms[ 'resolution' ].value.set( width, height );
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ generateSampleKernel: function () {
|
|
|
+
|
|
|
+ var kernelSize = this.kernelSize;
|
|
|
+ var kernel = this.kernel;
|
|
|
+
|
|
|
+ for ( var i = 0; i < kernelSize; i ++ ) {
|
|
|
+
|
|
|
+ var sample = new THREE.Vector3();
|
|
|
+ sample.x = ( Math.random() * 2 ) - 1;
|
|
|
+ sample.y = ( Math.random() * 2 ) - 1;
|
|
|
+ sample.z = Math.random();
|
|
|
+
|
|
|
+ sample.normalize();
|
|
|
+
|
|
|
+ var scale = i / kernelSize;
|
|
|
+ scale = THREE.Math.lerp( 0.1, 1, scale * scale );
|
|
|
+ sample.multiplyScalar( scale );
|
|
|
+
|
|
|
+ kernel.push( sample );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ generateRandomKernelRotations: function () {
|
|
|
+
|
|
|
+ var width = 4, height = 4;
|
|
|
+
|
|
|
+ if ( SimplexNoise === undefined ) {
|
|
|
+
|
|
|
+ console.error( 'THREE.SSAOPass: The pass relies on THREE.SimplexNoise.' );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var simplex = new SimplexNoise();
|
|
|
+
|
|
|
+ var size = width * height;
|
|
|
+ var data = new Float32Array( size );
|
|
|
+
|
|
|
+ for ( var i = 0; i < size; i ++ ) {
|
|
|
+
|
|
|
+ var x = ( Math.random() * 2 ) - 1;
|
|
|
+ var y = ( Math.random() * 2 ) - 1;
|
|
|
+ var z = 0;
|
|
|
+
|
|
|
+ data[ i ] = simplex.noise3d( x, y, z );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ this.noiseTexture = new THREE.DataTexture( data, width, height, THREE.LuminanceFormat, THREE.FloatType );
|
|
|
+ this.noiseTexture.wrapS = THREE.RepeatWrapping;
|
|
|
+ this.noiseTexture.wrapT = THREE.RepeatWrapping;
|
|
|
+ this.noiseTexture.needsUpdate = true;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- this.uniforms[ 'size' ].value.set( this.width, this.height );
|
|
|
- this.depthRenderTarget.setSize( this.width, this.height );
|
|
|
+} );
|
|
|
|
|
|
+THREE.SSAOPass.OUTPUT = {
|
|
|
+ 'Default': 0,
|
|
|
+ 'SSAO': 1,
|
|
|
+ 'Blur': 2,
|
|
|
+ 'Beauty': 3,
|
|
|
+ 'Depth': 4,
|
|
|
+ 'Normal': 5
|
|
|
};
|