diff options
Diffstat (limited to 'drivers/gles3/shaders/particles.glsl')
-rw-r--r-- | drivers/gles3/shaders/particles.glsl | 115 |
1 files changed, 93 insertions, 22 deletions
diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl index e72f12cc5e..347b15d639 100644 --- a/drivers/gles3/shaders/particles.glsl +++ b/drivers/gles3/shaders/particles.glsl @@ -22,16 +22,21 @@ struct Attractor { #define MAX_ATTRACTORS 64 -uniform mat4 origin; +uniform bool emitting; uniform float system_phase; uniform float prev_system_phase; -uniform float total_particles; +uniform int total_particles; uniform float explosiveness; +uniform float randomness; uniform vec4 time; uniform float delta; uniform vec3 gravity; uniform int attractor_count; uniform Attractor attractors[MAX_ATTRACTORS]; +uniform bool clear; +uniform uint cycle; +uniform float lifetime; +uniform mat4 emission_transform; out highp vec4 out_color; //tfb: @@ -53,52 +58,116 @@ MATERIAL_UNIFORMS #endif +uint hash(uint x) { + + x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b); + x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b); + x = (x >> uint(16)) ^ x; + return x; +} + + void main() { bool apply_forces=true; bool apply_velocity=true; + vec3 current_gravity = gravity; + float local_delta=delta; float mass = 1.0; - float restart_phase = float(gl_InstanceID)/total_particles; - restart_phase*= explosiveness; + float restart_phase = float(gl_VertexID)/float(total_particles); + + if (randomness>0.0) { + uint seed = cycle; + if (restart_phase >= system_phase) { + seed-=uint(1); + } + seed*=uint(total_particles); + seed+=uint(gl_VertexID); + float random = float(hash(seed) % uint(65536)) / 65536.0; + restart_phase+=randomness * random * 1.0 / float(total_particles); + } + + restart_phase*= (1.0-explosiveness); bool restart=false; - bool active = out_velocity_active.a > 0.5; + bool active = velocity_active.a > 0.5; if (system_phase > prev_system_phase) { - restart = prev_system_phase < restart_phase && system_phase >= restart_phase; + if (prev_system_phase < restart_phase && system_phase >= restart_phase) { + restart=true; +#ifdef USE_FRACTIONAL_DELTA + local_delta = (system_phase - restart_phase) * lifetime; +#endif + } + } else { - restart = prev_system_phase < restart_phase || system_phase >= restart_phase; + if (prev_system_phase < restart_phase) { + restart=true; +#ifdef USE_FRACTIONAL_DELTA + local_delta = (1.0 - restart_phase + system_phase) * lifetime; +#endif + } else if (system_phase >= restart_phase) { + restart=true; +#ifdef USE_FRACTIONAL_DELTA + local_delta = (system_phase - restart_phase) * lifetime; +#endif + } } - if (restart) { - active=true; + uint current_cycle = cycle; + + if (system_phase < restart_phase) { + current_cycle-=uint(1); } - out_color=color; - out_velocity_active=velocity_active; - out_custom=custom; + uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID); - mat4 xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0))); + if (restart) { + active=emitting; + } + mat4 xform; - out_rot_active=rot_active; +#if defined(ENABLE_KEEP_DATA) + if (clear) { +#else + if (clear || restart) { +#endif + out_color=vec4(1.0); + out_velocity_active=vec4(0.0); + out_custom=vec4(0.0); + if (!restart) + active=false; + + xform = mat4( + vec4(1.0,0.0,0.0,0.0), + vec4(0.0,1.0,0.0,0.0), + vec4(0.0,0.0,1.0,0.0), + vec4(0.0,0.0,0.0,1.0) + ); + } else { + out_color=color; + out_velocity_active=velocity_active; + out_custom=custom; + xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0))); + } if (active) { //execute shader { - VERTEX_SHADER_CODE +VERTEX_SHADER_CODE } #if !defined(DISABLE_FORCE) - { + if (true) { - vec3 force = gravity; + vec3 force = current_gravity; for(int i=0;i<attractor_count;i++) { - vec3 rel_vec = out_pos_lifetime.xyz - attractors[i].pos; + vec3 rel_vec = xform[3].xyz - attractors[i].pos; float dist = rel_vec.length(); if (attractors[i].radius < dist) continue; @@ -119,17 +188,19 @@ void main() { } } - out_velocity_seed.xyz += force * delta; + out_velocity_active.xyz += force * local_delta; } #endif #if !defined(DISABLE_VELOCITY) - { + if (true) { - out_pos_lifetime.xyz += out_velocity_seed.xyz * delta; + xform[3].xyz += out_velocity_active.xyz * local_delta; } #endif + } else { + xform=mat4(0.0); } xform = transpose(xform); @@ -162,6 +233,6 @@ MATERIAL_UNIFORMS void main() { { - FRAGMENT_SHADER_CODE +FRAGMENT_SHADER_CODE } } |