particleSystemChunk = `
${myRandChunk}
${easingChunk}
${zoneChunk}
${transformChunk}
mat4 emitterTransform(float timeSec) {
return translate(vec3(-250.0 + 500.0 * fract(timeSec * 0.2), 10.0, 0.0));
}
// Calculates a transform of a single particle at a given time of its lifespan
// given the myRand is procedurally seeded per particle
// @ particleTimeSec - time in [0, lifeSec)
// @ t - phase in [0, 1),
// @ iteration - an integer iteration of particle instance (each iteration seeds another particle)
mat4 particleTransform(in float particleTimeSec, in float t, in float iteration) {
return identity
// * translate(vec3(t * 30.0, 0.0, 0.0))
* scale(mix(vec3(1.0), vec3(randInRange(0.0, 3.0)), abs(sin(t * PI * 5.0))))
// * translate(randInBoxZone(vec3(0.0, -2.0, -2.0), vec3(0.0, 2.0, 2.0))) // initial position in a (flat) box
* translate(vec3(0.0, randInBallZone().yz) * 2.0) // initial position in a ball
* scale(mix(vec3(0.0), vec3(randInRange(0.05, 0.1)), abs(sin(t * PI * 5.0))))
* identity;
}
// Prepares particle iteration variables, seeds the random, returns particle transform
mat4 particleMain(in float timeSec, in float seed, bool debug) {
// if (debug) { return emitterTransform(timeSec); }
if (gl_InstanceID < 10) {
return identity
* translate(vec3(-250.0 + 500.0 * fract((timeSec + float(gl_InstanceID) + 0.5) * 0.2), 10.0, 0.0))
* scale(vec3(1.0))
* identity;
}
myRandSeed = seed;
float lifeSec = randInRange(5.0, 5.0);
float initialLifeOffsetSec = randInRange(-lifeSec, 0.0);
float iterationWithPhase = (timeSec + initialLifeOffsetSec) / lifeSec;
float iteration = floor(iterationWithPhase);
float t = fract(iterationWithPhase);
float particleTimeSec = t * lifeSec;
float emissionTimeSec = timeSec - particleTimeSec;
float iterationSeed = fract(iteration * 1e-10);
myRandSeed = fract(myRandSeed + iterationSeed); // reseed rand for every iteration
return emitterTransform(emissionTimeSec) * particleTransform(particleTimeSec, t, iteration);
}
`