123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #ifndef PARTICLES_GLSLV
- #define PARTICLES_GLSLV
- // #import u_p_time u_p_cyclic u_p_length
- // #import u_p_nfactor u_p_gravity u_p_mass u_p_wind_fac u_p_max_lifetime
- // #import u_p_fade_in u_p_fade_out u_p_color_ramp u_color_ramp_tex
- // #import u_model_tsr u_wind
- // #import a_position a_normal a_p_vels a_p_data
- /*==============================================================================
- VARS
- ==============================================================================*/
- #var EPSILON 0.000001
- #var COLOR_RAMP_LENGTH 0
- #var WORLD_SPACE 0
- #var USE_COLOR_RAMP 0
- /*============================================================================*/
- #include <math.glslv>
- struct part_params {
- float size;
- vec3 position;
- float alpha;
- vec3 color;
- float angle;
- vec3 velocity;
- vec3 ang_velocity;
- float age;
- };
- #if COLOR_RAMP_LENGTH > 0
- void process_color_ramp(inout vec3 color, float where, vec4 left, vec4 right) {
- float gap_size = right.x - left.x;
- float mix_factor = (where - left.x) / gap_size;
- color = mix(color, right.yzw, clamp(mix_factor, 0.0, 1.0));
- }
- #endif
- #if COLOR_RAMP_LENGTH > 0
- vec3 color_from_ramp(float t, float lifetime, vec4 ramp[COLOR_RAMP_LENGTH]) {
- float where = t/lifetime;
- vec3 color = ramp[0].yzw;
- // avoid loops becaus of performance issues on some mobiles
- # if COLOR_RAMP_LENGTH > 1
- process_color_ramp(color, where, ramp[0], ramp[1]);
- # endif
- # if COLOR_RAMP_LENGTH > 2
- process_color_ramp(color, where, ramp[1], ramp[2]);
- # endif
- # if COLOR_RAMP_LENGTH > 3
- process_color_ramp(color, where, ramp[2], ramp[3]);
- # endif
- return color;
- }
- #endif
- /*
- * Calculate alpha according to fade-in and fade-out intervals
- */
- float fade_alpha(float t, float lifetime, float fade_in, float fade_out) {
- float fin = max(0.01, min(lifetime, fade_in));
- float fout = max(0.01, min(lifetime, fade_out));
- float fout_start = lifetime - fout;
- float alpha = clamp(t/fin, 0.0, 1.0) -
- step(fout_start, t) * (t - fout_start) / fout;
- return alpha;
- }
- part_params calc_part_params(void) {
- part_params sp;
- float t;
- float lifetime = a_p_data[0];
- float delay = a_p_data[1];
- if (u_p_cyclic == 1) {
- t = mod(u_p_time, u_p_length) - delay;
- if (t < 0.0)
- t += u_p_length;
- }
- //} else {
- if (u_p_cyclic != 1) {
- t = u_p_time - delay;
- }
- if (t < 0.0 || t >= lifetime) {
- sp.size = 0.0001;
- sp.position = vec3(99999.0, 0.0, 0.0);
- }
- //} else {
- if (!(t < 0.0 || t >= lifetime)) {
- /* position */
- vec3 norm_tbn = qrot(a_tbn_quat, vec3(0.0, 1.0, 0.0));
- #if WORLD_SPACE
- vec3 pos = a_position;
- vec3 norm = norm_tbn;
- #else
- vec3 pos = tsr9_transform(u_model_tsr, a_position);
- vec3 norm = tsr9_transform_dir(u_model_tsr, norm_tbn);
- #endif
- /* cinematics */
- vec3 vel = u_p_nfactor * norm;
- vel += a_p_vels.xyz;
- vel.z -= u_p_gravity * t / 2.0;
- float mass = max(u_p_mass, EPSILON);
- vel += (u_p_wind_fac * u_wind / mass) * t /2.0;
- sp.age = t;
- sp.velocity = vel;
- sp.ang_velocity = norm_tbn * a_p_vels.w;
- sp.position = pos + vel * t;
- sp.angle = a_p_vels.w * t;
- #if USE_COLOR_RAMP
- sp.size = GLSL_TEXTURE(u_color_ramp_tex, vec2(t / u_p_max_lifetime, 0.5)).g;
- #else
- sp.size = 1.0;
- #endif
- #if COLOR_RAMP_LENGTH > 0
- sp.color = color_from_ramp(t, u_p_max_lifetime, u_p_color_ramp);
- #else
- sp.color = vec3(1.0);
- #endif
- sp.alpha = fade_alpha(t, a_p_data[0], u_p_fade_in, u_p_fade_out);
- }
- return sp;
- }
- #endif
|