Skip to content
Snippets Groups Projects
3d-force-graph.js 1.6 MiB
Newer Older
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
14001 14002 14003 14004 14005 14006 14007 14008 14009 14010 14011 14012 14013 14014 14015 14016 14017 14018 14019 14020 14021 14022 14023 14024 14025 14026 14027 14028 14029 14030 14031 14032 14033 14034 14035 14036 14037 14038 14039 14040 14041 14042 14043 14044 14045 14046 14047 14048 14049 14050 14051 14052 14053 14054 14055 14056 14057 14058 14059 14060 14061 14062 14063 14064 14065 14066 14067 14068 14069 14070 14071 14072 14073 14074 14075 14076 14077 14078 14079 14080 14081 14082 14083 14084 14085 14086 14087 14088 14089 14090 14091 14092 14093 14094 14095 14096 14097 14098 14099 14100 14101 14102 14103 14104 14105 14106 14107 14108 14109 14110 14111 14112 14113 14114 14115 14116 14117 14118 14119 14120 14121 14122 14123 14124 14125 14126 14127 14128 14129 14130 14131 14132 14133 14134 14135 14136 14137 14138 14139 14140 14141 14142 14143 14144 14145 14146 14147 14148 14149 14150 14151 14152 14153 14154 14155 14156 14157 14158 14159 14160 14161 14162 14163 14164 14165 14166 14167 14168 14169 14170 14171 14172 14173 14174 14175 14176 14177 14178 14179 14180 14181 14182 14183 14184 14185 14186 14187 14188 14189 14190 14191 14192 14193 14194 14195 14196 14197 14198 14199 14200 14201 14202 14203 14204 14205 14206 14207 14208 14209 14210 14211 14212 14213 14214 14215 14216 14217 14218 14219 14220 14221 14222 14223 14224 14225 14226 14227 14228 14229 14230 14231 14232 14233 14234 14235 14236 14237 14238 14239 14240 14241 14242 14243 14244 14245 14246 14247 14248 14249 14250 14251 14252 14253 14254 14255 14256 14257 14258 14259 14260 14261 14262 14263 14264 14265 14266 14267 14268 14269 14270 14271 14272 14273 14274 14275 14276 14277 14278 14279 14280 14281 14282 14283 14284 14285 14286 14287 14288 14289 14290 14291 14292 14293 14294 14295 14296 14297 14298 14299 14300 14301 14302 14303 14304 14305 14306 14307 14308 14309 14310 14311 14312 14313 14314 14315 14316 14317 14318 14319 14320 14321 14322 14323 14324 14325 14326 14327 14328 14329 14330 14331 14332 14333 14334 14335 14336 14337 14338 14339 14340 14341 14342 14343 14344 14345 14346 14347 14348 14349 14350 14351 14352 14353 14354 14355 14356 14357 14358 14359 14360 14361 14362 14363 14364 14365 14366 14367 14368 14369 14370 14371 14372 14373 14374 14375 14376 14377 14378 14379 14380 14381 14382 14383 14384 14385 14386 14387 14388 14389 14390 14391 14392 14393 14394 14395 14396 14397 14398 14399 14400 14401 14402 14403 14404 14405 14406 14407 14408 14409 14410 14411 14412 14413 14414 14415 14416 14417 14418 14419 14420 14421 14422 14423 14424 14425 14426 14427 14428 14429 14430 14431 14432 14433 14434 14435 14436 14437 14438 14439 14440 14441 14442 14443 14444 14445 14446 14447 14448 14449 14450 14451 14452 14453 14454 14455 14456 14457 14458 14459 14460 14461 14462 14463 14464 14465 14466 14467 14468 14469 14470 14471 14472 14473 14474 14475 14476 14477 14478 14479 14480 14481 14482 14483 14484 14485 14486 14487 14488 14489 14490 14491 14492 14493 14494 14495 14496 14497 14498 14499 14500 14501 14502 14503 14504 14505 14506 14507 14508 14509 14510 14511 14512 14513 14514 14515 14516 14517 14518 14519 14520 14521 14522 14523 14524 14525 14526 14527 14528 14529 14530 14531 14532 14533 14534 14535 14536 14537 14538 14539 14540 14541 14542 14543 14544 14545 14546 14547 14548 14549 14550 14551 14552 14553 14554 14555 14556 14557 14558 14559 14560 14561 14562 14563 14564 14565 14566 14567 14568 14569 14570 14571 14572 14573 14574 14575 14576 14577 14578 14579 14580 14581 14582 14583 14584 14585 14586 14587 14588 14589 14590 14591 14592 14593 14594 14595 14596 14597 14598 14599 14600 14601 14602 14603 14604 14605 14606 14607 14608 14609 14610 14611 14612 14613 14614 14615 14616 14617 14618 14619 14620 14621 14622 14623 14624 14625 14626 14627 14628 14629 14630 14631 14632 14633 14634 14635 14636 14637 14638 14639 14640 14641 14642 14643 14644 14645 14646 14647 14648 14649 14650 14651 14652 14653 14654 14655 14656 14657 14658 14659 14660 14661 14662 14663 14664 14665 14666 14667 14668 14669 14670 14671 14672 14673 14674 14675 14676 14677 14678 14679 14680 14681 14682 14683 14684 14685 14686 14687 14688 14689 14690 14691 14692 14693 14694 14695 14696 14697 14698 14699 14700 14701 14702 14703 14704 14705 14706 14707 14708 14709 14710 14711 14712 14713 14714 14715 14716 14717 14718 14719 14720 14721 14722 14723 14724 14725 14726 14727 14728 14729 14730 14731 14732 14733 14734 14735 14736 14737 14738 14739 14740 14741 14742 14743 14744 14745 14746 14747 14748 14749 14750 14751 14752 14753 14754 14755 14756 14757 14758 14759 14760 14761 14762 14763 14764 14765 14766 14767 14768 14769 14770 14771 14772 14773 14774 14775 14776 14777 14778 14779 14780 14781 14782 14783 14784 14785 14786 14787 14788 14789 14790 14791 14792 14793 14794 14795 14796 14797 14798 14799 14800 14801 14802 14803 14804 14805 14806 14807 14808 14809 14810 14811 14812 14813 14814 14815 14816 14817 14818 14819 14820 14821 14822 14823 14824 14825 14826 14827 14828 14829 14830 14831 14832 14833 14834 14835 14836 14837 14838 14839 14840 14841 14842 14843 14844 14845 14846 14847 14848 14849 14850 14851 14852 14853 14854 14855 14856 14857 14858 14859 14860 14861 14862 14863 14864 14865 14866 14867 14868 14869 14870 14871 14872 14873 14874 14875 14876 14877 14878 14879 14880 14881 14882 14883 14884 14885 14886 14887 14888 14889 14890 14891 14892 14893 14894 14895 14896 14897 14898 14899 14900 14901 14902 14903 14904 14905 14906 14907 14908 14909 14910 14911 14912 14913 14914 14915 14916 14917 14918 14919 14920 14921 14922 14923 14924 14925 14926 14927 14928 14929 14930 14931 14932 14933 14934 14935 14936 14937 14938 14939 14940 14941 14942 14943 14944 14945 14946 14947 14948 14949 14950 14951 14952 14953 14954 14955 14956 14957 14958 14959 14960 14961 14962 14963 14964 14965 14966 14967 14968 14969 14970 14971 14972 14973 14974 14975 14976 14977 14978 14979 14980 14981 14982 14983 14984 14985 14986 14987 14988 14989 14990 14991 14992 14993 14994 14995 14996 14997 14998 14999 15000

  	this.renderTarget = renderTarget;

  	const cameraPX = new PerspectiveCamera( fov, aspect, near, far );
  	cameraPX.layers = this.layers;
  	cameraPX.up.set( 0, - 1, 0 );
  	cameraPX.lookAt( new Vector3( 1, 0, 0 ) );
  	this.add( cameraPX );

  	const cameraNX = new PerspectiveCamera( fov, aspect, near, far );
  	cameraNX.layers = this.layers;
  	cameraNX.up.set( 0, - 1, 0 );
  	cameraNX.lookAt( new Vector3( - 1, 0, 0 ) );
  	this.add( cameraNX );

  	const cameraPY = new PerspectiveCamera( fov, aspect, near, far );
  	cameraPY.layers = this.layers;
  	cameraPY.up.set( 0, 0, 1 );
  	cameraPY.lookAt( new Vector3( 0, 1, 0 ) );
  	this.add( cameraPY );

  	const cameraNY = new PerspectiveCamera( fov, aspect, near, far );
  	cameraNY.layers = this.layers;
  	cameraNY.up.set( 0, 0, - 1 );
  	cameraNY.lookAt( new Vector3( 0, - 1, 0 ) );
  	this.add( cameraNY );

  	const cameraPZ = new PerspectiveCamera( fov, aspect, near, far );
  	cameraPZ.layers = this.layers;
  	cameraPZ.up.set( 0, - 1, 0 );
  	cameraPZ.lookAt( new Vector3( 0, 0, 1 ) );
  	this.add( cameraPZ );

  	const cameraNZ = new PerspectiveCamera( fov, aspect, near, far );
  	cameraNZ.layers = this.layers;
  	cameraNZ.up.set( 0, - 1, 0 );
  	cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );
  	this.add( cameraNZ );

  	this.update = function ( renderer, scene ) {

  		if ( this.parent === null ) this.updateMatrixWorld();

  		const currentXrEnabled = renderer.xr.enabled;
  		const currentRenderTarget = renderer.getRenderTarget();

  		renderer.xr.enabled = false;

  		const generateMipmaps = renderTarget.texture.generateMipmaps;

  		renderTarget.texture.generateMipmaps = false;

  		renderer.setRenderTarget( renderTarget, 0 );
  		renderer.render( scene, cameraPX );

  		renderer.setRenderTarget( renderTarget, 1 );
  		renderer.render( scene, cameraNX );

  		renderer.setRenderTarget( renderTarget, 2 );
  		renderer.render( scene, cameraPY );

  		renderer.setRenderTarget( renderTarget, 3 );
  		renderer.render( scene, cameraNY );

  		renderer.setRenderTarget( renderTarget, 4 );
  		renderer.render( scene, cameraPZ );

  		renderTarget.texture.generateMipmaps = generateMipmaps;

  		renderer.setRenderTarget( renderTarget, 5 );
  		renderer.render( scene, cameraNZ );

  		renderer.setRenderTarget( currentRenderTarget );

  		renderer.xr.enabled = currentXrEnabled;

  	};

  	this.clear = function ( renderer, color, depth, stencil ) {

  		const currentRenderTarget = renderer.getRenderTarget();

  		for ( let i = 0; i < 6; i ++ ) {

  			renderer.setRenderTarget( renderTarget, i );

  			renderer.clear( color, depth, stencil );

  		}

  		renderer.setRenderTarget( currentRenderTarget );

  	};

  }

  CubeCamera.prototype = Object.create( Object3D.prototype );
  CubeCamera.prototype.constructor = CubeCamera;

  /**
   * @author alteredq / http://alteredqualia.com
   * @author WestLangley / http://github.com/WestLangley
   */

  function WebGLCubeRenderTarget( size, options, dummy ) {

  	if ( Number.isInteger( options ) ) {

  		console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' );

  		options = dummy;

  	}

  	WebGLRenderTarget.call( this, size, size, options );

  }

  WebGLCubeRenderTarget.prototype = Object.create( WebGLRenderTarget.prototype );
  WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget;

  WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true;

  WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer, texture ) {

  	this.texture.type = texture.type;
  	this.texture.format = texture.format;
  	this.texture.encoding = texture.encoding;

  	const scene = new Scene();

  	const shader = {

  		uniforms: {
  			tEquirect: { value: null },
  		},

  		vertexShader: [

  			"varying vec3 vWorldDirection;",

  			"vec3 transformDirection( in vec3 dir, in mat4 matrix ) {",

  			"	return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );",

  			"}",

  			"void main() {",

  			"	vWorldDirection = transformDirection( position, modelMatrix );",

  			"	#include <begin_vertex>",
  			"	#include <project_vertex>",

  			"}"

  		].join( '\n' ),

  		fragmentShader: [

  			"uniform sampler2D tEquirect;",

  			"varying vec3 vWorldDirection;",

  			"#include <common>",

  			"void main() {",

  			"	vec3 direction = normalize( vWorldDirection );",

  			"	vec2 sampleUV = equirectUv( direction );",

  			"	gl_FragColor = texture2D( tEquirect, sampleUV );",

  			"}"

  		].join( '\n' ),
  	};

  	const material = new ShaderMaterial( {

  		name: 'CubemapFromEquirect',

  		uniforms: cloneUniforms( shader.uniforms ),
  		vertexShader: shader.vertexShader,
  		fragmentShader: shader.fragmentShader,
  		side: BackSide,
  		blending: NoBlending

  	} );

  	material.uniforms.tEquirect.value = texture;

  	const mesh = new Mesh( new BoxBufferGeometry( 5, 5, 5 ), material );

  	scene.add( mesh );

  	const camera = new CubeCamera( 1, 10, this );
  	camera.update( renderer, scene );

  	mesh.geometry.dispose();
  	mesh.material.dispose();

  	return this;

  };

  /**
   * @author alteredq / http://alteredqualia.com/
   */

  function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {

  	Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );

  	this.image = { data: data || null, width: width || 1, height: height || 1 };

  	this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
  	this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;

  	this.generateMipmaps = false;
  	this.flipY = false;
  	this.unpackAlignment = 1;

  	this.needsUpdate = true;

  }

  DataTexture.prototype = Object.create( Texture.prototype );
  DataTexture.prototype.constructor = DataTexture;

  DataTexture.prototype.isDataTexture = true;

  /**
   * @author mrdoob / http://mrdoob.com/
   * @author alteredq / http://alteredqualia.com/
   * @author bhouston / http://clara.io
   */

  const _sphere$1 = new Sphere();
  const _vector$5 = new Vector3();

  function Frustum( p0, p1, p2, p3, p4, p5 ) {

  	this.planes = [

  		( p0 !== undefined ) ? p0 : new Plane(),
  		( p1 !== undefined ) ? p1 : new Plane(),
  		( p2 !== undefined ) ? p2 : new Plane(),
  		( p3 !== undefined ) ? p3 : new Plane(),
  		( p4 !== undefined ) ? p4 : new Plane(),
  		( p5 !== undefined ) ? p5 : new Plane()

  	];

  }

  Object.assign( Frustum.prototype, {

  	set: function ( p0, p1, p2, p3, p4, p5 ) {

  		const planes = this.planes;

  		planes[ 0 ].copy( p0 );
  		planes[ 1 ].copy( p1 );
  		planes[ 2 ].copy( p2 );
  		planes[ 3 ].copy( p3 );
  		planes[ 4 ].copy( p4 );
  		planes[ 5 ].copy( p5 );

  		return this;

  	},

  	clone: function () {

  		return new this.constructor().copy( this );

  	},

  	copy: function ( frustum ) {

  		const planes = this.planes;

  		for ( let i = 0; i < 6; i ++ ) {

  			planes[ i ].copy( frustum.planes[ i ] );

  		}

  		return this;

  	},

  	setFromProjectionMatrix: function ( m ) {

  		const planes = this.planes;
  		const me = m.elements;
  		const me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];
  		const me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];
  		const me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];
  		const me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];

  		planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
  		planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
  		planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
  		planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
  		planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
  		planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();

  		return this;

  	},

  	intersectsObject: function ( object ) {

  		const geometry = object.geometry;

  		if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();

  		_sphere$1.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );

  		return this.intersectsSphere( _sphere$1 );

  	},

  	intersectsSprite: function ( sprite ) {

  		_sphere$1.center.set( 0, 0, 0 );
  		_sphere$1.radius = 0.7071067811865476;
  		_sphere$1.applyMatrix4( sprite.matrixWorld );

  		return this.intersectsSphere( _sphere$1 );

  	},

  	intersectsSphere: function ( sphere ) {

  		const planes = this.planes;
  		const center = sphere.center;
  		const negRadius = - sphere.radius;

  		for ( let i = 0; i < 6; i ++ ) {

  			const distance = planes[ i ].distanceToPoint( center );

  			if ( distance < negRadius ) {

  				return false;

  			}

  		}

  		return true;

  	},

  	intersectsBox: function ( box ) {

  		const planes = this.planes;

  		for ( let i = 0; i < 6; i ++ ) {

  			const plane = planes[ i ];

  			// corner at max distance

  			_vector$5.x = plane.normal.x > 0 ? box.max.x : box.min.x;
  			_vector$5.y = plane.normal.y > 0 ? box.max.y : box.min.y;
  			_vector$5.z = plane.normal.z > 0 ? box.max.z : box.min.z;

  			if ( plane.distanceToPoint( _vector$5 ) < 0 ) {

  				return false;

  			}

  		}

  		return true;

  	},

  	containsPoint: function ( point ) {

  		const planes = this.planes;

  		for ( let i = 0; i < 6; i ++ ) {

  			if ( planes[ i ].distanceToPoint( point ) < 0 ) {

  				return false;

  			}

  		}

  		return true;

  	}

  } );

  /**
   * Uniforms library for shared webgl shaders
   */

  const UniformsLib = {

  	common: {

  		diffuse: { value: new Color( 0xeeeeee ) },
  		opacity: { value: 1.0 },

  		map: { value: null },
  		uvTransform: { value: new Matrix3() },
  		uv2Transform: { value: new Matrix3() },

  		alphaMap: { value: null },

  	},

  	specularmap: {

  		specularMap: { value: null },

  	},

  	envmap: {

  		envMap: { value: null },
  		flipEnvMap: { value: - 1 },
  		reflectivity: { value: 1.0 },
  		refractionRatio: { value: 0.98 },
  		maxMipLevel: { value: 0 }

  	},

  	aomap: {

  		aoMap: { value: null },
  		aoMapIntensity: { value: 1 }

  	},

  	lightmap: {

  		lightMap: { value: null },
  		lightMapIntensity: { value: 1 }

  	},

  	emissivemap: {

  		emissiveMap: { value: null }

  	},

  	bumpmap: {

  		bumpMap: { value: null },
  		bumpScale: { value: 1 }

  	},

  	normalmap: {

  		normalMap: { value: null },
  		normalScale: { value: new Vector2( 1, 1 ) }

  	},

  	displacementmap: {

  		displacementMap: { value: null },
  		displacementScale: { value: 1 },
  		displacementBias: { value: 0 }

  	},

  	roughnessmap: {

  		roughnessMap: { value: null }

  	},

  	metalnessmap: {

  		metalnessMap: { value: null }

  	},

  	gradientmap: {

  		gradientMap: { value: null }

  	},

  	fog: {

  		fogDensity: { value: 0.00025 },
  		fogNear: { value: 1 },
  		fogFar: { value: 2000 },
  		fogColor: { value: new Color( 0xffffff ) }

  	},

  	lights: {

  		ambientLightColor: { value: [] },

  		lightProbe: { value: [] },

  		directionalLights: { value: [], properties: {
  			direction: {},
  			color: {}
  		} },

  		directionalLightShadows: { value: [], properties: {
  			shadowBias: {},
  			shadowNormalBias: {},
  			shadowRadius: {},
  			shadowMapSize: {}
  		} },

  		directionalShadowMap: { value: [] },
  		directionalShadowMatrix: { value: [] },

  		spotLights: { value: [], properties: {
  			color: {},
  			position: {},
  			direction: {},
  			distance: {},
  			coneCos: {},
  			penumbraCos: {},
  			decay: {}
  		} },

  		spotLightShadows: { value: [], properties: {
  			shadowBias: {},
  			shadowNormalBias: {},
  			shadowRadius: {},
  			shadowMapSize: {}
  		} },

  		spotShadowMap: { value: [] },
  		spotShadowMatrix: { value: [] },

  		pointLights: { value: [], properties: {
  			color: {},
  			position: {},
  			decay: {},
  			distance: {}
  		} },

  		pointLightShadows: { value: [], properties: {
  			shadowBias: {},
  			shadowNormalBias: {},
  			shadowRadius: {},
  			shadowMapSize: {},
  			shadowCameraNear: {},
  			shadowCameraFar: {}
  		} },

  		pointShadowMap: { value: [] },
  		pointShadowMatrix: { value: [] },

  		hemisphereLights: { value: [], properties: {
  			direction: {},
  			skyColor: {},
  			groundColor: {}
  		} },

  		// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
  		rectAreaLights: { value: [], properties: {
  			color: {},
  			position: {},
  			width: {},
  			height: {}
  		} }

  	},

  	points: {

  		diffuse: { value: new Color( 0xeeeeee ) },
  		opacity: { value: 1.0 },
  		size: { value: 1.0 },
  		scale: { value: 1.0 },
  		map: { value: null },
  		alphaMap: { value: null },
  		uvTransform: { value: new Matrix3() }

  	},

  	sprite: {

  		diffuse: { value: new Color( 0xeeeeee ) },
  		opacity: { value: 1.0 },
  		center: { value: new Vector2( 0.5, 0.5 ) },
  		rotation: { value: 0.0 },
  		map: { value: null },
  		alphaMap: { value: null },
  		uvTransform: { value: new Matrix3() }

  	}

  };

  /**
   * @author mrdoob / http://mrdoob.com/
   */

  function WebGLAnimation() {

  	let context = null;
  	let isAnimating = false;
  	let animationLoop = null;
  	let requestId = null;

  	function onAnimationFrame( time, frame ) {

  		animationLoop( time, frame );

  		requestId = context.requestAnimationFrame( onAnimationFrame );

  	}

  	return {

  		start: function () {

  			if ( isAnimating === true ) return;
  			if ( animationLoop === null ) return;

  			requestId = context.requestAnimationFrame( onAnimationFrame );

  			isAnimating = true;

  		},

  		stop: function () {

  			context.cancelAnimationFrame( requestId );

  			isAnimating = false;

  		},

  		setAnimationLoop: function ( callback ) {

  			animationLoop = callback;

  		},

  		setContext: function ( value ) {

  			context = value;

  		}

  	};

  }

  /**
   * @author mrdoob / http://mrdoob.com/
   */

  function WebGLAttributes( gl, capabilities ) {

  	const isWebGL2 = capabilities.isWebGL2;

  	const buffers = new WeakMap();

  	function createBuffer( attribute, bufferType ) {

  		const array = attribute.array;
  		const usage = attribute.usage;

  		const buffer = gl.createBuffer();

  		gl.bindBuffer( bufferType, buffer );
  		gl.bufferData( bufferType, array, usage );

  		attribute.onUploadCallback();

  		let type = 5126;

  		if ( array instanceof Float32Array ) {

  			type = 5126;

  		} else if ( array instanceof Float64Array ) {

  			console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' );

  		} else if ( array instanceof Uint16Array ) {

  			type = 5123;

  		} else if ( array instanceof Int16Array ) {

  			type = 5122;

  		} else if ( array instanceof Uint32Array ) {

  			type = 5125;

  		} else if ( array instanceof Int32Array ) {

  			type = 5124;

  		} else if ( array instanceof Int8Array ) {

  			type = 5120;

  		} else if ( array instanceof Uint8Array ) {

  			type = 5121;

  		}

  		return {
  			buffer: buffer,
  			type: type,
  			bytesPerElement: array.BYTES_PER_ELEMENT,
  			version: attribute.version
  		};

  	}

  	function updateBuffer( buffer, attribute, bufferType ) {

  		const array = attribute.array;
  		const updateRange = attribute.updateRange;

  		gl.bindBuffer( bufferType, buffer );

  		if ( updateRange.count === - 1 ) {

  			// Not using update ranges

  			gl.bufferSubData( bufferType, 0, array );

  		} else {

  			if ( isWebGL2 ) {

  				gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
  					array, updateRange.offset, updateRange.count );

  			} else {

  				gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
  					array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) );

  			}

  			updateRange.count = - 1; // reset range

  		}

  	}

  	//

  	function get( attribute ) {

  		if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;

  		return buffers.get( attribute );

  	}

  	function remove( attribute ) {

  		if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;

  		const data = buffers.get( attribute );

  		if ( data ) {

  			gl.deleteBuffer( data.buffer );

  			buffers.delete( attribute );

  		}

  	}

  	function update( attribute, bufferType ) {

  		if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;

  		const data = buffers.get( attribute );

  		if ( data === undefined ) {

  			buffers.set( attribute, createBuffer( attribute, bufferType ) );

  		} else if ( data.version < attribute.version ) {

  			updateBuffer( data.buffer, attribute, bufferType );

  			data.version = attribute.version;

  		}

  	}

  	return {

  		get: get,
  		remove: remove,
  		update: update

  	};

  }

  /**
   * @author mrdoob / http://mrdoob.com/
   * @author Mugen87 / https://github.com/Mugen87
   */

  // PlaneGeometry

  function PlaneGeometry( width, height, widthSegments, heightSegments ) {

  	Geometry.call( this );

  	this.type = 'PlaneGeometry';

  	this.parameters = {
  		width: width,
  		height: height,
  		widthSegments: widthSegments,
  		heightSegments: heightSegments
  	};

  	this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );
  	this.mergeVertices();

  }

  PlaneGeometry.prototype = Object.create( Geometry.prototype );
  PlaneGeometry.prototype.constructor = PlaneGeometry;

  // PlaneBufferGeometry

  function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {

  	BufferGeometry.call( this );

  	this.type = 'PlaneBufferGeometry';

  	this.parameters = {
  		width: width,
  		height: height,
  		widthSegments: widthSegments,
  		heightSegments: heightSegments
  	};

  	width = width || 1;
  	height = height || 1;

  	const width_half = width / 2;
  	const height_half = height / 2;

  	const gridX = Math.floor( widthSegments ) || 1;
  	const gridY = Math.floor( heightSegments ) || 1;

  	const gridX1 = gridX + 1;
  	const gridY1 = gridY + 1;

  	const segment_width = width / gridX;
  	const segment_height = height / gridY;

  	// buffers

  	const indices = [];
  	const vertices = [];
  	const normals = [];
  	const uvs = [];

  	// generate vertices, normals and uvs

  	for ( let iy = 0; iy < gridY1; iy ++ ) {

  		const y = iy * segment_height - height_half;

  		for ( let ix = 0; ix < gridX1; ix ++ ) {

  			const x = ix * segment_width - width_half;

  			vertices.push( x, - y, 0 );

  			normals.push( 0, 0, 1 );

  			uvs.push( ix / gridX );
  			uvs.push( 1 - ( iy / gridY ) );

  		}

  	}

  	// indices

  	for ( let iy = 0; iy < gridY; iy ++ ) {

  		for ( let ix = 0; ix < gridX; ix ++ ) {

  			const a = ix + gridX1 * iy;
  			const b = ix + gridX1 * ( iy + 1 );
  			const c = ( ix + 1 ) + gridX1 * ( iy + 1 );
  			const d = ( ix + 1 ) + gridX1 * iy;

  			// faces

  			indices.push( a, b, d );
  			indices.push( b, c, d );

  		}

  	}

  	// build geometry

  	this.setIndex( indices );
  	this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  	this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  	this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );

  }

  PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;

  var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif";

  var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";

  var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif";

  var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif";

  var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";

  var begin_vertex = "vec3 transformed = vec3( position );";

  var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif";

  var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE  = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS  = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha  = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif";

  var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif";

  var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif";

  var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif";

  var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif";

  var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif";

  var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif";

  var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";

  var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";

  var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif";

  var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n  return m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}";

  var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_maxMipLevel 8.0\n#define cubeUV_minMipLevel 4.0\n#define cubeUV_maxTileSize 256.0\n#define cubeUV_minTileSize 16.0\nfloat getFace(vec3 direction) {\n    vec3 absDirection = abs(direction);\n    float face = -1.0;\n    if (absDirection.x > absDirection.z) {\n      if (absDirection.x > absDirection.y)\n        face = direction.x > 0.0 ? 0.0 : 3.0;\n      else\n        face = direction.y > 0.0 ? 1.0 : 4.0;\n    } else {\n      if (absDirection.z > absDirection.y)\n        face = direction.z > 0.0 ? 2.0 : 5.0;\n      else\n        face = direction.y > 0.0 ? 1.0 : 4.0;\n    }\n    return face;\n}\nvec2 getUV(vec3 direction, float face) {\n    vec2 uv;\n    if (face == 0.0) {\n      uv = vec2(direction.z, direction.y) / abs(direction.x);    } else if (face == 1.0) {\n      uv = vec2(-direction.x, -direction.z) / abs(direction.y);    } else if (face == 2.0) {\n      uv = vec2(-direction.x, direction.y) / abs(direction.z);    } else if (face == 3.0) {\n      uv = vec2(-direction.z, direction.y) / abs(direction.x);    } else if (face == 4.0) {\n      uv = vec2(-direction.x, direction.z) / abs(direction.y);    } else {\n      uv = vec2(direction.x, direction.y) / abs(direction.z);    }\n    return 0.5 * (uv + 1.0);\n}\nvec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {\n  float face = getFace(direction);\n  float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);\n  mipInt = max(mipInt, cubeUV_minMipLevel);\n  float faceSize = exp2(mipInt);\n  float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);\n  vec2 uv = getUV(direction, face) * (faceSize - 1.0);\n  vec2 f = fract(uv);\n  uv += 0.5 - f;\n  if (face > 2.0) {\n    uv.y += faceSize;\n    face -= 3.0;\n  }\n  uv.x += face * faceSize;\n  if(mipInt < cubeUV_maxMipLevel){\n    uv.y += 2.0 * cubeUV_maxTileSize;\n  }\n  uv.y += filterInt * 2.0 * cubeUV_minTileSize;\n  uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);\n  uv *= texelSize;\n  vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n  uv.x += texelSize;\n  vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n  uv.y += texelSize;\n  vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n  uv.x -= texelSize;\n  vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n  vec3 tm = mix(tl, tr, f.x);\n  vec3 bm = mix(bl, br, f.x);\n  return mix(tm, bm, f.y);\n}\n#define r0 1.0\n#define v0 0.339\n#define m0 -2.0\n#define r1 0.8\n#define v1 0.276\n#define m1 -1.0\n#define r4 0.4\n#define v4 0.046\n#define m4 2.0\n#define r5 0.305\n#define v5 0.016\n#define m5 3.0\n#define r6 0.21\n#define v6 0.0038\n#define m6 4.0\nfloat roughnessToMip(float roughness) {\n  float mip = 0.0;\n  if (roughness >= r1) {\n    mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;\n  } else if (roughness >= r4) {\n    mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;\n  } else if (roughness >= r5) {\n    mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;\n  } else if (roughness >= r6) {\n    mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;\n  } else {\n    mip = -2.0 * log2(1.16 * roughness);  }\n  return mip;\n}\nvec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) {\n  float mip = clamp(roughnessToMip(roughness), m0, cubeUV_maxMipLevel);\n  float mipF = fract(mip);\n  float mipInt = floor(mip);\n  vec3 color0 = bilinearCubeUV(envMap, sampleDir, mipInt);\n  if (mipF == 0.0) {\n    return vec4(color0, 1.0);\n  } else {\n    vec3 color1 = bilinearCubeUV(envMap, sampleDir, mipInt + 1.0);\n    return vec4(mix(color0, color1, mipF), 1.0);\n  }\n}\n#endif";

  var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif";

  var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";

  var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif";

  var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif";

  var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif";

  var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";

  var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = clamp( floor( D ) / 255.0, 0.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value )  {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}";

  var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\t\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t}  else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec2 sampleUV = equirectUv( reflectVec );\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif";

  var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif";

  var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif";

  var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif";