123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- import * as RE from 'rogue-engine'
- import * as THREE from 'three'
- import { Color } from 'three';
- // import Player from './Player.re';
- //https://www.youtube.com/watch?v=OFqENgtqRAY
- export default class ParticleSystem extends RE.Component {
- vertexShader = `
- uniform float pointMultiplier;
- varying vec4 vColor;
- void main() {
- vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
- gl_Position = projectionMatrix * mvPosition;
- gl_PointSize = pointMultiplier / gl_Position.w;
- vColor = color;
- }`;
-
- fragmentShader = `
- uniform sampler2D diffuseTexture;
- varying vec4 vColor;
- void main() {
- gl_FragColor = texture2D(diffuseTexture, gl_PointCoord) * vColor;
- }`;
- @RE.Prop("Texture") particleTexture
- @RE.Prop("Number") maxParticles = 1
- @RE.Prop("Number") particleLifespan = 50
- @RE.Prop("Vector3") initialPosition = new THREE.Vector3(0,0,0)
- @RE.Prop("Vector3") initialVelocity = new THREE.Vector3(0,0,0)
- @RE.Prop("Object3D") points
- @RE.Prop("Number") thrustScalar = 0.01
- @RE.Prop("Vector3") positionRandomBounds = new THREE.Vector3(1,1,1)
- @RE.Prop("Vector3") velocityRandomBounds = new THREE.Vector3(1,1,1)
- @RE.Prop("Color") particleColor = new Color(255, 255, 255)
- @RE.Prop("Number") particleAlpha = 1
- @RE.Prop("Object3D") spawnLocation
- start() {
- const bounds = RE.Runtime.rogueDOMContainer.getBoundingClientRect();
- const uniforms = {
- diffuseTexture: {
- value: this.particleTexture
- },
- pointMultiplier: {
- value: bounds.width - bounds.left
- }
- }
- this.material = new THREE.ShaderMaterial({
- uniforms: uniforms,
- vertexShader: this.vertexShader,
- fragmentShader: this.fragmentShader,
- blending: THREE.AdditiveBlending,
- depthTest: true,
- depthWrite: false,
- transparent: true,
- vertexColors: true,
- })
- this.geometry = new THREE.BufferGeometry()
- this.geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
- this.geometry.setAttribute('color', new THREE.Float32BufferAttribute([], 4));
- this.points.geometry = this.geometry
- this.points.material = this.material
- this.particles = []
- // this.ship = RE.getComponent(Player, this.object3d)
- this.updateGeometry()
- }
- awake() {
- }
- update() {
- // if(this.ship.isThrusting) {
- // this.addParticles();
- // }
- this.updateParticles(RE.Runtime.deltaTime);
- this.updateGeometry();
- }
- addParticles() {
- if(this.particles.length >= this.maxParticles) {
- return
- }
- for (let i = 0; i < 1; i++) {
- const life = this.particleLifespan;
- const newPosition = new THREE.Vector3()
- this.spawnLocation.getWorldPosition(newPosition)
-
- newPosition.add(new THREE.Vector3(
- 1 * Math.random() - 0.5,
- 1 * Math.random() - 0.5,
- 1 * Math.random() - 0.5
- ).multiply(this.positionRandomBounds))
- const newVelocity = this.initialVelocity.clone()
- // if(this.ship) {
- // newVelocity.add(new THREE.Vector3(
- // -this.ship.bodyComponent.body.force.x,
- // -this.ship.bodyComponent.body.force.y,
- // -this.ship.bodyComponent.body.force.z))
- // }
- newVelocity.add(new THREE.Vector3(
- 1 * Math.random() - 0.5,
- 1 * Math.random() - 0.5,
- 1 * Math.random() - 0.5
- ).multiply(this.velocityRandomBounds))
- newVelocity.multiplyScalar(this.thrustScalar)
- // const thrustVelocity = new THREE.Vector3(
- // -this.ship.bodyComponent.body.force.x,
- // -this.ship.bodyComponent.body.force.y,
- // -this.ship.bodyComponent.body.force.z)
-
- // thrustVelocity.multiply(this.velocityRandomBounds)
- // thrustVelocity.multiplyScalar(this.thrustScalar)
- this.particles.push({
- position: newPosition,
- life: life,
- maxLife: life,
- velocity: newVelocity,
- color: this.particleColor,
- alpha: this.particleAlpha,
- });
- }
- }
-
- updateGeometry() {
- const positions = [];
- const colors = []
-
- for (let p of this.particles) {
- positions.push(p.position.x, p.position.y, p.position.z);
- colors.push(p.color.r, p.color.g, p.color.b, p.alpha);
- }
-
- this.geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
- this.geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 4));
-
- this.geometry.attributes.position.needsUpdate = true;
- this.geometry.attributes.color.needsUpdate = true;
- }
-
- updateParticles(deltaTime) {
- for (let p of this.particles) {
- p.life -= deltaTime;
- }
-
- this.particles = this.particles.filter(p => {
- return p.life > 0.0;
- });
-
- for (let p of this.particles) {
- p.position.add(p.velocity.clone());
- }
- // RE.Debug.log(JSON.stringify(this.particles[0].position))
- let camera = RE.App.currentScene.getObjectByProperty('uuid', RE.App.activeCamera)
-
- this.particles.sort((a, b) => {
- const d1 = camera.position.distanceTo(a.position);
- const d2 = camera.position.distanceTo(b.position);
-
- if (d1 > d2) {
- return -1;
- }
-
- if (d1 < d2) {
- return 1;
- }
-
- return 0;
- });
- }
- }
- RE.registerComponent(ParticleSystem)
|