gpuUpdateParticles.vertex.fx 4.3 KB

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