How do I include THREE.LensFlareElement in Angular Project?

I tried to use the LensFlareElement in my scene but every time I try to load the scene i got the following message:

THREE.LensFlare has been moved to /examples/js/objects/Lensflare.js

I installed Three.js with the npm three and included it as follows:

import * as THREE from 'three';

So is there any way i can get to that code which lays inside the js file using typescript and angular7?

Kind Regards

/cc

Your issue is similar to this one: OrbitControls issue with angular 6

Dear Mugen87

I read your answer already on a orbit-control issue on stackoverflow:

You have to transform the class into a module and import it separately.

All i can understand is that I have to use something? Webpack? To ā€œgenerateā€ the module out of the file but I donā€™t have any idea where to start?

How do I make such a module? How do I apply it to my angular 7 application? Do I have to use a console for that approach?

I am using angular 7 and the asp.net web app template provided by Microsoft.

It would be nice of you to provide me with a straight forward step by step instruction or set me up with a link that would explain what I have to do in order to get it to work?

Thank you in advance

You have to do this manually or by using one of the approaches mentioned in this issue (be aware, itā€™s huge). Fortunately, there will be a node script with the next release R101 that can generate modules from example files:

1 Like

be aware, itā€™s huge

Yepā€¦ :confused:

Fortunately, there will be a node script with the next release R101 that can generate modules from example files.

Are these node scripts easy to use, for example like npm install? And when will R101 approx. be released? And wouldnā€™t it make much more sense if mrdoob would provide the three npm with an example module that one could import and use like a service?

By the way thank you for your time, I appreciate it very much since Iā€™ve just recently began to use angular so Iā€™m kinda new in this section. In the end I just wanted to get a LensFlareElement Object for my Galaxy-Stars :smile:

The planned release date is January 30.

Please post any feature requests related to the script at github.

Sry, Iā€™m not familiar with angular so I canā€™t provide any framework-specific help.

Ok thanks for the input. I will look up to R101 and post regarding questions to github.

Eventhough itā€™s the npm package, I can still ask the question here right?

Kind Regards

Yes, but please focus on feature requests or bug reports. The forum or stackoverflow is intended for help requests.

Yes thank you for the advise. Can you >help< me with an instruction on using that module convert script that youā€™ve mentioned? Is there a documentation on how to set it up and use it? Iā€™ve tried to download the R101 release. When i tried to npm uninstall three and reinstall it with npm install three i actually still got the R100 version.

Any chance to switch on to R101 yet? I saw today (30th January 2019) that the Milestone Progressbar still remained at ā€˜42% completeā€™. Will the release come out today or is it delayed?

Kind Regards

//cc

https://github.com/mrdoob/three.js/issues/15648#event-2099175841>

The amount of completed milestones is no good orientation for the release date. Itā€™s better to focus defined date in the milestone.

Past due by 1 day from github Milestonesā€¦ Iā€™m sorry for the nervosity, but itā€™s very important that I get the LensFlare running asap. I was looking out for the other method in transforming the needed examples to a module that youā€™ve mentioned, but couldnā€™t find a clear example of how to do it, so is there any chance you can tell me if there is any instructions on how to do so or can you tell me when the LensFlare Part approx. is getting done?

Kind Regards

Okay, because you need it so urgent, I have manually transformed the file to a module. If you study a bit the changes, you will see that it is not complicated to do this. With a little more research, you could have done that yourself.

import * as THREE from '../../../build/three.module.js';

function Lensflare() {

	THREE.Mesh.call( this, LensflareGeometry, new THREE.MeshBasicMaterial( { opacity: 0, transparent: true } ) );

	this.type = 'Lensflare';
	this.frustumCulled = false;
	this.renderOrder = Infinity;

	//

	var positionScreen = new THREE.Vector3();
	var positionView = new THREE.Vector3();

	// textures

	var tempMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, THREE.RGBFormat );
	tempMap.minFilter = THREE.NearestFilter;
	tempMap.magFilter = THREE.NearestFilter;
	tempMap.wrapS = THREE.ClampToEdgeWrapping;
	tempMap.wrapT = THREE.ClampToEdgeWrapping;
	tempMap.needsUpdate = true;

	var occlusionMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, THREE.RGBFormat );
	occlusionMap.minFilter = THREE.NearestFilter;
	occlusionMap.magFilter = THREE.NearestFilter;
	occlusionMap.wrapS = THREE.ClampToEdgeWrapping;
	occlusionMap.wrapT = THREE.ClampToEdgeWrapping;
	occlusionMap.needsUpdate = true;

	// material

	var geometry = LensflareGeometry;

	var material1a = new THREE.RawShaderMaterial( {
		uniforms: {
			'scale': { value: null },
			'screenPosition': { value: null }
		},
		vertexShader: [

			'precision highp float;',

			'uniform vec3 screenPosition;',
			'uniform vec2 scale;',

			'attribute vec3 position;',

			'void main() {',

			'	gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );',

			'}'

		].join( '\n' ),
		fragmentShader: [

			'precision highp float;',

			'void main() {',

			'	gl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 );',

			'}'

		].join( '\n' ),
		depthTest: true,
		depthWrite: false,
		transparent: false
	} );

	var material1b = new THREE.RawShaderMaterial( {
		uniforms: {
			'map': { value: tempMap },
			'scale': { value: null },
			'screenPosition': { value: null }
		},
		vertexShader: [

			'precision highp float;',

			'uniform vec3 screenPosition;',
			'uniform vec2 scale;',

			'attribute vec3 position;',
			'attribute vec2 uv;',

			'varying vec2 vUV;',

			'void main() {',

			'	vUV = uv;',

			'	gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );',

			'}'

		].join( '\n' ),
		fragmentShader: [

			'precision highp float;',

			'uniform sampler2D map;',

			'varying vec2 vUV;',

			'void main() {',

			'	gl_FragColor = texture2D( map, vUV );',

			'}'

		].join( '\n' ),
		depthTest: false,
		depthWrite: false,
		transparent: false
	} );

	// the following object is used for occlusionMap generation

	var mesh1 = new THREE.Mesh( geometry, material1a );

	//

	var elements = [];

	var shader = LensflareElement.Shader;

	var material2 = new THREE.RawShaderMaterial( {
		uniforms: {
			'map': { value: null },
			'occlusionMap': { value: occlusionMap },
			'color': { value: new THREE.Color( 0xffffff ) },
			'scale': { value: new THREE.Vector2() },
			'screenPosition': { value: new THREE.Vector3() }
		},
		vertexShader: shader.vertexShader,
		fragmentShader: shader.fragmentShader,
		blending: THREE.AdditiveBlending,
		transparent: true,
		depthWrite: false
	} );

	var mesh2 = new THREE.Mesh( geometry, material2 );

	this.addElement = function ( element ) {

		elements.push( element );

	};

	//

	var scale = new THREE.Vector2();
	var screenPositionPixels = new THREE.Vector2();
	var validArea = new THREE.Box2();
	var viewport = new THREE.Vector4();

	this.onBeforeRender = function ( renderer, scene, camera ) {

		viewport.copy( renderer.getCurrentViewport() );

		var invAspect = viewport.w / viewport.z;
		var halfViewportWidth = viewport.z / 2.0;
		var halfViewportHeight = viewport.w / 2.0;

		var size = 16 / viewport.w;
		scale.set( size * invAspect, size );

		validArea.min.set( viewport.x, viewport.y );
		validArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );

		// calculate position in screen space

		positionView.setFromMatrixPosition( this.matrixWorld );
		positionView.applyMatrix4( camera.matrixWorldInverse );

		if ( positionView.z > 0 ) return; // lensflare is behind the camera

		positionScreen.copy( positionView ).applyMatrix4( camera.projectionMatrix );

		// horizontal and vertical coordinate of the lower left corner of the pixels to copy

		screenPositionPixels.x = viewport.x + ( positionScreen.x * halfViewportWidth ) + halfViewportWidth - 8;
		screenPositionPixels.y = viewport.y + ( positionScreen.y * halfViewportHeight ) + halfViewportHeight - 8;

		// screen cull

		if ( validArea.containsPoint( screenPositionPixels ) ) {

			// save current RGB to temp texture

			renderer.copyFramebufferToTexture( screenPositionPixels, tempMap );

			// render pink quad

			var uniforms = material1a.uniforms;
			uniforms[ "scale" ].value = scale;
			uniforms[ "screenPosition" ].value = positionScreen;

			renderer.renderBufferDirect( camera, null, geometry, material1a, mesh1, null );

			// copy result to occlusionMap

			renderer.copyFramebufferToTexture( screenPositionPixels, occlusionMap );

			// restore graphics

			var uniforms = material1b.uniforms;
			uniforms[ "scale" ].value = scale;
			uniforms[ "screenPosition" ].value = positionScreen;

			renderer.renderBufferDirect( camera, null, geometry, material1b, mesh1, null );

			// render elements

			var vecX = - positionScreen.x * 2;
			var vecY = - positionScreen.y * 2;

			for ( var i = 0, l = elements.length; i < l; i ++ ) {

				var element = elements[ i ];

				var uniforms = material2.uniforms;

				uniforms[ "color" ].value.copy( element.color );
				uniforms[ "map" ].value = element.texture;
				uniforms[ "screenPosition" ].value.x = positionScreen.x + vecX * element.distance;
				uniforms[ "screenPosition" ].value.y = positionScreen.y + vecY * element.distance;

				var size = element.size / viewport.w;
				var invAspect = viewport.w / viewport.z;

				uniforms[ "scale" ].value.set( size * invAspect, size );

				material2.uniformsNeedUpdate = true;

				renderer.renderBufferDirect( camera, null, geometry, material2, mesh2, null );

			}

		}

	};

	this.dispose = function () {

		material1a.dispose();
		material1b.dispose();
		material2.dispose();

		tempMap.dispose();
		occlusionMap.dispose();

		for ( var i = 0, l = elements.length; i < l; i ++ ) {

			elements[ i ].texture.dispose();

		}

	};

}

Lensflare.prototype = Object.create( THREE.Mesh.prototype );
Lensflare.prototype.constructor = Lensflare;
Lensflare.prototype.isLensflare = true;

//

function LensflareElement( texture, size, distance, color ) {

	this.texture = texture;
	this.size = size || 1;
	this.distance = distance || 0;
	this.color = color || new THREE.Color( 0xffffff );

}

LensflareElement.Shader = {

	uniforms: {

		'map': { value: null },
		'occlusionMap': { value: null },
		'color': { value: null },
		'scale': { value: null },
		'screenPosition': { value: null }

	},

	vertexShader: [

		'precision highp float;',

		'uniform vec3 screenPosition;',
		'uniform vec2 scale;',

		'uniform sampler2D occlusionMap;',

		'attribute vec3 position;',
		'attribute vec2 uv;',

		'varying vec2 vUV;',
		'varying float vVisibility;',

		'void main() {',

		'	vUV = uv;',

		'	vec2 pos = position.xy;',

		'	vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );',
		'	visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );',
		'	visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );',
		'	visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );',
		'	visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );',
		'	visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );',
		'	visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );',
		'	visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );',
		'	visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );',

		'	vVisibility =        visibility.r / 9.0;',
		'	vVisibility *= 1.0 - visibility.g / 9.0;',
		'	vVisibility *=       visibility.b / 9.0;',

		'	gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );',

		'}'

	].join( '\n' ),

	fragmentShader: [

		'precision highp float;',

		'uniform sampler2D map;',
		'uniform vec3 color;',

		'varying vec2 vUV;',
		'varying float vVisibility;',

		'void main() {',

		'	vec4 texture = texture2D( map, vUV );',
		'	texture.a *= vVisibility;',
		'	gl_FragColor = texture;',
		'	gl_FragColor.rgb *= color;',

		'}'

	].join( '\n' )

};

var count = 0;

var LensflareGeometry = ( function () {

	var geometry = new THREE.BufferGeometry();

	var float32Array = new Float32Array( [
		- 1, - 1, 0, 0, 0,
		1, - 1, 0, 1, 0,
		1, 1, 0, 1, 1,
		- 1, 1, 0, 0, 1
	] );

	var interleavedBuffer = new THREE.InterleavedBuffer( float32Array, 5 );

	geometry.setIndex( [ 0, 1, 2,	0, 2, 3 ] );
	geometry.addAttribute( 'position', new THREE.InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) );
	geometry.addAttribute( 'uv', new THREE.InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) );

	geometry.index.temp = count ++;

	return geometry;

} )();

export { Lensflare, LensflareElement };

5 Likes

Thanks for the example. After seeing this example i noticed the following:

How to transform a Module:

  1. Take the original example code
  2. import * as THREE from 'three'
  3. Remove the THREE declaration of each and put an export { TheExampleIWant } on the endā€¦

Anyway sorry for the inconvenienceā€¦