summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp30
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h6
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp1
-rw-r--r--drivers/gles3/shaders/particles.glsl9
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;