Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const
- pVert = `
- attribute vec3 color;
- attribute vec2 scale;
- attribute float size;
- attribute float rotation;
- attribute float opacity;
- attribute float active;
- varying vec3 vColor;
- varying vec2 vScale;
- varying float vRotation;
- varying float vOpacity;
- varying float vActive;
- void main() {
- vColor = color;
- vScale = scale;
- vRotation = rotation;
- vOpacity = opacity;
- vActive = active;
- vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
- if (active > 0.5) { gl_PointSize = size * (300.0 / length(mvPosition.xyz)); };
- gl_Position = projectionMatrix * mvPosition;
- }
- `,
- pFrag = `
- uniform sampler2D map;
- varying vec3 vColor;
- varying vec2 vScale;
- varying float vRotation;
- varying float vOpacity;
- varying float vActive;
- void main() {
- float vMid = 0.5;
- if (vActive > 0.5) {
- vec2 rotated = vec2(
- cos(vRotation) * (gl_PointCoord.x / vScale.x - vMid) + sin(vRotation) * (gl_PointCoord.y - vMid) + vMid,
- 1.0 - (cos(vRotation) * (gl_PointCoord.y / vScale.y - vMid) - sin(vRotation) * (gl_PointCoord.x - vMid) + vMid)
- );
- gl_FragColor = vec4(vColor, vOpacity);
- gl_FragColor = gl_FragColor * texture2D(map, rotated);
- } else {
- gl_FragColor = vec4(0, 0, 0, 0);
- }
- }
- `
- class particleSystem {
- pCld: THREE.PointCloud = null;
- pGeo: THREE.BufferGeometry = new THREE.BufferGeometry;
- pMat: THREE.ShaderMaterial = new THREE.ShaderMaterial;
- pNum: number = 100;
- pDef;
- pAct: boolean[] = [];
- pLif: number[] = [];
- p = {
- position: null as THREE.BufferAttribute,
- color: null as THREE.BufferAttribute,
- scale: null as THREE.BufferAttribute,
- size: null as THREE.BufferAttribute,
- rotation: null as THREE.BufferAttribute,
- opacity: null as THREE.BufferAttribute,
- active: null as THREE.BufferAttribute
- };
- constructor(maxParticles: number, texture: THREE.Texture, extraFunction?: Function) {
- this.pNum = maxParticles;
- let
- positions: Float32Array = new Float32Array(maxParticles * 3),
- colors: Float32Array = new Float32Array(maxParticles * 3),
- scales: Float32Array = new Float32Array(maxParticles * 2),
- sizes: Float32Array = new Float32Array(maxParticles),
- rotations: Float32Array = new Float32Array(maxParticles),
- opacities: Float32Array = new Float32Array(maxParticles),
- actives: Float32Array = new Float32Array(maxParticles);
- // default values
- for (let p = 0; p < this.pNum; p ++) {
- this.pDef = {
- id: p,
- position: new Sup.Math.Vector3(),
- scale: new Sup.Math.Vector2(1, 1),
- color: new Sup.Color (1.0, 1.0, 1.0),
- size: 1.0,
- rotation: 0,
- opacity: 1.0,
- active: false
- };
- if (extraFunction != undefined) extraFunction(this.pDef);
- positions [p * 3 + 0] = this.pDef.position.x;
- positions [p * 3 + 1] = this.pDef.position.y;
- positions [p * 3 + 2] = this.pDef.position.z;
- colors [p * 3 + 0] = this.pDef.color.r;
- colors [p * 3 + 1] = this.pDef.color.g;
- colors [p * 3 + 2] = this.pDef.color.b;
- scales [p * 2 + 0] = this.pDef.scale.x;
- scales [p * 2 + 1] = this.pDef.scale.y;
- sizes [p] = this.pDef.size;
- rotations [p] = this.pDef.rotation;
- opacities [p] = this.pDef.opacity;
- actives [p] = this.pDef.active ? 1.0 : 0.0;
- this.pAct [p] = this.pDef.active;
- this.pLif [p] = 0;
- }
- // shader values
- this.pMat.uniforms = {map: {type: "t", value: texture}};
- this.pMat.vertexShader = pVert;
- this.pMat.fragmentShader = pFrag;
- this.pMat.transparent = true;
- this.pMat.depthWrite = false;
- // attribute values
- this.p.position = new THREE.BufferAttribute(positions, 3);
- this.p.color = new THREE.BufferAttribute(colors, 3);
- this.p.scale = new THREE.BufferAttribute(scales, 2);
- this.p.size = new THREE.BufferAttribute(sizes, 1);
- this.p.rotation = new THREE.BufferAttribute(rotations, 1);
- this.p.opacity = new THREE.BufferAttribute(opacities, 1);
- this.p.active = new THREE.BufferAttribute(actives, 1)
- this.pGeo.addAttribute('position', this.p.position);
- this.pGeo.addAttribute('color', this.p.color);
- this.pGeo.addAttribute('scale', this.p.scale);
- this.pGeo.addAttribute('size', this.p.size);
- this.pGeo.addAttribute('rotation', this.p.rotation);
- this.pGeo.addAttribute('opacity', this.p.opacity);
- this.pGeo.addAttribute('active', this.p.active);
- this.pCld = new THREE.PointCloud(this.pGeo, this.pMat);
- };
- animate(particleFunction: Function) {
- for (let p = 0; p < this.pNum; p ++) {
- if (this.pAct[p]) {
- let pSt = {
- id: p,
- position: new Sup.Math.Vector3(
- this.p.position.getX(p),
- this.p.position.getY(p),
- this.p.position.getZ(p)
- ),
- color: new Sup.Color(
- this.p.color.getX(p),
- this.p.color.getY(p),
- this.p.color.getZ(p)
- ),
- scale: new Sup.Math.Vector2(
- this.p.scale.getX(p),
- this.p.scale.getY(p)
- ),
- size: this.p.size.array[p],
- rotation: this.p.rotation.array[p],
- opacity: this.p.opacity.array[p],
- active: true,
- life: this.pLif[p]
- };
- particleFunction(pSt);
- this.p.position.setXYZ(p,
- pSt.position.x,
- pSt.position.y,
- pSt.position.z
- );
- this.p.color.setXYZ( p,
- pSt.color.r,
- pSt.color.g,
- pSt.color.b
- );
- this.p.scale.setXY(p,
- pSt.scale.x,
- pSt.scale.y
- );
- this.p.size.array[p] = pSt.size;
- this.p.rotation.array[p] = pSt.rotation;
- this.p.opacity.array[p] = pSt.opacity;
- this.p.active.array[p] = pSt.active ? 1.0 : 0.0;
- this.pAct[p] = pSt.active;
- this.pLif[p] ++;
- if (!pSt.active) this.pLif[p] = 0;
- }
- }
- this.p.position.needsUpdate = true;
- this.p.size.needsUpdate = true;
- this.p.scale.needsUpdate = true;
- this.p.color.needsUpdate = true;
- this.p.rotation.needsUpdate = true;
- this.p.opacity.needsUpdate = true;
- this.p.active.needsUpdate = true;
- }
- destroy() {
- for (let name in this.pGeo.attributes) {
- let attribute: THREE.BufferAttribute = this.pGeo.attributes[ name ];
- if (typeof(attribute.array) != 'undefined') {
- delete attribute.array;
- attribute = null;
- }
- }
- this.pGeo.dispose();
- this.pMat.dispose();
- this.pCld = null;
- this.pGeo = null;
- this.pMat = null;
- delete this.pGeo;
- delete this.pMat;
- delete this.pCld;
- }
- }
- class particleEmitterOptions {
- colorRange = {
- start: new THREE.Color(1.0, 1.0, 1.0) as THREE.Color,
- end: new THREE.Color(1.0, 1.0, 1.0) as THREE.Color
- }
- sizeRange = {
- start: 1.0 as number,
- end: 1.0 as number
- }
- rotationRange = {
- start: 0.0 as number,
- end: 0.0 as number
- }
- opacityRange = {
- start: 1.0 as number,
- end: 1.0 as number
- }
- getColor(): THREE.Color {
- return new THREE.Color(
- Sup.Math.Random.float(this.colorRange.start.r, this.colorRange.end.r),
- Sup.Math.Random.float(this.colorRange.start.g, this.colorRange.end.g),
- Sup.Math.Random.float(this.colorRange.start.b, this.colorRange.end.b)
- )
- }
- getSize(): number { return Sup.Math.Random.float(this.sizeRange.start, this.sizeRange.end ) };
- getRotation(): number { return Sup.Math.Random.float(this.rotationRange.start, this.rotationRange.end) };
- getOpacity(): number { return Sup.Math.Random.float(this.opacityRange.start, this.opacityRange.end ) };
- }
- class pointParticleEmitter {
- start: Sup.Math.Vector3;
- pSys: particleSystem;
- cId: number;
- options: particleEmitterOptions;
- constructor(pSys: particleSystem, start: Sup.Math.Vector3) {
- this.start = start;
- this.pSys = pSys
- this.cId = 0;
- this.options = new particleEmitterOptions();
- }
- burst(numParticles: number) {
- for (let p = 0; p < numParticles; p ++) {
- const pSysAct = this.pSys.pAct
- const toActivate = pSysAct.indexOf(false);
- if (toActivate !== -1) {
- let cc = this.options.getColor();
- pSysAct[toActivate] = true;
- this.pSys.p.position.setXYZ(toActivate, this.start.x, this.start.y, this.start.z);
- this.pSys.p.color. setXYZ(toActivate, cc.r, cc.b, cc.g);
- this.pSys.p.size. array[toActivate] = this.options.getSize();
- this.pSys.p.rotation.array[toActivate] = this.options.getRotation();
- this.pSys.p.opacity .array[toActivate] = this.options.getOpacity();
- }
- }
- }
- }
- class cubeParticleEmitter {
- start: Sup.Math.Vector3;
- end: Sup.Math.Vector3;
- offset: Sup.Math.Vector3;
- pSys: particleSystem;
- cId: number;
- options: particleEmitterOptions;
- bounds: number[][];
- constructor(pSys: particleSystem, start: Sup.Math.Vector3, end: Sup.Math.Vector3) {
- this.start = start;
- this.end = end;
- this.offset = new Sup.Math.Vector3;
- this.pSys = pSys;
- this.cId = 0;
- this.options = new particleEmitterOptions();
- this.bounds = [
- [Math.min(start.x, end.x), Math.max(start.x, end.x)],
- [Math.min(start.y, end.y), Math.max(start.y, end.y)],
- [Math.min(start.z, end.z), Math.max(start.z, end.z)]
- ];
- }
- burst(numParticles: number) {
- let a: number[] = [];
- for (let p = 0; p < numParticles; p ++) {
- const pSysAct = this.pSys.pAct;
- const toActivate = pSysAct.indexOf(false);
- a.push(toActivate);
- if (toActivate !== -1) {
- let cc = this.options.getColor();
- pSysAct[toActivate] = true;
- this.pSys.p.position.setXYZ(
- toActivate,
- this.offset.x + Sup.Math.Random.float(this.bounds[0][0], this.bounds[0][1]),
- this.offset.y + Sup.Math.Random.float(this.bounds[1][0], this.bounds[1][1]),
- this.offset.z + Sup.Math.Random.float(this.bounds[2][0], this.bounds[2][1])
- );
- this.pSys.p.color. setXYZ(toActivate, cc.r, cc.b, cc.g);
- this.pSys.p.size. array[toActivate] = this.options.getSize();
- this.pSys.p.rotation.array[toActivate] = this.options.getRotation();
- this.pSys.p.opacity .array[toActivate] = this.options.getOpacity();
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement