123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- #version 300 es
- #define PI 3.14159
- uniform float currentCount;
- uniform float timeDelta;
- uniform vec3 generalRandoms;
- uniform mat4 emitterWM;
- uniform vec2 lifeTime;
- uniform vec2 emitPower;
- uniform vec2 sizeRange;
- uniform vec4 color1;
- uniform vec4 color2;
- uniform vec3 gravity;
- uniform sampler2D randomSampler;
- #ifdef BOXEMITTER
- uniform vec3 direction1;
- uniform vec3 direction2;
- uniform vec3 minEmitBox;
- uniform vec3 maxEmitBox;
- #endif
- #ifdef SPHEREEMITTER
- uniform float radius;
- #ifdef DIRECTEDSPHEREEMITTER
- uniform vec3 direction1;
- uniform vec3 direction2;
- #else
- uniform float directionRandomizer;
- #endif
- #endif
- #ifdef CONEEMITTER
- uniform float radius;
- uniform float angle;
- uniform float height;
- uniform float directionRandomizer;
- #endif
- // Particles state
- in vec3 position;
- in float age;
- in float life;
- in float seed;
- in float size;
- in vec4 color;
- in vec3 direction;
- // Output
- out vec3 outPosition;
- out float outAge;
- out float outLife;
- out float outSeed;
- out float outSize;
- out vec4 outColor;
- out vec3 outDirection;
- vec3 getRandomVec3(float offset) {
- return texture(randomSampler, 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) {
- vec3 position;
- vec3 direction;
- // Let's get some random values
- vec4 randoms = getRandomVec4(generalRandoms.x);
- // Age and life
- outAge = 0.0;
- outLife = lifeTime.x + (lifeTime.y - lifeTime.x) * randoms.r;
- // Seed
- outSeed = seed;
- // Size
- outSize = sizeRange.x + (sizeRange.y - sizeRange.x) * randoms.g;
- // Color
- outColor = color1 + (color2 - color1) * randoms.b;
- // Position / Direction (based on emitter type)
- #ifdef BOXEMITTER
- vec3 randoms2 = getRandomVec3(generalRandoms.y);
- vec3 randoms3 = getRandomVec3(generalRandoms.z);
- position = minEmitBox + (maxEmitBox - minEmitBox) * randoms2;
- direction = direction1 + (direction2 - direction1) * randoms3;
- #elif defined(SPHEREEMITTER)
- vec3 randoms2 = getRandomVec3(generalRandoms.y);
- vec3 randoms3 = getRandomVec3(generalRandoms.z);
- // Position on the sphere surface
- float phi = 2.0 * PI * randoms2.x;
- float theta = PI * randoms2.y;
- float randX = cos(phi) * sin(theta);
- float randY = cos(theta);
- float randZ = sin(phi) * sin(theta);
- position = radius * vec3(randX, randY, randZ);
- #ifdef DIRECTEDSPHEREEMITTER
- direction = direction1 + (direction2 - direction1) * randoms3;
- #else
- // Direction
- direction = position + directionRandomizer * randoms3;
- #endif
- #elif defined(CONEEMITTER)
- vec3 randoms2 = getRandomVec3(generalRandoms.y);
- float s = 2.0 * PI * randoms2.x;
- float h = randoms2.y;
-
- // Better distribution in a cone at normal angles.
- h = 1. - h * h;
- float lRadius = radius * randoms2.z;
- lRadius = lRadius * h / height;
- float randX = lRadius * sin(s);
- float randZ = lRadius * cos(s);
- float randY = h * height;
- position = vec3(randX, randY, randZ);
- // Direction
- if (angle == 0.) {
- direction = vec3(0., 1.0, 0.);
- } else {
- vec3 randoms3 = getRandomVec3(generalRandoms.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) - vec3(0.5, 0.5, 0.5));
- #endif
- float power = emitPower.x + (emitPower.y - emitPower.x) * randoms.a;
- outPosition = (emitterWM * vec4(position, 1.)).xyz;
- outDirection = (emitterWM * vec4(normalize(direction) * power, 0.)).xyz;
- } else {
- outPosition = position + (direction + gravity) * timeDelta;
- outAge = age + timeDelta;
- outLife = life;
- outSeed = seed;
- outColor = color;
- outSize = size;
- outDirection = direction;
- }
- }
|