Particle system
Make writing a habit together! This is the fourth day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.
Particle system: this paper lists some common scenes such as: snowy day, rainy day, firefly, starry sky, smoke, explosion, flame, cloudy, haze - Point particle - custom shader - map - motion animation and particle survival time through the point particle carrying map with custom coloring equipment quality, control particle movement track and survival time, during the survival time control particle transparency and position and color, size, etcCopy the code
Effect of particle
Here the particle is unified encapsulation, a brief introduction to the relevant properties: positionBase: the initial position of the particle generationnew THREE.Vector3
positionRadius: rounded cornerspositionSpread: Particle rangenew THREE.Vector3
velocityBase: Speed Of motion Speed in three dimensional coordinate directionnew THREE.Vector3
velocityBase: Range of motionnew THREE.Vector3
accelerationBase: Acceleration of motion Acceleration in the direction of three dimensional coordinatesnew THREE.Vector3
particleTexture: mapsizeTween: particle sizeopacityTween: Particle transparencycolorTweenParticlesPerSecond: specifies the number of particlesparticleDeathAge: Single particle survival timeemitterDeathAge: Animation durationCopy the code
snow
Snow particle object: The related properties are described above, mainly through mapping and particle animationCopy the code
snow :
{
positionStyle : Type.CUBE,
positionBase : new THREE.Vector3( 0.200.0 ),
positionSpread : new THREE.Vector3( 400.0.400 ),
velocityStyle : Type.CUBE,
velocityBase : new THREE.Vector3( 50, -200.0 ),
velocitySpread : new THREE.Vector3( 50.200.50 ),
accelerationBase : new THREE.Vector3( 0, -10.0 ),
angleBase : 0.angleSpread : 720.angleVelocityBase : 0.angleVelocitySpread : 60.particleTexture : textureLoader.load(gAppPath+'images/snowflake.png' ),
sizeTween : new Tween( [0.0.25], [4.5]),colorBase : new THREE.Vector3(0.66.1.0.0.9), // H,S,L
opacityTween : new Tween( [2.3], [0.8.0]),particlesPerSecond : 500.particleDeathAge : 1.0.emitterDeathAge : 60
},
Copy the code
fireflies
Firefly particle object: The related properties are described above, mainly through mapping and particle animationCopy the code
fireflies :
{
positionStyle : Type.CUBE,
positionBase : new THREE.Vector3( 0.100.0 ),
positionSpread : new THREE.Vector3( 400.200.400 ),
velocityStyle : Type.CUBE,
velocityBase : new THREE.Vector3( 0.0.0 ),
velocitySpread : new THREE.Vector3( 60.20.60 ),
particleTexture : textureLoader.load(gAppPath+'images/spark.png' ),
sizeBase : 30.0.sizeSpread : 10.0.opacityTween : new Tween([0.0.1.0.1.1.2.0.2.1.3.0.3.1.4.0.4.1.5.0.5.1.6.0.6.1],
[0.2.0.2.1.0.1.0.0.2.0.2.1.0.1.0.0.2.0.2.1.0.1.0.0.2]),colorBase : new THREE.Vector3(0.30.1.0.0.6), // H,S,L
colorSpread : new THREE.Vector3(0.3.0.0.0.0),
particlesPerSecond : 20.particleDeathAge : 6.1.emitterDeathAge : 600
},
Copy the code
smoke
Smoke particle object: The related properties are described above, mainly through mapping and particle animationCopy the code
smoke :
{
positionStyle : Type.CUBE,
positionBase : new THREE.Vector3( 0.0.0 ),
positionSpread : new THREE.Vector3( 2.0.2 ),
velocityStyle : Type.CUBE,
velocityBase : new THREE.Vector3( 0.40.0 ),
velocitySpread : new THREE.Vector3( 20.40.20 ),
accelerationBase : new THREE.Vector3( 0, -10.0 ),
particleTexture : textureLoader.load(gAppPath+'images/smokeparticle.png'),
speedBase : 10.speedSpread : 10.angleBase : 0.angleSpread : 720.angleVelocityBase : 0.angleVelocitySpread : 720.sizeTween : new Tween( [0.1], [32.128]),opacityTween : new Tween( [0.8.2], [0.5.0]),colorTween : new Tween( [0.4.1], [ new THREE.Vector3(0.0.0.2), new THREE.Vector3(0.0.0.5)),particlesPerSecond : 6.particleDeathAge : 2.0.emitterDeathAge : 5
},
Copy the code
The explosion
Explosive particle object: The related properties are described above, mainly through mapping and particle animationCopy the code
fireball :
{
positionStyle : Type.SPHERE,
positionBase : new THREE.Vector3( 0.50.0 ),
positionRadius : 2.velocityStyle : Type.SPHERE,
speedBase : 10.speedSpread : 50.particleTexture : textureLoader.load(gAppPath+'images/smokeparticle.png' ),
sizeTween : new Tween( [0.0.1], [1.50]),opacityTween : new Tween( [0.7.1], [1.0]),colorBase : new THREE.Vector3(0.02.1.0.4),
blendStyle : THREE.AdditiveBlending,
particlesPerSecond : 300.particleDeathAge : 0.5.emitterDeathAge : 60
},
Copy the code
The starry sky
Star particle object: The related properties are described above, mainly through mapping and particle animationCopy the code
starfield :
{
positionStyle : Type.CUBE,
positionBase : new THREE.Vector3( 0.100.0 ),
positionSpread : new THREE.Vector3( 400.100.400 ),
velocityStyle : Type.CUBE,
velocityBase : new THREE.Vector3( 0.0.0 ),
velocitySpread : new THREE.Vector3( 0.5.0.5.0.5 ),
angleBase : 0.angleSpread : 720.angleVelocityBase : 0.angleVelocitySpread : 4.particleTexture : textureLoader.load(gAppPath+'images/spikey.png' ),
sizeBase : 10.0.sizeSpread : 2.0.colorBase : new THREE.Vector3(0.15.1.0.0.9), // H,S,L
colorSpread : new THREE.Vector3(0.00.0.0.0.2),
opacityBase : 1.particlesPerSecond : 1000.particleDeathAge : 60.0.emitterDeathAge : 0.1
},
Copy the code
The rain
Rain particle object: The related properties are described above, mainly through mapping and particle animationCopy the code
rain :
{
positionStyle : Type.CUBE,
positionBase : new THREE.Vector3( 0.200.0 ),
positionSpread : new THREE.Vector3( 400.0.400 ),
velocityStyle : Type.CUBE,
velocityBase : new THREE.Vector3( 0, -700.0 ),
velocitySpread : new THREE.Vector3( 10.50.10 ),
accelerationBase : new THREE.Vector3( 0, -10.0 ),
particleTexture : textureLoader.load(gAppPath+'images/raindrop2flip.png' ),
sizeBase : 8.sizeSpread : 4.0.colorBase : new THREE.Vector3(0.66.1.0.0.75), // H,S,L
colorSpread : new THREE.Vector3(0.0.0.0.1),
opacityBase : 0.4.particlesPerSecond : 600.particleDeathAge : 1.0.emitterDeathAge : 60
},
Copy the code
The flame
Fire particle object: The properties are described above, mainly through mapping and particle animationCopy the code
candle :
{
positionStyle : Type.SPHERE,
positionBase : new THREE.Vector3( 0.50.0 ),
positionRadius : 2.velocityStyle : Type.CUBE,
velocityBase : new THREE.Vector3(0.30.0),
velocitySpread : new THREE.Vector3(20.0.20),
speedBase : 10.speedSpread : 10.particleTexture : textureLoader.load(gAppPath+'images/smokeparticle.png' ),
sizeTween : new Tween( [0.0.3.1.2], [20.15.1]),opacityTween : new Tween( [0.9.1.5], [1.0]),colorTween : new Tween( [0.5.1.0], [ new THREE.Vector3(0.02.1.0.5), new THREE.Vector3(0.05.1.0)),blendStyle : THREE.AdditiveBlending,
particlesPerSecond : 600.particleDeathAge : 104.emitterDeathAge : 10
}
Copy the code
cloud
Cloud particle object: The related properties are described above, mainly through mapping and particle animationCopy the code
clouds :
{
positionStyle : Type.CUBE,
positionBase : new THREE.Vector3( -100.100.0 ),
positionSpread : new THREE.Vector3( 0.10.60 ),
velocityStyle : Type.CUBE,
velocityBase : new THREE.Vector3( 100.0.0 ),
velocitySpread : new THREE.Vector3( 100.0.0 ),
particleTexture : textureLoader.load(gAppPath+'images/smokeparticle.png'),
sizeBase : 80.0.sizeSpread : 100.0.colorBase : new THREE.Vector3(0.0.0.0.1.0), // H,S,L
opacityTween : new Tween([0.1.4.5], [0.1.1.0]),
particlesPerSecond : 100.particleDeathAge : 10.0.emitterDeathAge : 60
},
Copy the code
haze
Haze particle object: Related properties are described above, mainly through mapping and particle animationCopy the code
haze: / / the fog haze
{
positionStyle: Type.CUBE,
positionBase: new THREE.Vector3(0.50.0),
positionSpread: new THREE.Vector3(400.100.400),
velocityStyle: Type.CUBE,
velocityBase: new THREE.Vector3(0.0.0),
velocitySpread: new THREE.Vector3(100.5.0.5.100.5),
angleBase: 0.angleSpread: 0.angleVelocityBase: 0.angleVelocitySpread: 4.particleTexture: textureLoader.load(gAppPath + 'images/smoke512.png'),
sizeBase: 1000.0.sizeSpread: 2.0.colorBase: new THREE.Vector3(0.15.1.0.0), // H,S,L
colorSpread: new THREE.Vector3(0.00.0.0.0.2),
opacityBase: 0.15.particlesPerSecond: 1000.particleDeathAge: 60.0.emitterDeathAge: 0.1
},
Copy the code
Particle class
Here, through the form of class, the particle system has made an overall encapsulation, and I will analyze most of the ideas. Class is divided into: -tween class (according to the time interval and value interval of particle object sizeTween, opacityTween and colorBase, ParticleEngine ParticleEngine ParticleEngine ParticleEngine ParticleEngine ParticleEngine ParticleEngine ParticleEngineCopy the code
Tween
Call example: new Tween([0, 1], [1, 10]) The main function of this class is to obtain the values of size, color, and opacity by passing t into timeArrayCopy the code
class Tween {
constructor(timeArray, valueArray) {
this.times = timeArray || []
this.values = valueArray || []
}
lerp(t) {
var i = 0
var n = this.times.length
while (i < n && t > this.times[i]) {
i++
}
if (i == 0) {
return this.values[0]}if (i == n) {
return this.values[n - 1]}var p = (t - this.times[i - 1)/(this.times[i] - this.times[i - 1])
if (this.values[0] instanceof THREE.Vector3) {
return this.values[i - 1].clone().lerp(this.values[i], p)
} else // its a float
{
return this.values[i - 1] + p * (this.values[i] - this.values[i - 1])}}}Copy the code
Particle
Var particle = new particle () Resolution: This class is used to create particles, just single particles. By randomly generating the position of the particle in a specific range, continuously accumulating vector scalars, vector scalars constantly increasing simulation acceleration, control Angle (draw in custom shader), control size, color, transparencyCopy the code
class Particle {
constructor() {
this.position = new THREE.Vector3() // Particle position
this.velocity = new THREE.Vector3() // Scalar vectors
this.acceleration = new THREE.Vector3()
this.angle = 0 / / Angle
this.angleVelocity = 0
this.angleAcceleration = 0
this.size = 16.0
this.color = new THREE.Color()
this.opacity = 1.0
this.age = 0 // Survival time
this.alive = 0 // Whether to display
}
update(dt) { // Particle property update function
this.position.add(this.velocity.clone().multiplyScalar(dt))// Add the vectors and move the particles
this.velocity.add(this.acceleration.clone().multiplyScalar(dt))// Add the sum of vectors to simulate acceleration
this.angle += this.angleVelocity * 0.01745329251 * dt / / Angle
this.angleVelocity += this.angleAcceleration * 0.01745329251 * dt / / angular velocity
this.age += dt // Add the particle lifetime
if (this.sizeTween.times.length > 0) {
this.size = this.sizeTween.lerp(this.age) / / size
}
if (this.colorTween.times.length > 0) {
var colorHSL = this.colorTween.lerp(this.age)
this.color = new THREE.Color().setHSL(colorHSL.x, colorHSL.y, colorHSL.z)/ / color
}
if (this.opacityTween.times.length > 0) {
this.opacity = this.opacityTween.lerp(this.age)/ / transparency}}}Copy the code
ParticleEngine
Particle class functions: -setvalues Initializes the properties of the particle class by particle type. -createparticle creates a particle, randomly generating the values of its position, color, Angle, size, transparency, etc. -Initialize Initializes the particle scene. Generate all particles by the number of particles and add the -update particle property update function with the scene, Particle update loop system - destroy Destroy particle - randomVector3 Randomly generates a 3D coordinate based on a specific range and initial position - randomValue Generates a random Angle based on the initial Angle and the range of anglesCopy the code
Examples of global particle calls:import {ParticleEngine} from 'zhdPartice'
import ParticleEngineExamples from 'zhdParticleExamples'
initParticle = function () {
this.particle = new ParticleEngine()
this.particle.setValues(ParticleEngineExamples.candle, {
positionBase: new THREE.Vector3(0.0.0})),this.particle.initialize(this.scene)
this.renderFunction.push(() = > {
if (this.particle) this.particle.update(0.01)})}Copy the code
shader
The shader code is as follows, not expanded here.Copy the code
const particleVertexShader =
[
'attribute vec3 customColor;'.'attribute float customOpacity; '.'attribute float customSize; '.'attribute float customAngle; '.'attribute float customVisible; '.// float used as boolean (0 = false, 1 = true)
'varying vec4 vColor;'.'varying float vAngle; '.'void main()'.'{'.'If (customVisible > 0.5)'.// true
'vColor = vec4( customColor, customOpacity ); '.// set color associated to vertex; use later in fragment shader.
'else'.// false
'vColor = vec4,0,0,0 (0); '.// make particle invisible.
'vAngle = customAngle; '.'vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); '.'gl_PointSize = customSize * (300.0 / length(mvposition.xyz)); '.// scale particles as objects in 3D space
'gl_Position = projectionMatrix * mvPosition; '.'} '
].join('\n')
const particleFragmentShader =
[
'uniform sampler2D mytexture; '.'varying vec4 vColor; '.'varying float vAngle; '.'void main()'.'{'.'gl_FragColor = vColor; '.'float c = cos(vAngle); '.'float s = sin(vAngle); '.Vec2 rotatedUV = vec2(c * (gl_pointcoord.x-0.5) + s * (gl_pointcoord.y-0.5) + 0.5,'.'c * * (gl_PointCoord. Y - 0.5) - s (gl_PointCoord. X - 0.5 + 0.5); '.// rotate UV coordinates to rotate texture
'vec4 rotatedTexture = texture2D( mytexture, rotatedUV );'.'gl_FragColor = gl_FragColor * rotatedTexture; '.// sets an otherwise white particle texture to desired color
'} '
].join('\n')
Copy the code
setValues
Generate the initialization properties of the particle through the type and the new object.Copy the code
setValues(parameters,params) {
/ * * * *@param Whether the mugen loops indefinitely *@param Number of particlesPerSecond particles *@param ParticleDeathAge Lifetime of each particle *@param EmitterDeathAge Duration mugen valid for false *@param PositionBase obj Particle system initial position xyz *@param PositionSpread OBj Particle range xyz *@param The velocityBase particle moves in the xzy direction with a velocity xyz *@param VelocitySpread The range of motion of the particle along the xzy direction */
this.mugen = params.mugen||false // Infinite loop
if (parameters === undefined) {
return
}
let obj=Object.assign(parameters,params) // Override the original attribute values
this.sizeTween = new Tween() / / size
this.colorTween = new Tween() / / color
this.opacityTween = new Tween()/ / transparency
for (var key in obj) { // Initialize parameter assignment
this[key] = obj[key]
}
Particle.prototype.sizeTween = this.sizeTween
Particle.prototype.colorTween = this.colorTween
Particle.prototype.opacityTween = this.opacityTween
this.particleArray = [] // Particle collection
this.emitterAge = 0.0
this.emitterAlive = true
this.particleCount = this.particlesPerSecond * Math.min(this.particleDeathAge, this.emitterDeathAge)// Number of particles
// Material dependent
this.particleGeometry = new THREE.BufferGeometry()
this.particleMaterial = new THREE.ShaderMaterial(
{
uniforms: {
mytexture: {value: this.particleTexture},
},
vertexShader: particleVertexShader,
fragmentShader: particleFragmentShader,
blending: THREE.AdditiveBlending,
depthTest: false.transparent: true.vertexColors: true})}Copy the code
createParticle
Create a particle. Initialize the position, Angle, size, transparency, color, life time, display and other properties of the particle randomly generated within a specific range according to the properties of the particle object. The corresponding annotations have been made in the code. Because of the close correlation, it is necessary to combine the code before and after to understand the code ~~Copy the code
createParticle() {
var particle = new Particle() // Initializes the creation of the particle class
// Initializes random generation of corresponding attribute values according to the particle type
if (this.positionStyle == Type.CUBE) {
particle.position = this.randomVector3(this.positionBase, this.positionSpread)/ / position
}
if (this.positionStyle == Type.SPHERE) {
var z = 2 * Math.random() - 1
var t = 6.2832 * Math.random()
var r = Math.sqrt(1 - z * z)
var vec3 = new THREE.Vector3(r * Math.cos(t), r * Math.sin(t), z)
particle.position = new THREE.Vector3().addVectors(this.positionBase, vec3.multiplyScalar(this.positionRadius))
}
if (this.velocityStyle == Type.CUBE) {
particle.velocity = this.randomVector3(this.velocityBase, this.velocitySpread)// Vector scalars
}
if (this.velocityStyle == Type.SPHERE) {
var direction = new THREE.Vector3().subVectors(particle.position, this.positionBase)
var speed = this.randomValue(this.speedBase, this.speedSpread)
particle.velocity = direction.normalize().multiplyScalar(speed)
}
particle.acceleration = this.randomVector3(this.accelerationBase, this.accelerationSpread)// Scalar summation vector
particle.angle = this.randomValue(this.angleBase, this.angleSpread)/ / Angle
particle.angleVelocity = this.randomValue(this.angleVelocityBase, this.angleVelocitySpread)
particle.angleAcceleration = this.randomValue(this.angleAccelerationBase, this.angleAccelerationSpread)
particle.size = this.randomValue(this.sizeBase, this.sizeSpread)/ / size
var color = this.randomVector3(this.colorBase, this.colorSpread)/ / color
particle.color = new THREE.Color().setHSL(color.x, color.y, color.z)
particle.opacity = this.randomValue(this.opacityBase, this.opacitySpread)/ / transparency
particle.age = 0// Survival time
particle.alive = 0 // Whether to display
return particle
}
Copy the code
initialize
Initialize the particle scene, generate the BufferGeometry and material generation point particle set through traversal, and add it to the scene. Record all the attributes of each particle, and control the values of the related attributes of the particle through setAttribute. The custom related attributes indirectly affect the particle color, explicit and implicit, size, transparency and other attributes in the custom shaderCopy the code
initialize(scene) {
var positions = []
var customVisibles = []
var customColor = []
var customOpacity = []
var customSize = []
var customAngle = []
for (var i = 0; i < this.particleCount; i++) { // Iterates to generate the corresponding number of BufferGeometry
this.particleArray[i] = this.createParticle()
positions.push(this.particleArray[i].position.x)
positions.push(this.particleArray[i].position.y)
positions.push(this.particleArray[i].position.z)
// Custom shader related
customVisibles.push(this.particleArray[i].alive)
customColor.push(this.particleArray[i].color.r)
customColor.push(this.particleArray[i].color.g)
customColor.push(this.particleArray[i].color.b)
customOpacity.push(this.particleArray[i].opacity)
customSize.push(this.particleArray[i].size)
customAngle.push(this.particleArray[i].angle)
}
this.positions = positions // Array of positions
this.customVisibles = customVisibles // Implicit array
this.customColor = customColor// Color array
this.customOpacity = customOpacity// Transparency array
this.customSize = customSize// Size array
this.customAngle = customAngle// Angle array
// Sets the attribute attribute of BufferGeometry
this.particleGeometry.setAttribute('position'.new THREE.Float32BufferAttribute(this.positions, 3))
this.particleGeometry.setAttribute('customVisible'.new THREE.Float32BufferAttribute(this.customVisibles, 1))
this.particleGeometry.setAttribute('customColor'.new THREE.Float32BufferAttribute(this.customColor, 3))
this.particleGeometry.setAttribute('customOpacity'.new THREE.Float32BufferAttribute(this.customOpacity, 1))
this.particleGeometry.setAttribute('customSize'.new THREE.Float32BufferAttribute(this.customSize, 1))
this.particleGeometry.setAttribute('customAngle'.new THREE.Float32BufferAttribute(this.customAngle, 1))
this.particleMaterial.blending = this.blendStyle
if (this.blendStyle ! == THREE.NormalBlending) {this.particleMaterial.depthTest = false
}
/ / involves
this.particleMesh = new THREE.Points(this.particleGeometry, this.particleMaterial)
this.particleMesh.dynamic = true
this.particleMesh.sortParticles = true
scene.add(this.particleMesh)
}
Copy the code
update
Particle motion function analysis: update corresponding particle properties and shaders by traversing particles, record invalid particle subscripts, and generate new particles by subscripts. Particle transition from nothing: generate the corresponding percentage of particles according to the existence time of the particle scene and the end time of the particle scene, and control whether the particle animation stops within the specified time or continues indefinitely according to the infinite loop. Particlearray. update Updates the positions of particles by subscripting them in groups of threeCopy the code
update(dt) {
var recycleIndices = []
for (var i = 0; i < this.particleCount; i++) {// Walk through the particles in the scene
if (this.particleArray[i].alive) {
this.particleArray[i].update(dt) // Particle properties updated
if (this.particleArray[i].age > this.particleDeathAge) { // Determine whether the particle has survived for longer than the specified time
this.particleArray[i].alive = 0.0 // Hide particles
recycleIndices.push(i)// Void particle index array
}
// Update the shader specific properties array
this.customVisibles[i] = this.particleArray[i].alive
this.customColor[i * 3] = this.particleArray[i].color.r
this.customColor[i * 3 + 1] = this.particleArray[i].color.g
this.customColor[i * 3 + 2] = this.particleArray[i].color.b
this.customOpacity[i] = this.particleArray[i].opacity
this.customSize[i] = this.particleArray[i].size
this.customAngle[i] = this.particleArray[i].angle
}
}
// Sets the attribute attribute of BufferGeometry, shader dependent, color, size, position, and explicit and implicit effects
this.particleGeometry.setAttribute('customVisible'.new THREE.Float32BufferAttribute(this.customVisibles, 1))
this.particleGeometry.setAttribute('customColor'.new THREE.Float32BufferAttribute(this.customColor, 3))
this.particleGeometry.setAttribute('customOpacity'.new THREE.Float32BufferAttribute(this.customOpacity, 1))
this.particleGeometry.setAttribute('customSize'.new THREE.Float32BufferAttribute(this.customSize, 1))
this.particleGeometry.setAttribute('customAngle'.new THREE.Float32BufferAttribute(this.customAngle, 1))
this.particleGeometry.attributes.customVisible.needsUpdate = true
this.particleGeometry.attributes.customColor.needsUpdate = true
this.particleGeometry.attributes.customOpacity.needsUpdate = true
this.particleGeometry.attributes.customSize.needsUpdate = true
this.particleGeometry.attributes.customAngle.needsUpdate = true
if (!this.emitterAlive) return // The entire particle system is alive (particle animation time)
// Control the display of some particles of all particles, the longer the longer the number of particles, until all particles are displayed
if (this.emitterAge < this.particleDeathAge) { // If the time is not finished
var startIndex = Math.round(this.particlesPerSecond * (this.emitterAge + 0))
var endIndex = Math.round(this.particlesPerSecond * (this.emitterAge + dt))
if (endIndex > this.particleCount) { // Determine the number of particles
endIndex = this.particleCount
}
for (var i = startIndex; i < endIndex; i++) { //
this.particleArray[i].alive = 1.0}}for (var j = 0; j < recycleIndices.length; j++) // Failed particles are regenerated
{
var i = recycleIndices[j] // Get index subscript
this.particleArray[i] = this.createParticle() // Recreate the particle
this.particleArray[i].alive = 1.0 // Display particles
}
// Particle position changes
for (var j = 0; j < this.particleCount; j++) {
this.positions[j * 3] = this.particleArray[j].position.x
this.positions[j * 3 + 1] = this.particleArray[j].position.y
this.positions[j * 3 + 2] = this.particleArray[j].position.z
}
// In groups of three, update the particle positions of the entire BufferGeometry
this.particleGeometry.setAttribute('position'.new THREE.Float32BufferAttribute(this.positions, 3))
// Particle animation time accumulated
this.emitterAge += dt
if (!this.mugen) { // Whether the loop is infinite
if (this.emitterAge > this.emitterDeathAge) this.emitterAlive = false}}Copy the code
destroy
Destruction of the particleCopy the code
destroy(scene) {
scene.remove(this.particleMesh)
}
Copy the code
randomVector3
Generate a random 3 D coordinate based on a specific range and initial positionCopy the code
randomVector3(base, spread) {
var rand3 = new THREE.Vector3(Math.random() - 0.5.Math.random() - 0.5.Math.random() - 0.5)
return new THREE.Vector3().addVectors(base, new THREE.Vector3().multiplyVectors(spread, rand3))
}
Copy the code
randomValue
Generate a random Angle based on the initial Angle and the range of anglesCopy the code
randomValue(base, spread) {
return base + spread * (Math.random() - 0.5)}Copy the code
conclusion
Not easy to write, pig sigh! It took me a whole day to write this article. I tried my best to annotate the whole idea of the article. The amount of code was a bit much, but full of work! Hope the students who have harvest can gently point a praise ~
Of course, if you have any comments and don’t understand the place, you are welcome to put forward in the comment area, I will learn to make corrections ~~