gpuUpdateParticles.vertex.fx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #version 300 es
  2. #define PI 3.14159
  3. uniform float currentCount;
  4. uniform float timeDelta;
  5. uniform float stopFactor;
  6. uniform mat4 emitterWM;
  7. uniform vec2 lifeTime;
  8. uniform vec2 emitPower;
  9. uniform vec2 sizeRange;
  10. uniform vec4 scaleRange;
  11. #ifndef COLORGRADIENTS
  12. uniform vec4 color1;
  13. uniform vec4 color2;
  14. #endif
  15. uniform vec3 gravity;
  16. uniform sampler2D randomSampler;
  17. uniform sampler2D randomSampler2;
  18. uniform vec4 angleRange;
  19. #ifdef BOXEMITTER
  20. uniform vec3 direction1;
  21. uniform vec3 direction2;
  22. uniform vec3 minEmitBox;
  23. uniform vec3 maxEmitBox;
  24. #endif
  25. #ifdef SPHEREEMITTER
  26. uniform float radius;
  27. uniform float radiusRange;
  28. #ifdef DIRECTEDSPHEREEMITTER
  29. uniform vec3 direction1;
  30. uniform vec3 direction2;
  31. #else
  32. uniform float directionRandomizer;
  33. #endif
  34. #endif
  35. #ifdef CONEEMITTER
  36. uniform float radius;
  37. uniform float coneAngle;
  38. uniform float height;
  39. uniform float directionRandomizer;
  40. #endif
  41. // Particles state
  42. in vec3 position;
  43. in float age;
  44. in float life;
  45. in vec4 seed;
  46. in vec3 size;
  47. #ifndef COLORGRADIENTS
  48. in vec4 color;
  49. #endif
  50. in vec3 direction;
  51. #ifndef BILLBOARD
  52. in vec3 initialDirection;
  53. #endif
  54. in vec2 angle;
  55. #ifdef ANIMATESHEET
  56. in float cellIndex;
  57. #endif
  58. // Output
  59. out vec3 outPosition;
  60. out float outAge;
  61. out float outLife;
  62. out vec4 outSeed;
  63. out vec3 outSize;
  64. #ifndef COLORGRADIENTS
  65. out vec4 outColor;
  66. #endif
  67. out vec3 outDirection;
  68. #ifndef BILLBOARD
  69. out vec3 outInitialDirection;
  70. #endif
  71. out vec2 outAngle;
  72. #ifdef ANIMATESHEET
  73. out float outCellIndex;
  74. #endif
  75. #ifdef SIZEGRADIENTS
  76. uniform sampler2D sizeGradientSampler;
  77. #endif
  78. #ifdef ANIMATESHEET
  79. uniform vec3 cellInfos;
  80. #endif
  81. vec3 getRandomVec3(float offset) {
  82. return texture(randomSampler2, vec2(float(gl_VertexID) * offset / currentCount, 0)).rgb;
  83. }
  84. vec4 getRandomVec4(float offset) {
  85. return texture(randomSampler, vec2(float(gl_VertexID) * offset / currentCount, 0));
  86. }
  87. void main() {
  88. if (age >= life) {
  89. if (stopFactor == 0.) {
  90. outPosition = position;
  91. outAge = life;
  92. outLife = life;
  93. outSeed = seed;
  94. #ifndef COLORGRADIENTS
  95. outColor = vec4(0.,0.,0.,0.);
  96. #endif
  97. outSize = vec3(0., 0., 0.);
  98. #ifndef BILLBOARD
  99. outInitialDirection = initialDirection;
  100. #endif
  101. outDirection = direction;
  102. outAngle = angle;
  103. #ifdef ANIMATESHEET
  104. outCellIndex = cellIndex;
  105. #endif
  106. return;
  107. }
  108. vec3 position;
  109. vec3 direction;
  110. // Let's get some random values
  111. vec4 randoms = getRandomVec4(seed.x);
  112. // Age and life
  113. outAge = 0.0;
  114. outLife = lifeTime.x + (lifeTime.y - lifeTime.x) * randoms.r;
  115. // Seed
  116. outSeed = seed;
  117. // Size
  118. outSize.x = texture(sizeGradientSampler, vec2(0, 0)).r;
  119. outSize.y = scaleRange.x + (scaleRange.y - scaleRange.x) * randoms.b;
  120. outSize.z = scaleRange.z + (scaleRange.w - scaleRange.z) * randoms.a;
  121. #ifndef COLORGRADIENTS
  122. // Color
  123. outColor = color1 + (color2 - color1) * randoms.b;
  124. #endif
  125. // Angular speed
  126. outAngle.y = angleRange.x + (angleRange.y - angleRange.x) * randoms.a;
  127. outAngle.x = angleRange.z + (angleRange.w - angleRange.z) * randoms.r;
  128. // Position / Direction (based on emitter type)
  129. #ifdef BOXEMITTER
  130. vec3 randoms2 = getRandomVec3(seed.y);
  131. vec3 randoms3 = getRandomVec3(seed.z);
  132. position = minEmitBox + (maxEmitBox - minEmitBox) * randoms2;
  133. direction = direction1 + (direction2 - direction1) * randoms3;
  134. #elif defined(SPHEREEMITTER)
  135. vec3 randoms2 = getRandomVec3(seed.y);
  136. vec3 randoms3 = getRandomVec3(seed.z);
  137. // Position on the sphere surface
  138. float phi = 2.0 * PI * randoms2.x;
  139. float theta = acos(2.0 * randoms2.y - 1.0);
  140. float randX = cos(phi) * sin(theta);
  141. float randY = cos(theta);
  142. float randZ = sin(phi) * sin(theta);
  143. position = (radius - (radius * radiusRange * randoms2.z)) * vec3(randX, randY, randZ);
  144. #ifdef DIRECTEDSPHEREEMITTER
  145. direction = direction1 + (direction2 - direction1) * randoms3;
  146. #else
  147. // Direction
  148. direction = position + directionRandomizer * randoms3;
  149. #endif
  150. #elif defined(CONEEMITTER)
  151. vec3 randoms2 = getRandomVec3(seed.y);
  152. float s = 2.0 * PI * randoms2.x;
  153. float h = randoms2.y;
  154. // Better distribution in a cone at normal angles.
  155. h = 1. - h * h;
  156. float lRadius = radius * randoms2.z;
  157. lRadius = lRadius * h;
  158. float randX = lRadius * sin(s);
  159. float randZ = lRadius * cos(s);
  160. float randY = h * height;
  161. position = vec3(randX, randY, randZ);
  162. // Direction
  163. if (coneAngle == 0.) {
  164. direction = vec3(0., 1.0, 0.);
  165. } else {
  166. vec3 randoms3 = getRandomVec3(seed.z);
  167. direction = position + directionRandomizer * randoms3;
  168. }
  169. #else
  170. // Create the particle at origin
  171. position = vec3(0., 0., 0.);
  172. // Spread in all directions
  173. direction = 2.0 * (getRandomVec3(seed.w) - vec3(0.5, 0.5, 0.5));
  174. #endif
  175. float power = emitPower.x + (emitPower.y - emitPower.x) * randoms.a;
  176. outPosition = (emitterWM * vec4(position, 1.)).xyz;
  177. vec3 initial = (emitterWM * vec4(direction, 0.)).xyz;
  178. outDirection = initial * power;
  179. #ifndef BILLBOARD
  180. outInitialDirection = initial;
  181. #endif
  182. #ifdef ANIMATESHEET
  183. outCellIndex = cellInfos.x;
  184. #endif
  185. } else {
  186. outPosition = position + direction * timeDelta;
  187. outAge = age + timeDelta;
  188. outLife = life;
  189. outSeed = seed;
  190. #ifndef COLORGRADIENTS
  191. outColor = color;
  192. #endif
  193. #ifdef SIZEGRADIENTS
  194. outSize.x = texture(sizeGradientSampler, vec2(age / life, 0)).r;
  195. outSize.yz = size.yz;
  196. #else
  197. outSize = size;
  198. #endif
  199. #ifndef BILLBOARD
  200. outInitialDirection = initialDirection;
  201. #endif
  202. outDirection = direction + gravity * timeDelta;
  203. outAngle = vec2(angle.x + angle.y * timeDelta, angle.y);
  204. #ifdef ANIMATESHEET
  205. float dist = cellInfos.y - cellInfos.x;
  206. float ratio = clamp(mod(((outAge * cellInfos.z) / life), life), 0., 1.0);
  207. outCellIndex = float(int(cellInfos.x + ratio * dist));
  208. #endif
  209. }
  210. }