gpuUpdateParticles.vertex.fx 4.9 KB

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