<canvas id="app"></canvas>
<script>
  image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAYAAADL1t+KAAAACXBIWXMAAAsTAAALEwEAmpwYAAAF8WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIxLTExLTE4VDE1OjM1OjU4KzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIxLTExLTE4VDE1OjM1OjU4KzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMS0xMS0xOFQxNTozNTo1OCswODowMCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxNzNjNGY0Zi01ZmVmLTA3NGUtYTRkOS0wYmUyMWMzMzI1OGYiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDpiYzU1MDYwNy1kMDJlLWZiNDUtOGM4MS04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';
</script>
#app {
  width: 100vw;
  height: 100vh;
}
var vs=[];
var fs=[];
var mesh=[];
var tex=[];
var mat=[];

var texture_loader=new THREE.TextureLoader();


const canvas = document.querySelector('#app');
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const context = canvas.getContext('webgl');
const renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true,
  transparent:true,
  canvas: canvas,
  context: context,
});
renderer.setClearColor(0x000000, 0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height, false);
const camera = new THREE.PerspectiveCamera(
  45,
  width / height,
  1,
  100000
);
camera.position.z = 500;
const scene = new THREE.Scene();
const pl1 = new THREE.PointLight(0xffffff, 0.8);
pl1.position.set(
  -200,
  200,
  200,
);
scene.add(pl1);
const clock = new THREE.Clock();
let elapsedTime;

const group = new THREE.Object3D();
group.add(
  new THREE.Mesh(
    new THREE.SphereGeometry(100, 32, 32),
    new THREE.MeshPhongMaterial({ 
      color: 0xfffaaa,
      transparent: true,
      opacity: 1,
    })
  )
);
scene.add(group);

group.add(
  new THREE.Line(
    new THREE.BufferGeometry().setFromPoints([
      new THREE.Vector3(-100, 0, 0),
      new THREE.Vector3(0, 100, 0),
      new THREE.Vector3(100, 0, 0)
    ]), 
    new THREE.LineBasicMaterial({
      color: 0x0000ff
    })
  )
);

const vert = `
uniform float uPointSize;
uniform float uTime;
uniform float uEnableAnimation;

attribute float type;
attribute float startTime;
attribute vec3 pointColor;

varying float vAlpha;
varying vec3 vColor;

void main() {
	float p = fract(uTime - startTime);
	vAlpha = 1.0 - p;
  gl_PointSize = p * uPointSize;

	vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
	gl_Position = projectionMatrix * mvPosition;

	vColor = vec3(pointColor);
}`;
const frag = `
uniform sampler2D uPointTexture;
varying float vAlpha;
varying vec3 vColor;

void main() {
  if (vAlpha <= 0.0) {
  	discard;
  }
  vec4 texColor = texture2D(uPointTexture, gl_PointCoord);
  gl_FragColor = vec4(vColor, texColor.a * vAlpha);
}`;
 
const material = new THREE.ShaderMaterial({
  uniforms: {
    uTime: {
      value: 0,
    },
    uPointSize: {
      value: 50,
    },
    uPointTexture: {
      value: new THREE.TextureLoader().load(image),
    },
  },
  vertexShader: vert,
  fragmentShader: frag,
  vertexColors: true,
  transparent: true,
  depthWrite: false,
  side: THREE.DoubleSide,
});



var geometry = new THREE.BufferGeometry();
const positionSize = 20;
geometry.setAttribute(
  "position",
  new THREE.BufferAttribute(new Float32Array(positionSize * 3), 3)
);
geometry.setAttribute(
  "startTime",
  new THREE.BufferAttribute(new Float32Array(positionSize), 1)
);
geometry.setAttribute(
  "pointColor",
  new THREE.BufferAttribute(new Float32Array(positionSize * 3), 3)
);
mesh["points"] = new THREE.Points(geometry, material);
group.add(mesh["points"]);



const position = geometry.attributes.position;
Array.from(Array(positionSize)).forEach((_, i) => {
  position.setXYZ(
    i,
    Math.random() * 210 - 105,
    Math.random() * 210 - 105,
    Math.random() * 210 - 105,
  );
});
position.needsUpdate = true;


tex["one"]=texture_loader.load(image);
tex["two"]=texture_loader.load("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABPUlEQVR42mNgoDpovvF/2v//qVtf8wpLEVatYuu75fv/////P/3/v+7RfwYGBib8Gt49uf/hLwMDA4MUA4MlP4NReCYhDfevnLr048lfBgYGBnc+Bgkzf8Ku4uAVKb3+/8v//////8898JuJoIYfn98sCVaa8IiBgYHh969vTGzc/AT1PL92/+VThh8MDK/vX2b68/MbMYF7cnblPQaGL08eMP3785sYDe4F7U++Mby7c5KBgYEhrGs2ftU6niEr3v6f+wMWDyzskj33/uNSLSAlm7Zg9X8WhtX1UxGiXXf+TnrxX8XaGU21VWz+1Df/57//X7D9IUSEES5XtPmmrofa+xcM+6dN+/LusbCcrkN6FBMTAzcvw45pe5bnu2KxXVrXPmrCqr6H/5f+/7/o///GM/+DWxeycQtRlHgBrNiEw8eNQ4gAAAAASUVORK5CYII=");


vs["sprite"]=`


attribute vec3 offset;
attribute vec2 scale;
attribute vec4 quaternion;
attribute float rotation;
attribute vec4 color;
attribute float blend;
attribute float texture;
uniform float time;
varying vec2 vUv;
varying vec4 vColor;
varying float vBlend;
varying float num;


void main(){


float angle=time*rotation;
float p=fract(time-sin(length(offset)));


vec3 vRotated=vec3(position.x*scale.x*p*cos(angle)-position.y*scale.y*p*sin(angle),position.y*scale.y*p*cos(angle)+position.x*scale.x*p*sin(angle),position.z);


vUv=uv;
vColor=color;
vBlend=blend;
num=texture;


vColor.w=1.0-p;


vec3 localUpVector=vec3(0.0,1.0,0.0);
vec3 vLook=normalize(quaternion.xyz-cameraPosition);
vec3 vRight=normalize(cross(vLook,localUpVector));
vec3 vUp=normalize(cross(vLook,vRight));
vec3 vPosition=vRight*vRotated.x+vUp*vRotated.y+vLook*vRotated.z;


gl_Position=projectionMatrix*modelViewMatrix*vec4(vPosition+offset,1.0);


}


`;


fs["sprite"]=`


const int count=2;
uniform sampler2D map[count];
varying vec2 vUv;
varying vec4 vColor;
varying float vBlend;
varying float num;


void main(){


if(num==0.0){ gl_FragColor=texture2D(map[0],vUv)*vColor; }
else if(num==1.0){ gl_FragColor=texture2D(map[1],vUv)*vColor; }


gl_FragColor.rgb*=gl_FragColor.a;
gl_FragColor.a*=vBlend;


}


`;


var particles=[];


function particles_update(){


particles=[];


var max_1=particles_flare_a.length;
particles.length=max_1;
for(var n=0;n<max_1;n++){
particles[n]=particles_flare_a[n];
}


var count=particles.length;
var item=camera.position;
var x=item.x;
var y=item.y;
var z=item.z;


for(var n=0;n<count;n++){
var item=particles[n].offset;
particles[n].d=Math.sqrt(Math.pow((x-item[0]),2)+Math.pow((y-item[1]),2)+Math.pow((z-item[2]),2));
}


particles.sort((a,b)=>b.d-a.d);


var offset=new Float32Array(count*3);
var scale=new Float32Array(count*2);
var quaternion=new Float32Array(count*4);
var rotation=new Float32Array(count);
var color=new Float32Array(count*4);
var blend=new Float32Array(count);
var texture=new Float32Array(count);


for(var n=0;n<count;n++){


// 1 VALUE
var item=particles[n];
rotation[n]=item.rotation;
texture[n]=item.texture;
blend[n]=item.blend;


// 2 VALUE
var p=n*2;
var one=p+1;
var i_scale=item.scale;
scale[p]=i_scale[0];
scale[one]=i_scale[1];


// 3 VALUE
var p=n*3;
var one=p+1;
var two=p+2;
var i_offset=item.offset;
offset[p]=i_offset[0];
offset[one]=i_offset[1];
offset[two]=i_offset[2];


// 4 VALUE
var p=n*4;
var one=p+1;
var two=p+2;
var three=p+3;
var i_color=item.color;
color[p]=i_color[0];
color[one]=i_color[1];
color[two]=i_color[2];
color[three]=i_color[3];
var i_quaternion=item.quaternion;
quaternion[p]=i_quaternion[0];
quaternion[one]=i_quaternion[1];
quaternion[two]=i_quaternion[2];
quaternion[three]=i_quaternion[3];


}


var item=mesh["sprite"].geometry.attributes;
item.offset=new THREE.InstancedBufferAttribute(offset,3).setUsage(THREE.DynamicDrawUsage);
item.scale=new THREE.InstancedBufferAttribute(scale,2).setUsage(THREE.DynamicDrawUsage);
item.quaternion=new THREE.InstancedBufferAttribute(quaternion,4).setUsage(THREE.DynamicDrawUsage);
item.rotation=new THREE.InstancedBufferAttribute(rotation,1).setUsage(THREE.DynamicDrawUsage);
item.color=new THREE.InstancedBufferAttribute(color,4).setUsage(THREE.DynamicDrawUsage);
item.blend=new THREE.InstancedBufferAttribute(blend,1).setUsage(THREE.DynamicDrawUsage);
item.texture=new THREE.InstancedBufferAttribute(texture,1).setUsage(THREE.DynamicDrawUsage);


mesh["sprite"].geometry._maxInstanceCount=count;


}


var geometry=new THREE.InstancedBufferGeometry();
geometry.setAttribute('position',new THREE.Float32BufferAttribute(new Float32Array([-0.5,0.5,0,-0.5,-0.5,0,0.5,0.5,0,0.5,-0.5,0,0.5,0.5,0,-0.5,-0.5,0]),3));
geometry.setAttribute('uv',new THREE.Float32BufferAttribute(new Float32Array([0,1,0,0,1,1,1,0,1,1,0,0]),2));
geometry.setAttribute('offset',new THREE.InstancedBufferAttribute(new Float32Array(),3));
geometry.setAttribute('scale',new THREE.InstancedBufferAttribute(new Float32Array(),2));
geometry.setAttribute('quaternion',new THREE.InstancedBufferAttribute(new Float32Array(),4));
geometry.setAttribute('rotation',new THREE.InstancedBufferAttribute(new Float32Array(),1));
geometry.setAttribute('color',new THREE.InstancedBufferAttribute(new Float32Array(),4));
geometry.setAttribute('blend',new THREE.InstancedBufferAttribute(new Float32Array(),1));
geometry.setAttribute('texture',new THREE.InstancedBufferAttribute(new Float32Array(),1));


mat["sprite"]=new THREE.ShaderMaterial({
uniforms:{
map:{value:[tex["one"],tex["two"]]},
time:{value:0}
},
vertexShader:vs["sprite"],
fragmentShader:fs["sprite"],
side:THREE.DoubleSide,
transparent:true,
depthWrite:false,
blending:THREE.CustomBlending,
blendEquation:THREE.AddEquation,
blendSrc:THREE.OneFactor,
blendDst:THREE.OneMinusSrcAlphaFactor
});


mesh["sprite"]=new THREE.Mesh(geometry,mat["sprite"]);
mesh["sprite"].frustumCulled=false;
//mesh["sprite"].matrixAutoUpdate=false;
//mesh["sprite"].updateMatrixWorld=function(){};
scene.add(mesh["sprite"]);


var particles_flare_a=[];


particles_flare_a.push({offset:[100,0,0],scale:[100,100],quaternion:[0,0,0,1],rotation:0.01,color:[1,1,1,1],blend:1,texture:1});
particles_flare_a.push({offset:[-100,0,0],scale:[20,30],quaternion:[0,0,0,1],rotation:0,color:[1,1,1,1],blend:1,texture:0});
particles_flare_a.push({offset:[100,100,0],scale:[60,40],quaternion:[0,0,0,1],rotation:0,color:[1,1,1,1],blend:1,texture:1});


for(var n=0;n<10;n++){
particles_flare_a.push({offset:[Math.random()*210-105,Math.random()*210-105,Math.random()*210-105],scale:[100,100],quaternion:[0,0,0,1],rotation:10,color:[Math.random(),Math.random(),Math.random(),1],blend:1,texture:1});
}


for(var n=0;n<100;n++){
particles_flare_a.push({offset:[Math.random()*210-105,Math.random()*210-105,Math.random()*210-105],scale:[30,30],quaternion:[0,0,0,1],rotation:0.01,color:[1,1,1,1],blend:1,texture:0});
}


const update = () => {
  const delta = clock.getDelta();
  elapsedTime = clock.elapsedTime;
  material.uniforms.uTime.value = elapsedTime;
  group.rotation.y += 0.01;
  particles_update();
  mat["sprite"].uniforms.time.value = elapsedTime;
  mesh["sprite"].rotation.y += 0.01;
  renderer.render(scene, camera);
  requestAnimationFrame(update);
}
update();
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js