particles.glsl 5.3 KB

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