浏览代码

Initial add of lens flare

Mikael Emtinger 14 年之前
父节点
当前提交
926f1be28f
共有 2 个文件被更改,包括 204 次插入118 次删除
  1. 53 0
      src/lights/LensFlare.js
  2. 151 118
      src/renderers/WebGLRenderer.js

+ 53 - 0
src/lights/LensFlare.js

@@ -0,0 +1,53 @@
+/**
+ * @author Mikael Emtinger
+ */
+ 
+THREE.LensFlare = function ( material, size ) {
+
+	THREE.Object3D.call( this );
+
+	this.positionScreen = new THREE.Vector3();
+	this.lensFlares = [];
+	this.customUpdateCallback = undefined;
+
+	this.addLensFlare( material, size, 0 );
+};
+
+THREE.LensFlare.prototype = new THREE.Object3D();
+THREE.LensFlare.prototype.constructor = THREE.LensFlare;
+THREE.LensFlare.prototype.supr = THREE.Object3D.prototype;
+
+
+/*
+ * Add: adds another flare 
+ */
+
+THREE.LensFlare.prototype.add = function( material, size, distance ) {
+	
+	distance = Math.min( distance, Math.max( 0, distance ));
+
+	lensFlares.push( { material: material, size: size, distance: distance, position: new THREE.Vector3() } );
+}
+
+
+/*
+ * Update lens flares update positions on all flares based on the screen position
+ * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.
+ */
+
+THREE.LensFlare.updateLensFlares = function() {
+	
+	// todo: update lens halo positions here
+}
+
+
+
+
+
+
+
+
+
+
+
+

+ 151 - 118
src/renderers/WebGLRenderer.js

@@ -2524,159 +2524,186 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
+		// render flares
+		
+		if( scene.__webglLensFlares.length ) {
+			
+			renderLensFlares( scene, renderTarget );
+		
+		}
 
 
-		//////////////////////// stencil shadows begin //////////////////////
-		// method: we're rendering the world in light, then the shadow
-		//         volumes into the stencil and last a big darkening 
-		//         quad over the whole thing. This is NOT how you're
-		//         supposed to do stencil shadows but is much faster
-		//
+		// render stencil shadows
 
 		if( scene.__webglShadowVolumes.length && scene.lights.length ) {
+
+			renderStencilShadows( scene );
+		
+		}
+
+
+		// Generate mipmap if we're using any kind of mipmap filtering
+
+		if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
+
+			updateRenderTargetMipmap( renderTarget );
+
+		}
+
+	};
+
+
+	/*
+	 * Render lens flares
+	 * Method: renders 9 0xff00ff-colored points scattered over the light source area, 
+	 *         reads these back and calculates occlusion.  
+	 *         Then LensFlare.updateLensFlares() is called to re-position and 
+	 *         update transparency of flares. Then they are rendered.
+	 * 
+	 */
+
+	function renderLensFlares() {
+		
+		
+	}
+
+
+	/*
+	 * Stencil Shadows
+	 * method: we're rendering the world in light, then the shadow
+	 *         volumes into the stencil and last a big darkening 
+	 *         quad over the whole thing. This is not how "you're
+	 *	       supposed to" do stencil shadows but is much faster
+	 * 
+	 */
+
+	function renderStencilShadows( scene ) {
 			
-			// setup stencil
-	
-			_gl.enable( _gl.POLYGON_OFFSET_FILL );
-			_gl.polygonOffset( 0.1, 1.0 );
-			_gl.enable( _gl.STENCIL_TEST );
-			_gl.depthMask( false );
-			_gl.colorMask( false, false, false, false );
-		
-			_gl.stencilFunc( _gl.ALWAYS, 1, 0xFF );
-			_gl.stencilOpSeparate( _gl.BACK,  _gl.KEEP, _gl.INCR, _gl.KEEP );
-			_gl.stencilOpSeparate( _gl.FRONT, _gl.KEEP, _gl.DECR, _gl.KEEP );
-	
+		// setup stencil
+
+		_gl.enable( _gl.POLYGON_OFFSET_FILL );
+		_gl.polygonOffset( 0.1, 1.0 );
+		_gl.enable( _gl.STENCIL_TEST );
+		_gl.depthMask( false );
+		_gl.colorMask( false, false, false, false );
 	
+		_gl.stencilFunc( _gl.ALWAYS, 1, 0xFF );
+		_gl.stencilOpSeparate( _gl.BACK,  _gl.KEEP, _gl.INCR, _gl.KEEP );
+		_gl.stencilOpSeparate( _gl.FRONT, _gl.KEEP, _gl.DECR, _gl.KEEP );
+
+		
+		// loop through all directional lights
+		
+		var l, ll = scene.lights.length;
+		var p;
+		var light, lights = scene.lights, geometryGroup;
+		var dirLight = [];			
+		var	program;
+		var p_uniforms;
+	    var m_uniforms;
+	    var attributes;
+		var o, ol = scene.__webglShadowVolumes.length;
+		
+		for( l = 0; l < ll; l++ ) {
 			
-			// loop through all directional lights
-			
-			var l, ll = scene.lights.length;
-			var p;
-			var light, geometryGroup;
-			var dirLight = [];			
-			var	program;
-			var p_uniforms;
-		    var m_uniforms;
-		    var attributes;
-	
-			ol = scene.__webglShadowVolumes.length;
+			light = scene.lights[ l ];
 			
-			for( l = 0; l < ll; l++ ) {
+			if( light instanceof THREE.DirectionalLight ) {
+
+				dirLight[ 0 ] = -light.position.x;
+				dirLight[ 1 ] = -light.position.y;
+				dirLight[ 2 ] = -light.position.z;
+
 				
-				light = scene.lights[ l ];
+				// render all volumes
 				
-				if( light instanceof THREE.DirectionalLight ) {
+				for( o = 0; o < ol; o++ ) {
+		
+					object        = scene.__webglShadowVolumes[ o ].object;
+					geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
+					material      = object.materials[ 0 ];
 
-					dirLight[ 0 ] = -light.position.x;
-					dirLight[ 1 ] = -light.position.y;
-					dirLight[ 2 ] = -light.position.z;
 
-					
-					// render all volumes
-					
-					for ( o = 0; o < ol; o++ ) {
-			
-						object        = scene.__webglShadowVolumes[ o ].object;
-						geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
-						material      = object.materials[ 0 ];
+					if ( !material.program ) _this.initMaterial( material, lights, undefined, object );
 
+					program = material.program,
+		  			p_uniforms = program.uniforms,
+	                m_uniforms = material.uniforms,
+	                attributes = program.attributes;
 
-						if ( !material.program ) _this.initMaterial( material, lights, fog, object );
-	
-						program = material.program,
-			  			p_uniforms = program.uniforms,
-		                m_uniforms = material.uniforms,
-		                attributes = program.attributes;
 
+					if( _oldProgram !== program ) {
+						
+						_gl.useProgram( program );
+						_oldProgram = program;
 
-						if( _oldProgram !== program ) {
-							
-							_gl.useProgram( program );
-							_oldProgram = program;
+						_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
+						_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
+						_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
+					}
 
-							_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
-							_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
-							_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
-						}
 
+					object.matrixWorld.flattenToArray( object._objectMatrixArray );
+					_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
 
-						object.matrixWorld.flattenToArray( object._objectMatrixArray );
-						//object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
 
-						_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
-						//_gl.uniformMatrix4fv( p_uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
+					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
+					_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
 
-	
-						_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
-						_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
+					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
+					_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
 
-						_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
-						_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
+					_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
 
-						_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
+					_gl.cullFace( _gl.FRONT );
+					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
 
-						_gl.cullFace( _gl.FRONT );
-						_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
-
-						_gl.cullFace( _gl.BACK );
-						_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
-				
-					}
-	
+					_gl.cullFace( _gl.BACK );
+					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
+			
 				}
-	
+
 			}
-	
-	
-			// draw darkening polygon	
-	
-			_gl.disable( _gl.POLYGON_OFFSET_FILL );
-			_gl.colorMask( true, true, true, true );
-			_gl.stencilFunc( _gl.NOTEQUAL, 0, 0xFF );
-			_gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
-		    _gl.disable( _gl.DEPTH_TEST );
-			
-			_gl.enable( _gl.BLEND );
-			_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
-			_gl.blendEquation( _gl.FUNC_ADD );
-	
-	
-			_oldBlending = "";
-			_oldProgram = _shadow.program;
-	
-			_gl.useProgram( _shadow.program );
-			_gl.uniformMatrix4fv( _shadow.projectionLocation, false, _projectionMatrixArray );
-			
-			_gl.bindBuffer( _gl.ARRAY_BUFFER, _shadow.vertexBuffer );
-			_gl.vertexAttribPointer( _shadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
-			_gl.enableVertexAttribArray( _shadow.vertexLocation );
-				
-			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _shadow.elementBuffer );
-			_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
-	
-	
-			// disable stencil
-	
-		    _gl.disable	 ( _gl.STENCIL_TEST );
-		    _gl.enable	 ( _gl.DEPTH_TEST );
-			_gl.disable  ( _gl.BLEND );
-		    _gl.depthMask( true );
+
 		}
 
+		// setup color+stencil
 
-		//////////////////////// stencil shadows end //////////////////////
+		_gl.disable( _gl.POLYGON_OFFSET_FILL );
+		_gl.colorMask( true, true, true, true );
+		_gl.stencilFunc( _gl.NOTEQUAL, 0, 0xFF );
+		_gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
+	    _gl.disable( _gl.DEPTH_TEST );
 
 
-		// Generate mipmap if we're using any kind of mipmap filtering
+		// draw darkening polygon	
 
-		if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
+		_oldBlending = "";
+		_oldProgram = _shadow.program;
 
-			updateRenderTargetMipmap( renderTarget );
+		_gl.useProgram( _shadow.program );
+		_gl.uniformMatrix4fv( _shadow.projectionLocation, false, _projectionMatrixArray );
+		
+		_gl.bindBuffer( _gl.ARRAY_BUFFER, _shadow.vertexBuffer );
+		_gl.vertexAttribPointer( _shadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
+		_gl.enableVertexAttribArray( _shadow.vertexLocation );
 
-		}
+		_gl.enable( _gl.BLEND );
+		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
+		_gl.blendEquation( _gl.FUNC_ADD );
+			
+		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _shadow.elementBuffer );
+		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
+
+
+		// disable stencil
+
+	    _gl.disable	 ( _gl.STENCIL_TEST );
+	    _gl.enable	 ( _gl.DEPTH_TEST );
+		_gl.disable  ( _gl.BLEND );
+	    _gl.depthMask( true );
+	}
 
-	};
 
 	function setupMatrices ( object, camera ) {
 
@@ -2692,6 +2719,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			scene.__webglObjects = [];
 			scene.__webglObjectsImmediate = [];
 			scene.__webglShadowVolumes = [];
+			scene.__webglLensFlares = [];
 		}
 
 		while ( scene.__objectsAdded.length ) {
@@ -2722,6 +2750,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 		
+		for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {
+
+			updateObject( scene.__webglLensFlares[ o ].object, scene );
+
+		}
 
 	};