123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- #version 300 es
- #define PI 3.14159
- uniform float currentCount;
- uniform float timeDelta;
- uniform float stopFactor;
- uniform mat4 emitterWM;
- uniform vec2 lifeTime;
- uniform vec2 emitPower;
- uniform vec2 sizeRange;
- uniform vec4 scaleRange;
- #ifndef COLORGRADIENTS
- uniform vec4 color1;
- uniform vec4 color2;
- #endif
- uniform vec3 gravity;
- uniform sampler2D randomSampler;
- uniform sampler2D randomSampler2;
- uniform vec4 angleRange;
- #ifdef BOXEMITTER
- uniform vec3 direction1;
- uniform vec3 direction2;
- uniform vec3 minEmitBox;
- uniform vec3 maxEmitBox;
- #endif
- #ifdef SPHEREEMITTER
- uniform float radius;
- uniform float radiusRange;
- #ifdef DIRECTEDSPHEREEMITTER
- uniform vec3 direction1;
- uniform vec3 direction2;
- #else
- uniform float directionRandomizer;
- #endif
- #endif
- #ifdef CONEEMITTER
- uniform vec2 radius;
- uniform float coneAngle;
- uniform vec2 height;
- uniform float directionRandomizer;
- #endif
- // Particles state
- in vec3 position;
- in float age;
- in float life;
- in vec4 seed;
- in vec3 size;
- #ifndef COLORGRADIENTS
- in vec4 color;
- #endif
- in vec3 direction;
- #ifndef BILLBOARD
- in vec3 initialDirection;
- #endif
- #ifdef ANGULARSPEEDGRADIENTS
- in float angle;
- #else
- in vec2 angle;
- #endif
- #ifdef ANIMATESHEET
- in float cellIndex;
- #endif
- // Output
- out vec3 outPosition;
- out float outAge;
- out float outLife;
- out vec4 outSeed;
- out vec3 outSize;
- #ifndef COLORGRADIENTS
- out vec4 outColor;
- #endif
- out vec3 outDirection;
- #ifndef BILLBOARD
- out vec3 outInitialDirection;
- #endif
- #ifdef ANGULARSPEEDGRADIENTS
- out float outAngle;
- #else
- out vec2 outAngle;
- #endif
- #ifdef ANIMATESHEET
- out float outCellIndex;
- #endif
- #ifdef SIZEGRADIENTS
- uniform sampler2D sizeGradientSampler;
- #endif
- #ifdef ANGULARSPEEDGRADIENTS
- uniform sampler2D angularSpeedGradientSampler;
- #endif
- #ifdef VELOCITYGRADIENTS
- uniform sampler2D velocityGradientSampler;
- #endif
- #ifdef NOISE
- uniform vec3 noiseStrength;
- uniform sampler2D noiseSampler;
- #endif
- #ifdef ANIMATESHEET
- uniform vec3 cellInfos;
- #endif
- vec3 getRandomVec3(float offset) {
- return texture(randomSampler2, vec2(float(gl_VertexID) * offset / currentCount, 0)).rgb;
- }
- vec4 getRandomVec4(float offset) {
- return texture(randomSampler, vec2(float(gl_VertexID) * offset / currentCount, 0));
- }
- void main() {
- if (age >= life) {
- if (stopFactor == 0.) {
- outPosition = position;
- outAge = life;
- outLife = life;
- outSeed = seed;
- #ifndef COLORGRADIENTS
- outColor = vec4(0.,0.,0.,0.);
- #endif
- outSize = vec3(0., 0., 0.);
- #ifndef BILLBOARD
- outInitialDirection = initialDirection;
- #endif
- outDirection = direction;
- outAngle = angle;
- #ifdef ANIMATESHEET
- outCellIndex = cellIndex;
- #endif
- return;
- }
- vec3 position;
- vec3 direction;
- // Let's get some random values
- vec4 randoms = getRandomVec4(seed.x);
- // Age and life
- outAge = 0.0;
- outLife = lifeTime.x + (lifeTime.y - lifeTime.x) * randoms.r;
- // Seed
- outSeed = seed;
- // Size
- #ifdef SIZEGRADIENTS
- outSize.x = texture(sizeGradientSampler, vec2(0, 0)).r;
- #else
- outSize.x = sizeRange.x + (sizeRange.y - sizeRange.x) * randoms.g;
- #endif
- outSize.y = scaleRange.x + (scaleRange.y - scaleRange.x) * randoms.b;
- outSize.z = scaleRange.z + (scaleRange.w - scaleRange.z) * randoms.a;
- #ifndef COLORGRADIENTS
- // Color
- outColor = color1 + (color2 - color1) * randoms.b;
- #endif
- // Angular speed
- #ifndef ANGULARSPEEDGRADIENTS
- outAngle.y = angleRange.x + (angleRange.y - angleRange.x) * randoms.a;
- outAngle.x = angleRange.z + (angleRange.w - angleRange.z) * randoms.r;
- #else
- outAngle = angleRange.z + (angleRange.w - angleRange.z) * randoms.r;
- #endif
- // Position / Direction (based on emitter type)
- #ifdef BOXEMITTER
- vec3 randoms2 = getRandomVec3(seed.y);
- vec3 randoms3 = getRandomVec3(seed.z);
- position = minEmitBox + (maxEmitBox - minEmitBox) * randoms2;
- direction = direction1 + (direction2 - direction1) * randoms3;
- #elif defined(SPHEREEMITTER)
- vec3 randoms2 = getRandomVec3(seed.y);
- vec3 randoms3 = getRandomVec3(seed.z);
- // Position on the sphere surface
- float phi = 2.0 * PI * randoms2.x;
- float theta = acos(2.0 * randoms2.y - 1.0);
- float randX = cos(phi) * sin(theta);
- float randY = cos(theta);
- float randZ = sin(phi) * sin(theta);
- position = (radius - (radius * radiusRange * randoms2.z)) * vec3(randX, randY, randZ);
- #ifdef DIRECTEDSPHEREEMITTER
- direction = direction1 + (direction2 - direction1) * randoms3;
- #else
- // Direction
- direction = position + directionRandomizer * randoms3;
- #endif
- #elif defined(CONEEMITTER)
- vec3 randoms2 = getRandomVec3(seed.y);
- float s = 2.0 * PI * randoms2.x;
- float h = randoms2.y * height.y;
-
- // Better distribution in a cone at normal angles.
- h = 1. - h * h;
- float lRadius = radius.x - radius.x * randoms2.z * radius.y;
- lRadius = lRadius * h;
- float randX = lRadius * sin(s);
- float randZ = lRadius * cos(s);
- float randY = h * height.x;
- position = vec3(randX, randY, randZ);
- // Direction
- if (abs(cos(coneAngle)) == 1.0) {
- direction = vec3(0., 1.0, 0.);
- } else {
- vec3 randoms3 = getRandomVec3(seed.z);
- direction = position + directionRandomizer * randoms3;
- }
- #else
- // Create the particle at origin
- position = vec3(0., 0., 0.);
- // Spread in all directions
- direction = 2.0 * (getRandomVec3(seed.w) - vec3(0.5, 0.5, 0.5));
- #endif
- float power = emitPower.x + (emitPower.y - emitPower.x) * randoms.a;
- outPosition = (emitterWM * vec4(position, 1.)).xyz;
- vec3 initial = (emitterWM * vec4(normalize(direction), 0.)).xyz;
- outDirection = initial * power;
- #ifndef BILLBOARD
- outInitialDirection = initial;
- #endif
- #ifdef ANIMATESHEET
- outCellIndex = cellInfos.x;
- #endif
- } else {
- float directionScale = timeDelta;
- float ageGradient = age / life;
- #ifdef VELOCITYGRADIENTS
- directionScale *= texture(velocityGradientSampler, vec2(ageGradient, 0)).r;
- #endif
- outPosition = position + direction * directionScale;
- outAge = age + timeDelta;
- outLife = life;
- outSeed = seed;
- #ifndef COLORGRADIENTS
- outColor = color;
- #endif
- #ifdef SIZEGRADIENTS
- outSize.x = texture(sizeGradientSampler, vec2(ageGradient, 0)).r;
- outSize.yz = size.yz;
- #else
- outSize = size;
- #endif
- #ifndef BILLBOARD
- outInitialDirection = initialDirection;
- #endif
- outDirection = direction + gravity * timeDelta;
- #ifdef NOISE
- vec3 localPosition = outPosition - emitterWM[3].xyz;
- float fetchedR = texture(noiseSampler, vec2(localPosition.y, localPosition.z) * vec2(0.5) + vec2(0.5)).r;
- float fetchedG = texture(noiseSampler, vec2(localPosition.x + 0.33, localPosition.z + 0.33) * vec2(0.5) + vec2(0.5)).r;
- float fetchedB = texture(noiseSampler, vec2(localPosition.z - 0.33, localPosition.y - 0.33) * vec2(0.5) + vec2(0.5)).r;
- vec3 force = vec3(2. * fetchedR - 1., 2. * fetchedG - 1., 2. * fetchedB - 1.) * noiseStrength;
- outDirection = outDirection + force * timeDelta;
- #endif
- #ifdef ANGULARSPEEDGRADIENTS
- float angularSpeed = texture(angularSpeedGradientSampler, vec2(ageGradient, 0)).r;
- outAngle = angle + angularSpeed * timeDelta;
- #else
- outAngle = vec2(angle.x + angle.y * timeDelta, angle.y);
- #endif
- #ifdef ANIMATESHEET
- float dist = cellInfos.y - cellInfos.x;
- float ratio = clamp(mod(outAge * cellInfos.z, life) / life, 0., 1.0);
- outCellIndex = float(int(cellInfos.x + ratio * dist));
- #endif
- }
- }
|