particles.glsl 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /* clang-format off */
  2. [vertex]
  3. layout(location = 0) in highp vec4 color;
  4. /* clang-format on */
  5. layout(location = 1) in highp vec4 velocity_active;
  6. layout(location = 2) in highp vec4 custom;
  7. layout(location = 3) in highp vec4 xform_1;
  8. layout(location = 4) in highp vec4 xform_2;
  9. layout(location = 5) in highp vec4 xform_3;
  10. struct Attractor {
  11. vec3 pos;
  12. vec3 dir;
  13. float radius;
  14. float eat_radius;
  15. float strength;
  16. float attenuation;
  17. };
  18. #define MAX_ATTRACTORS 64
  19. uniform bool emitting;
  20. uniform float system_phase;
  21. uniform float prev_system_phase;
  22. uniform int total_particles;
  23. uniform float explosiveness;
  24. uniform float randomness;
  25. uniform float time;
  26. uniform float delta;
  27. uniform int attractor_count;
  28. uniform Attractor attractors[MAX_ATTRACTORS];
  29. uniform bool clear;
  30. uniform uint cycle;
  31. uniform float lifetime;
  32. uniform mat4 emission_transform;
  33. uniform uint random_seed;
  34. out highp vec4 out_color; //tfb:
  35. out highp vec4 out_velocity_active; //tfb:
  36. out highp vec4 out_custom; //tfb:
  37. out highp vec4 out_xform_1; //tfb:
  38. out highp vec4 out_xform_2; //tfb:
  39. out highp vec4 out_xform_3; //tfb:
  40. #if defined(USE_MATERIAL)
  41. /* clang-format off */
  42. layout(std140) uniform UniformData { //ubo:0
  43. MATERIAL_UNIFORMS
  44. };
  45. /* clang-format on */
  46. #endif
  47. /* clang-format off */
  48. VERTEX_SHADER_GLOBALS
  49. /* clang-format on */
  50. uint hash(uint x) {
  51. x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
  52. x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
  53. x = (x >> uint(16)) ^ x;
  54. return x;
  55. }
  56. void main() {
  57. #ifdef PARTICLES_COPY
  58. out_color = color;
  59. out_velocity_active = velocity_active;
  60. out_custom = custom;
  61. out_xform_1 = xform_1;
  62. out_xform_2 = xform_2;
  63. out_xform_3 = xform_3;
  64. #else
  65. bool apply_forces = true;
  66. bool apply_velocity = true;
  67. float local_delta = delta;
  68. float mass = 1.0;
  69. float restart_phase = float(gl_VertexID) / float(total_particles);
  70. if (randomness > 0.0) {
  71. uint seed = cycle;
  72. if (restart_phase >= system_phase) {
  73. seed -= uint(1);
  74. }
  75. seed *= uint(total_particles);
  76. seed += uint(gl_VertexID);
  77. float random = float(hash(seed) % uint(65536)) / 65536.0;
  78. restart_phase += randomness * random * 1.0 / float(total_particles);
  79. }
  80. restart_phase *= (1.0 - explosiveness);
  81. bool restart = false;
  82. bool shader_active = velocity_active.a > 0.5;
  83. if (system_phase > prev_system_phase) {
  84. // restart_phase >= prev_system_phase is used so particles emit in the first frame they are processed
  85. if (restart_phase >= prev_system_phase && restart_phase < system_phase) {
  86. restart = true;
  87. #ifdef USE_FRACTIONAL_DELTA
  88. local_delta = (system_phase - restart_phase) * lifetime;
  89. #endif
  90. }
  91. } else {
  92. if (restart_phase >= prev_system_phase) {
  93. restart = true;
  94. #ifdef USE_FRACTIONAL_DELTA
  95. local_delta = (1.0 - restart_phase + system_phase) * lifetime;
  96. #endif
  97. } else if (restart_phase < system_phase) {
  98. restart = true;
  99. #ifdef USE_FRACTIONAL_DELTA
  100. local_delta = (system_phase - restart_phase) * lifetime;
  101. #endif
  102. }
  103. }
  104. uint current_cycle = cycle;
  105. if (system_phase < restart_phase) {
  106. current_cycle -= uint(1);
  107. }
  108. uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID);
  109. int index = int(gl_VertexID);
  110. if (restart) {
  111. shader_active = emitting;
  112. }
  113. mat4 xform;
  114. #if defined(ENABLE_KEEP_DATA)
  115. if (clear) {
  116. #else
  117. if (clear || restart) {
  118. #endif
  119. out_color = vec4(1.0);
  120. out_velocity_active = vec4(0.0);
  121. out_custom = vec4(0.0);
  122. if (!restart)
  123. shader_active = false;
  124. xform = mat4(
  125. vec4(1.0, 0.0, 0.0, 0.0),
  126. vec4(0.0, 1.0, 0.0, 0.0),
  127. vec4(0.0, 0.0, 1.0, 0.0),
  128. vec4(0.0, 0.0, 0.0, 1.0));
  129. } else {
  130. out_color = color;
  131. out_velocity_active = velocity_active;
  132. out_custom = custom;
  133. xform = transpose(mat4(xform_1, xform_2, xform_3, vec4(vec3(0.0), 1.0)));
  134. }
  135. if (shader_active) {
  136. //execute shader
  137. {
  138. /* clang-format off */
  139. VERTEX_SHADER_CODE
  140. /* clang-format on */
  141. }
  142. #if !defined(DISABLE_FORCE)
  143. if (false) {
  144. vec3 force = vec3(0.0);
  145. for (int i = 0; i < attractor_count; i++) {
  146. vec3 rel_vec = xform[3].xyz - attractors[i].pos;
  147. float dist = length(rel_vec);
  148. if (attractors[i].radius < dist)
  149. continue;
  150. if (attractors[i].eat_radius > 0.0 && attractors[i].eat_radius > dist) {
  151. out_velocity_active.a = 0.0;
  152. }
  153. rel_vec = normalize(rel_vec);
  154. float attenuation = pow(dist / attractors[i].radius, attractors[i].attenuation);
  155. if (attractors[i].dir == vec3(0.0)) {
  156. //towards center
  157. force += attractors[i].strength * rel_vec * attenuation * mass;
  158. } else {
  159. force += attractors[i].strength * attractors[i].dir * attenuation * mass;
  160. }
  161. }
  162. out_velocity_active.xyz += force * local_delta;
  163. }
  164. #endif
  165. #if !defined(DISABLE_VELOCITY)
  166. if (true) {
  167. xform[3].xyz += out_velocity_active.xyz * local_delta;
  168. }
  169. #endif
  170. } else {
  171. xform = mat4(0.0);
  172. }
  173. xform = transpose(xform);
  174. out_velocity_active.a = mix(0.0, 1.0, shader_active);
  175. out_xform_1 = xform[0];
  176. out_xform_2 = xform[1];
  177. out_xform_3 = xform[2];
  178. #endif //PARTICLES_COPY
  179. }
  180. /* clang-format off */
  181. [fragment]
  182. //any code here is never executed, stuff is filled just so it works
  183. #if defined(USE_MATERIAL)
  184. layout(std140) uniform UniformData {
  185. MATERIAL_UNIFORMS
  186. };
  187. #endif
  188. FRAGMENT_SHADER_GLOBALS
  189. void main() {
  190. {
  191. LIGHT_SHADER_CODE
  192. }
  193. {
  194. FRAGMENT_SHADER_CODE
  195. }
  196. }
  197. /* clang-format on */