gpuUpdateParticles.vertex.fx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #version 300 es
  2. #define PI 3.14159
  3. uniform float currentCount;
  4. uniform float timeDelta;
  5. uniform vec3 generalRandoms;
  6. uniform mat4 emitterWM;
  7. uniform vec2 lifeTime;
  8. uniform vec2 emitPower;
  9. uniform vec2 sizeRange;
  10. uniform vec4 color1;
  11. uniform vec4 color2;
  12. uniform vec3 gravity;
  13. uniform sampler2D randomSampler;
  14. #ifdef BOXEMITTER
  15. uniform vec3 direction1;
  16. uniform vec3 direction2;
  17. uniform vec3 minEmitBox;
  18. uniform vec3 maxEmitBox;
  19. #endif
  20. #ifdef SPHEREEMITTER
  21. uniform float radius;
  22. #ifdef DIRECTEDSPHEREEMITTER
  23. uniform vec3 direction1;
  24. uniform vec3 direction2;
  25. #else
  26. uniform float directionRandomizer;
  27. #endif
  28. #endif
  29. #ifdef CONEEMITTER
  30. uniform float radius;
  31. uniform float angle;
  32. uniform float height;
  33. uniform float directionRandomizer;
  34. #endif
  35. // Particles state
  36. in vec3 position;
  37. in float age;
  38. in float life;
  39. in float seed;
  40. in float size;
  41. in vec4 color;
  42. in vec3 direction;
  43. // Output
  44. out vec3 outPosition;
  45. out float outAge;
  46. out float outLife;
  47. out float outSeed;
  48. out float outSize;
  49. out vec4 outColor;
  50. out vec3 outDirection;
  51. vec3 getRandomVec3(float offset) {
  52. return texture(randomSampler, vec2(float(gl_VertexID) * offset / currentCount, 0)).rgb;
  53. }
  54. vec4 getRandomVec4(float offset) {
  55. return texture(randomSampler, vec2(float(gl_VertexID) * offset / currentCount, 0));
  56. }
  57. void main() {
  58. if (age >= life) {
  59. vec3 position;
  60. vec3 direction;
  61. // Let's get some random values
  62. vec4 randoms = getRandomVec4(generalRandoms.x);
  63. // Age and life
  64. outAge = 0.0;
  65. outLife = lifeTime.x + (lifeTime.y - lifeTime.x) * randoms.r;
  66. // Seed
  67. outSeed = seed;
  68. // Size
  69. outSize = sizeRange.x + (sizeRange.y - sizeRange.x) * randoms.g;
  70. // Color
  71. outColor = color1 + (color2 - color1) * randoms.b;
  72. // Position / Direction (based on emitter type)
  73. #ifdef BOXEMITTER
  74. vec3 randoms2 = getRandomVec3(generalRandoms.y);
  75. vec3 randoms3 = getRandomVec3(generalRandoms.z);
  76. position = minEmitBox + (maxEmitBox - minEmitBox) * randoms2;
  77. direction = direction1 + (direction2 - direction1) * randoms3;
  78. #elif defined(SPHEREEMITTER)
  79. vec3 randoms2 = getRandomVec3(generalRandoms.y);
  80. vec3 randoms3 = getRandomVec3(generalRandoms.z);
  81. // Position on the sphere surface
  82. float phi = 2.0 * PI * randoms2.x;
  83. float theta = PI * randoms2.y;
  84. float randX = cos(phi) * sin(theta);
  85. float randY = cos(theta);
  86. float randZ = sin(phi) * sin(theta);
  87. position = radius * vec3(randX, randY, randZ);
  88. #ifdef DIRECTEDSPHEREEMITTER
  89. direction = direction1 + (direction2 - direction1) * randoms3;
  90. #else
  91. // Direction
  92. direction = position + directionRandomizer * randoms3;
  93. #endif
  94. #elif defined(CONEEMITTER)
  95. vec3 randoms2 = getRandomVec3(generalRandoms.y);
  96. float s = 2.0 * PI * randoms2.x;
  97. float h = randoms2.y;
  98. // Better distribution in a cone at normal angles.
  99. h = 1. - h * h;
  100. float lRadius = radius * randoms2.z;
  101. lRadius = lRadius * h / height;
  102. float randX = lRadius * sin(s);
  103. float randZ = lRadius * cos(s);
  104. float randY = h * height;
  105. position = vec3(randX, randY, randZ);
  106. // Direction
  107. if (angle == 0.) {
  108. direction = vec3(0., 1.0, 0.);
  109. } else {
  110. vec3 randoms3 = getRandomVec3(generalRandoms.z);
  111. direction = position + directionRandomizer * randoms3;
  112. }
  113. #else
  114. // Create the particle at origin
  115. position = vec3(0., 0., 0.);
  116. // Spread in all directions
  117. direction = 2.0 * (getRandomVec3(seed) - vec3(0.5, 0.5, 0.5));
  118. #endif
  119. float power = emitPower.x + (emitPower.y - emitPower.x) * randoms.a;
  120. outPosition = (emitterWM * vec4(position, 1.)).xyz;
  121. outDirection = (emitterWM * vec4(normalize(direction) * power, 0.)).xyz;
  122. } else {
  123. outPosition = position + (direction + gravity) * timeDelta;
  124. outAge = age + timeDelta;
  125. outLife = life;
  126. outSeed = seed;
  127. outColor = color;
  128. outSize = size;
  129. outDirection = direction;
  130. }
  131. }