three.js dev template - module

HTML

<div id="container"></div>
<script id="vertexShader" type="x-shader/x-vertex">
		precision highp float;
		
		#include <clipping_planes_pars_vertex>

		uniform float sineTime;

		uniform mat4 modelViewMatrix;
		uniform mat4 projectionMatrix;

		attribute vec3 position;
		attribute vec3 offset;
		attribute vec4 color;
		attribute vec4 orientationStart;
		attribute vec4 orientationEnd;

		varying vec3 vPosition;
		varying vec4 vColor;

		void main(){

			vPosition = offset * max( abs( sineTime * 2.0 + 1.0 ), 0.5 ) + position;
			vec4 orientation = normalize( mix( orientationStart, orientationEnd, sineTime ) );
			vec3 vcV = cross( orientation.xyz, vPosition );
			vPosition = vcV * ( 2.0 * orientation.w ) + ( cross( orientation.xyz, vcV ) * 2.0 + vPosition );

			vColor = color;
			
			vec4 mvPosition = modelViewMatrix * vec4( vPosition, 1.0 );

			gl_Position = projectionMatrix * mvPosition;
			
			#if NUM_CLIPPING_PLANES > 0

				vClipPosition = - mvPosition.xyz;

			#endif

		}

	</script>

	<script id="fragmentShader" type="x-shader/x-fragment">

		precision highp float;
		
		#include <clipping_planes_pars_fragment>

		uniform float time;

		varying vec3 vPosition;
		varying vec4 vColor;

		void main() {
		
			#include <clipping_planes_fragment>

			vec4 color = vec4( vColor );
			color.r += sin( vPosition.x * 10.0 + time ) * 0.5;

			gl_FragColor = color;

		}

	</script>

CSS

body {
  background-color: #000;
  margin: 0px;
  overflow: hidden;
}

.label {
  color: #FFF;
  font-family: sans-serif;
  padding: 2px;
  background: rgba(0, 0, 0, .6);
}

JavaScript

import * as THREE from "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js";

var container;

var camera, scene, renderer;

init();
animate();

function init() {

	container = document.getElementById( 'container' );

	camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10 );
	camera.position.z = 2;

	scene = new THREE.Scene();

	// geometry

	var vector = new THREE.Vector4();

	var instances = 50000;

	var positions = [];
	var offsets = [];
	var colors = [];
	var orientationsStart = [];
	var orientationsEnd = [];

	positions.push( 0.025, - 0.025, 0 );
	positions.push( - 0.025, 0.025, 0 );
	positions.push( 0, 0, 0.025 );

	// instanced attributes

	for ( var i = 0; i < instances; i ++ ) {

		// offsets

		offsets.push( Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5 );

		// colors

		colors.push( Math.random(), Math.random(), Math.random(), Math.random() );

		// orientation start

		vector.set( Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1 );
		vector.normalize();

		orientationsStart.push( vector.x, vector.y, vector.z, vector.w );

		// orientation end

		vector.set( Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1 );
		vector.normalize();

		orientationsEnd.push( vector.x, vector.y, vector.z, vector.w );

	}

	var geometry = new THREE.InstancedBufferGeometry();
	geometry.instanceCount = instances; // set so its initalized for dat.GUI, will be set in first draw otherwise

	geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );

	geometry.setAttribute( 'offset', new THREE.InstancedBufferAttribute( new Float32Array( offsets ), 3 ) );
	geometry.setAttribute( 'color', new THREE.InstancedBufferAttribute( new Float32Array( colors ), 4 ) );
	geometry.setAttribute( 'orientationStart', new THREE.InstancedBufferAttribute( new Float32Array( orientationsStart ), 4 ) );
	geometry.setAttribute(...