浏览代码

Added SSAOPass and ajusted example

Tentone 8 年之前
父节点
当前提交
468d0f1ffb
共有 2 个文件被更改,包括 119 次插入37 次删除
  1. 104 0
      examples/js/postprocessing/SSAOPass.js
  2. 15 37
      examples/webgl_postprocessing_ssao.html

+ 104 - 0
examples/js/postprocessing/SSAOPass.js

@@ -0,0 +1,104 @@
+'use strict';
+
+/*
+ * Screen-space ambient occlusion pass.
+ *
+ * Has the following parameters
+ *  - radius
+ *  - onlyAO
+ *  - aoClamp
+ *  - lumInfluence
+ * 
+ * To output to screen set renderToScreens true
+ *
+ * @author alteredq / http://alteredqualia.com/
+ * @author tentone
+ */
+THREE.SSAOPass = function ( scene, camera, width, height ) {
+
+	if ( THREE.SSAOShader === undefined)
+	{
+		console.warn('THREE.SSAOPass depends on THREE.SSAOShader');
+		return new THREE.ShaderPass();
+	}
+
+	THREE.ShaderPass.call( this, THREE.SSAOShader );
+
+	this.width = ( width !== undefined ) ? width : 512;
+	this.height = ( height !== undefined ) ? height : 512;
+
+	this.renderToScreen = false;
+
+	this.camera2 = camera;
+	this.scene2 = scene;
+
+	//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';
+	
+	//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;
+
+	//Setters and getters for uniforms
+	var self = this;
+	Object.defineProperties(this, {
+
+		radius: {
+			get: function() { return this.uniforms[ 'radius' ].value; },
+			set: function(value) { this.uniforms[ 'radius' ].value = value; }
+		},
+
+		onlyAO: {
+			get: function() { return this.uniforms[ 'onlyAO' ].value; },
+			set: function(value) { this.uniforms[ 'onlyAO' ].value = value; }
+		},
+
+		aoClamp: {
+			get: function() { return this.uniforms[ 'aoClamp' ].value; },
+			set: function(value) { this.uniforms[ 'aoClamp' ].value = value; }
+		},
+
+		lumInfluence: {
+			get: function() { return this.uniforms[ 'lumInfluence' ].value; },
+			set: function(value) { this.uniforms[ 'lumInfluence' ].value = value; }
+		},
+
+	});
+}
+
+THREE.SSAOPass.prototype = Object.create( THREE.ShaderPass.prototype );
+
+THREE.SSAOPass.prototype.render = function( renderer, writeBuffer, readBuffer, delta, maskActive ) {
+
+	//Render depth into depthRenderTarget
+	this.scene2.overrideMaterial = this.depthMaterial;
+	renderer.render( this.scene2, this.camera2, this.depthRenderTarget, true );
+	
+	//Render renderPass and SSAO shaderPass
+	this.scene2.overrideMaterial = null;
+	THREE.ShaderPass.prototype.render.call( this, renderer, writeBuffer, readBuffer, delta, maskActive );
+
+};
+
+THREE.SSAOPass.prototype.setSize = function( width, height ) {
+
+	this.width = width;
+	this.height = height;
+
+	this.uniforms[ 'size' ].value.set( this.width, this.height );
+	this.depthRenderTarget.setSize( this.width, this.height );
+
+};

+ 15 - 37
examples/webgl_postprocessing_ssao.html

@@ -48,6 +48,7 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 		<script src="js/postprocessing/RenderPass.js"></script>
 		<script src="js/postprocessing/ShaderPass.js"></script>
 		<script src="js/postprocessing/MaskPass.js"></script>
+		<script src="js/postprocessing/SSAOPass.js"></script>
 
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
@@ -64,10 +65,11 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 
 			var container, stats;
 			var camera, scene, renderer;
-			var depthMaterial, effectComposer, depthRenderTarget;
+			var effectComposer;
 			var ssaoPass;
 			var group;
-			var postprocessing = { enabled: true, ao_only: false, radius: 32 };
+
+			var postprocessing = { enabled: true, onlyAO: false, radius: 32, aoClamp: 0.25, lumInfluence: 0.7 };
 
 			init();
 			animate();
@@ -120,24 +122,22 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 				// Init gui
 				var gui = new dat.GUI();
 				gui.add( postprocessing, "enabled" );
-				gui.add( postprocessing, "ao_only", false ).onChange( renderModeChange );
-				gui.add( postprocessing, "radius" ).min( 0 ).max( 64 ).onChange( radiusChange );
 
-				window.addEventListener( 'resize', onWindowResize, false );
+				gui.add( postprocessing, "onlyAO", false ).onChange( function( value ) { ssaoPass.onlyAO = value; } );
 
-			}
+				gui.add( postprocessing, "radius" ).min( 0 ).max( 64 ).onChange( function( value ) { ssaoPass.radius = value; } );
+				
+				gui.add( postprocessing, "aoClamp" ).min( 0 ).max( 1 ).onChange( function( value ) { ssaoPass.aoClamp = value; } );
+				
+				gui.add( postprocessing, "lumInfluence" ).min( 0 ).max( 1 ).onChange( function( value ) { ssaoPass.lumInfluence = value; } );
+				
 
-			function radiusChange( value ) {
+				window.addEventListener( 'resize', onWindowResize, false );
 
-				ssaoPass.uniforms[ 'radius' ].value = value;
+				onWindowResize();
 
 			}
 
-			function renderModeChange( value ) {
-
-				ssaoPass.uniforms[ 'onlyAO' ].value = value;
-
-			}
 
 			function onWindowResize() {
 
@@ -149,14 +149,12 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 				renderer.setSize( width, height );
 
 				// Resize renderTargets
-				ssaoPass.uniforms[ 'size' ].value.set( width, height );
+				ssaoPass.setSize( 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 );
-
 			}
 
 			function initPostprocessing() {
@@ -164,23 +162,9 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 				// Setup render pass
 				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 );
-				depthRenderTarget.texture.name = "SSAOShader.rt";
-
 				// Setup SSAO pass
-				ssaoPass = new THREE.ShaderPass( THREE.SSAOShader );
+				ssaoPass = new THREE.SSAOPass( scene, camera );
 				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;
 
 				// Add pass to effect composer
 				effectComposer = new THREE.EffectComposer( renderer );
@@ -207,12 +191,6 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 
 				if ( postprocessing.enabled ) {
 
-					// Render depth into depthRenderTarget
-					scene.overrideMaterial = depthMaterial;
-					renderer.render( scene, camera, depthRenderTarget, true );
-
-					// Render renderPass and SSAO shaderPass
-					scene.overrideMaterial = null;
 					effectComposer.render();
 
 				} else {