Ver Fonte

LensFlare: Refactored. No longer needs alpha: true, nor autoClear: false.

Mr.doob há 7 anos atrás
pai
commit
fe29d2def0

+ 60 - 103
examples/js/objects/LensFlare.js

@@ -1,15 +1,21 @@
 /**
  * @author Mugen87 / https://github.com/Mugen87
+ * @author mrdoob / http://mrdoob.com/
  */
 
 THREE.LensFlare = function () {
 
-	THREE.Group.call( this );
+	THREE.Mesh.call( this );
 
 	this.type = 'LensFlare';
 
-	this.positionScreen = new THREE.Vector3();
-	this.flareVisible = false;
+	this.renderOrder = Infinity; // see #12883
+	this.frustumCulled = false;
+
+	//
+
+	var flareVisible = false;
+	var positionScreen = new THREE.Vector3();
 
 	// textures
 
@@ -18,7 +24,7 @@ THREE.LensFlare = function () {
 	tempMap.magFilter = THREE.NearestFilter;
 	tempMap.needsUpdate = true;
 
-	var occlusionMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 4 ), 16, 16, THREE.RGBAFormat );
+	var occlusionMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, THREE.RGBFormat );
 	occlusionMap.minFilter = THREE.NearestFilter;
 	occlusionMap.magFilter = THREE.NearestFilter;
 	occlusionMap.needsUpdate = true;
@@ -31,7 +37,8 @@ THREE.LensFlare = function () {
 		uniforms: shader.uniforms,
 		vertexShader: shader.vertexShader,
 		fragmentShader: shader.fragmentShader,
-		depthWrite: false
+		depthWrite: false,
+		transparent: false
 	} );
 
 	// the following object is used for occlusionMap generation
@@ -44,19 +51,15 @@ THREE.LensFlare = function () {
 	var scale = new THREE.Vector2();
 	var screenPositionPixels = new THREE.Vector2();
 	var validArea = new THREE.Box2();
-	var currentFrame = 0;
-
-	this.update = function ( renderer, camera, viewport ) {
-
-		var frame = renderer.info.render.frame;
+	var viewport = new THREE.Vector4();
 
-		if ( currentFrame === frame ) return;
+	this.onBeforeRender = function ( renderer, scene, camera, geometry, material, group ) {
 
-		currentFrame = frame;
+		viewport.copy( renderer.getCurrentViewport() );
 
 		var invAspect = viewport.w / viewport.z;
-		var halfViewportWidth = viewport.z * 0.5;
-		var halfViewportHeight = viewport.w * 0.5;
+		var halfViewportWidth = viewport.z / 2.0;
+		var halfViewportHeight = viewport.w / 2.0;
 
 		var size = 16 / viewport.w;
 		scale.set( size * invAspect, size );
@@ -66,21 +69,26 @@ THREE.LensFlare = function () {
 
 		// calculate position in screen space
 
-		this.positionScreen.setFromMatrixPosition( this.matrixWorld );
+		positionScreen.setFromMatrixPosition( this.matrixWorld );
 
-		this.positionScreen.applyMatrix4( camera.matrixWorldInverse );
-		this.positionScreen.applyMatrix4( camera.projectionMatrix );
+		positionScreen.applyMatrix4( camera.matrixWorldInverse );
+		positionScreen.applyMatrix4( camera.projectionMatrix );
 
 		// horizontal and vertical coordinate of the lower left corner of the pixels to copy
 
-		screenPositionPixels.x = viewport.x + ( this.positionScreen.x * halfViewportWidth ) + halfViewportWidth - 8;
-		screenPositionPixels.y = viewport.y + ( this.positionScreen.y * halfViewportHeight ) + halfViewportHeight - 8;
+		screenPositionPixels.x = viewport.x + ( positionScreen.x * halfViewportWidth ) + halfViewportWidth - 8;
+		screenPositionPixels.y = viewport.y + ( positionScreen.y * halfViewportHeight ) + halfViewportHeight - 8;
 
 		// screen cull
 
-		if ( validArea.containsPoint( screenPositionPixels ) === true ) {
+		flareVisible = validArea.containsPoint( screenPositionPixels );
+
+		if ( flareVisible ) {
+
+			var currentAutoClear = renderer.autoClear;
+
+			renderer.autoClear = false;
 
-			this.flareVisible = true;
 
 			// save current RGB to temp texture
 
@@ -90,7 +98,7 @@ THREE.LensFlare = function () {
 
 			occluder.material.uniforms.renderType.value = 0;
 			occluder.material.uniforms.scale.value = scale;
-			occluder.material.uniforms.screenPosition.value = this.positionScreen;
+			occluder.material.uniforms.screenPosition.value = positionScreen;
 			occluder.material.depthTest = true;
 
 			renderer.render( occluder, camera );
@@ -107,39 +115,38 @@ THREE.LensFlare = function () {
 
 			renderer.render( occluder, camera );
 
-			// update object positions
-
-			updateLensFlares();
-
-		} else {
+			//
 
-			this.flareVisible = false;
+			renderer.autoClear = currentAutoClear;
 
 		}
 
-	};
+		// update object positions
 
-	var scope = this;
+		var children = this.children;
 
-	function updateLensFlares() {
+		var vecX = - positionScreen.x * 2;
+		var vecY = - positionScreen.y * 2;
 
-		var vecX = - scope.positionScreen.x * 2;
-		var vecY = - scope.positionScreen.y * 2;
+		for ( var i = 0, l = children.length; i < l; i ++ ) {
 
-		for ( var i = 0, l = scope.children.length; i < l; i ++ ) {
+			var flare = children[ i ];
 
-			var flare = scope.children[ i ];
+			var flarePosition = flare.material.uniforms.screenPosition.value;
+			flarePosition.x = positionScreen.x + vecX * flare.flareDistance;
+			flarePosition.y = positionScreen.y + vecY * flare.flareDistance;
 
-			flare.flarePosition.x = scope.positionScreen.x + vecX * flare.flareDistance;
-			flare.flarePosition.y = scope.positionScreen.y + vecY * flare.flareDistance;
+			//
 
-		}
+			var size = flare.flareSize / viewport.w;
+			var invAspect = viewport.w / viewport.z;
 
-	}
+			flare.material.uniforms.occlusionMap.value = occlusionMap;
+			flare.material.uniforms.scale.value.set( size * invAspect, size );
 
-	this.getOcclusionMap = function () {
+			flare.material.uniforms.opacity.value = flareVisible ? 1 : 0;
 
-		return occlusionMap;
+		}
 
 	};
 
@@ -154,7 +161,7 @@ THREE.LensFlare = function () {
 
 };
 
-THREE.LensFlare.prototype = Object.create( THREE.Group.prototype );
+THREE.LensFlare.prototype = Object.create( THREE.Mesh.prototype );
 THREE.LensFlare.prototype.constructor = THREE.LensFlare;
 THREE.LensFlare.prototype.isLensFlare = true;
 
@@ -208,7 +215,7 @@ THREE.LensFlare.Shader = {
 
 		'	if ( renderType == 0 ) {',
 
-		'		gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );',
+		'		gl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 );',
 
 		// restore
 
@@ -232,75 +239,31 @@ THREE.LensFlareElement = function ( texture, size, distance, color, blending, op
 
 	this.type = 'LensFlareElement';
 	this.frustumCulled = false;
-	this.renderOrder = Infinity; // see #12883
 
-	this.flareTexture = texture;
 	this.flareSize = size || 1;
 	this.flareDistance = distance || 0;
-	this.flareBlending = blending || THREE.AdditiveBlending;
-	this.flareColor = color || new THREE.Color( 0xffffff );
-	this.flareOpacity = opacity || 1;
-	this.flarePosition = new THREE.Vector3();
-	this.flareRotation = 0;
 
 	this.geometry = THREE.LensFlare.Geometry;
 
 	var shader = THREE.LensFlareElement.Shader;
 
 	this.material = new THREE.RawShaderMaterial( {
-		uniforms: shader.uniforms,
+		// uniforms: Object.assign( {}, shader.uniforms ),
+		uniforms: {
+			'map': { value: texture },
+			'occlusionMap': { value: null },
+			'opacity': { value: 1 },
+			'color': { value: color || new THREE.Color( 0xffffff ) },
+			'scale': { value: new THREE.Vector2() },
+			'screenPosition': { value: new THREE.Vector3() }
+		},
 		vertexShader: shader.vertexShader,
 		fragmentShader: shader.fragmentShader,
-		blending: this.flareBlending,
+		blending: blending || THREE.AdditiveBlending,
 		transparent: true,
 		depthWrite: false
 	} );
 
-	//
-
-	var scale = new THREE.Vector2();
-	var viewport = new THREE.Vector4();
-
-	this.onBeforeRender = function ( renderer, scene, camera, geometry, material, group ) {
-
-		var parent = this.parent;
-
-		if ( parent === null ) {
-
-			console.error( 'THREE.LensFlareElement: LensFlareElement not assigned to a LensFlare. Rendering not possible.' );
-			return;
-
-		}
-
-		//
-
-		viewport.copy( renderer.getCurrentViewport() );
-
-		parent.update( renderer, camera, viewport );
-
-		//
-
-		var size = this.flareSize / viewport.w;
-		var invAspect = viewport.w / viewport.z;
-
-		scale.set( size * invAspect, size );
-
-		this.material.uniforms.map.value = this.flareTexture;
-		this.material.uniforms.occlusionMap.value = parent.getOcclusionMap();
-		this.material.uniforms.opacity.value = this.flareOpacity;
-		this.material.uniforms.color.value = this.flareColor;
-		this.material.uniforms.scale.value = scale;
-		this.material.uniforms.rotation.value = this.flareRotation;
-		this.material.uniforms.screenPosition.value = this.flarePosition;
-
-		if ( parent.flareVisible === false ) {
-
-			this.material.uniforms.opacity.value = 0;
-
-		}
-
-	};
-
 	this.dispose = function () {
 
 		this.material.dispose();
@@ -322,7 +285,6 @@ THREE.LensFlareElement.Shader = {
 		'opacity': { value: 1 },
 		'color': { value: null },
 		'scale': { value: null },
-		'rotation': { value: 0 },
 		'screenPosition': { value: null }
 
 	},
@@ -333,7 +295,6 @@ THREE.LensFlareElement.Shader = {
 
 		'uniform vec3 screenPosition;',
 		'uniform vec2 scale;',
-		'uniform float rotation;',
 
 		'uniform sampler2D occlusionMap;',
 
@@ -362,10 +323,6 @@ THREE.LensFlareElement.Shader = {
 		'	vVisibility =        visibility.r / 9.0;',
 		'	vVisibility *= 1.0 - visibility.g / 9.0;',
 		'	vVisibility *=       visibility.b / 9.0;',
-		'	vVisibility *= 1.0 - visibility.a / 9.0;',
-
-		'	pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;',
-		'	pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;',
 
 		'	gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );',
 

+ 1 - 5
examples/webgl_lensflares.html

@@ -155,11 +155,9 @@
 
 				// renderer
 
-				renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.autoClear = false;
-				renderer.info.autoReset = false;
 				container.appendChild( renderer.domElement );
 
 				//
@@ -205,8 +203,6 @@
 				var delta = clock.getDelta();
 
 				controls.update( delta );
-				renderer.clear();
-				renderer.info.reset();
 				renderer.render( scene, camera );
 
 			}

+ 1 - 5
examples/webvr_sandbox.html

@@ -128,12 +128,10 @@
 
 				//
 
-				renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setClearColor( 0x000000 );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.autoClear = false;
-				renderer.info.autoReset = false;
 				renderer.shadowMap.enabled = true;
 				renderer.vr.enabled = true;
 				document.body.appendChild( renderer.domElement );
@@ -157,8 +155,6 @@
 
 			function animate() {
 
-				renderer.clear();
-				renderer.info.reset();
 				renderer.animate( render );
 
 			}