diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 30 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 6 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 1 | ||||
-rw-r--r-- | drivers/gles3/shaders/particles.glsl | 9 |
4 files changed, 43 insertions, 3 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 81baf542c0..f7e1fdee9d 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -5288,6 +5288,7 @@ void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_de if (particles->clear) { particles->cycle_number = 0; + particles->random_seed = Math::rand(); } else if (new_phase < particles->phase) { particles->cycle_number++; } @@ -5298,6 +5299,8 @@ void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_de shaders.particles.set_uniform(ParticlesShaderGLES3::DELTA, p_delta * particles->speed_scale); shaders.particles.set_uniform(ParticlesShaderGLES3::CLEAR, particles->clear); + glUniform1ui(shaders.particles.get_uniform_location(ParticlesShaderGLES3::RANDOM_SEED), particles->random_seed); + if (particles->use_local_coords) shaders.particles.set_uniform(ParticlesShaderGLES3::EMISSION_TRANSFORM, Transform()); else @@ -5353,6 +5356,33 @@ void RasterizerStorageGLES3::update_particles() { Particles *particles = particle_update_list.first()->self(); + if (particles->inactive && !particles->emitting) { + + particle_update_list.remove(particle_update_list.first()); + continue; + } + + if (particles->emitting) { + if (particles->inactive) { + //restart system from scratch + particles->prev_ticks = 0; + particles->phase = 0; + particles->prev_phase = 0; + particles->clear = true; + particles->particle_valid_histories[0] = false; + particles->particle_valid_histories[1] = false; + } + particles->inactive = false; + particles->inactive_time = 0; + } else { + particles->inactive_time += particles->speed_scale * frame.delta; + if (particles->inactive_time > particles->lifetime * 1.2) { + particles->inactive = true; + particle_update_list.remove(particle_update_list.first()); + continue; + } + } + Material *material = material_owner.getornull(particles->process_material); if (!material || !material->shader || material->shader->mode != VS::SHADER_PARTICLES) { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index ca0194bd5e..65026a16ec 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -1033,6 +1033,8 @@ public: struct Particles : public GeometryOwner { + bool inactive; + float inactive_time; bool emitting; int amount; float lifetime; @@ -1060,6 +1062,7 @@ public: float phase; float prev_phase; uint64_t prev_ticks; + uint32_t random_seed; uint32_t cycle_number; @@ -1088,6 +1091,7 @@ public: frame_remainder = 0; histories_enabled = false; speed_scale = 1.0; + random_seed = 0; custom_aabb = Rect3(Vector3(-4, -4, -4), Vector3(8, 8, 8)); @@ -1098,6 +1102,8 @@ public: prev_ticks = 0; clear = true; + inactive = true; + inactive_time = false; glGenBuffers(2, particle_buffers); glGenVertexArrays(2, particle_vaos); diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 3376f99112..41421a3e2f 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -795,6 +795,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_PARTICLES].renames["INDEX"] = "index"; actions[VS::SHADER_PARTICLES].renames["GRAVITY"] = "current_gravity"; actions[VS::SHADER_PARTICLES].renames["EMISSION_TRANSFORM"] = "emission_transform"; + actions[VS::SHADER_PARTICLES].renames["RANDOM_SEED"] = "random_seed"; actions[VS::SHADER_SPATIAL].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n"; diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl index 7e7b083f73..ec2577538c 100644 --- a/drivers/gles3/shaders/particles.glsl +++ b/drivers/gles3/shaders/particles.glsl @@ -37,6 +37,7 @@ uniform bool clear; uniform uint cycle; uniform float lifetime; uniform mat4 emission_transform; +uniform uint random_seed; out highp vec4 out_color; //tfb: @@ -104,7 +105,9 @@ void main() { bool shader_active = velocity_active.a > 0.5; if (system_phase > prev_system_phase) { - if (prev_system_phase < restart_phase && system_phase >= restart_phase) { + // restart_phase >= prev_system_phase is used so particles emit in the first frame they are processed + + if (restart_phase >= prev_system_phase && restart_phase < system_phase ) { restart=true; #ifdef USE_FRACTIONAL_DELTA local_delta = (system_phase - restart_phase) * lifetime; @@ -112,12 +115,12 @@ void main() { } } else { - if (prev_system_phase < restart_phase) { + if (restart_phase >= prev_system_phase) { restart=true; #ifdef USE_FRACTIONAL_DELTA local_delta = (1.0 - restart_phase + system_phase) * lifetime; #endif - } else if (system_phase >= restart_phase) { + } else if (restart_phase < system_phase ) { restart=true; #ifdef USE_FRACTIONAL_DELTA local_delta = (system_phase - restart_phase) * lifetime; |