Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix particles not properly updated by their lifetime #45496

Merged
merged 1 commit into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions scene/2d/cpu_particles_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,8 @@ void CPUParticles2D::_particles_process(float p_delta) {
restart = true;
}

float tv = 0.0;

if (restart) {
if (!emitting) {
p.active = false;
Expand All @@ -685,12 +687,12 @@ void CPUParticles2D::_particles_process(float p_delta) {

float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0);
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}

float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0);
tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}

p.seed = Math::rand();
Expand Down Expand Up @@ -765,59 +767,61 @@ void CPUParticles2D::_particles_process(float p_delta) {
continue;
} else if (p.time > p.lifetime) {
p.active = false;
tv = 1.0;
} else {
uint32_t alt_seed = p.seed;

p.time += local_delta;
p.custom[1] = p.time / lifetime;
tv = p.time / p.lifetime;

Copy link
Member

@lawnjelly lawnjelly Jan 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should p.custom[1] be set as the same as tv too? Or is there something that assumes p.custom[1] is in relation to the unadjusted lifetime?

Copy link
Member Author

@Chaosus Chaosus Jan 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its used in this code:

float base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp(1.0f, p.angle_rand, randomness[PARAM_ANGLE]);
			base_angle += p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]);
			p.rotation = Math::deg2rad(base_angle); //angle
			float animation_phase = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]);
			p.custom[2] = animation_phase;

I'm not sure whether it's can be changed here so I used a temporary variable to avoid this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've no idea either not that familiar with the particles, we'll see if anyone else chimes in.. Worst case though it wouldn't be bad to merge as is and this could be fixed in a separate PR if necessary.

float tex_linear_velocity = 0.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]);
tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}

float tex_orbit_velocity = 0.0;
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]);
tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}

float tex_angular_velocity = 0.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]);
tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}

float tex_linear_accel = 0.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]);
tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}

float tex_tangential_accel = 0.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]);
tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}

float tex_radial_accel = 0.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]);
tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}

float tex_damping = 0.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]);
tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}

float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]);
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_speed = 0.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]);
tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}

float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]);
tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}

Vector2 force = gravity;
Expand Down Expand Up @@ -869,12 +873,12 @@ void CPUParticles2D::_particles_process(float p_delta) {

float tex_scale = 1.0;
if (curve_parameters[PARAM_SCALE].is_valid()) {
tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]);
tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
}

float tex_hue_variation = 0.0;
if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) {
tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]);
tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}

float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
Expand All @@ -893,7 +897,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
}

if (color_ramp.is_valid()) {
p.color = color_ramp->get_color_at_offset(p.custom[1]) * color;
p.color = color_ramp->get_color_at_offset(tv) * color;
} else {
p.color = color;
}
Expand Down
34 changes: 19 additions & 15 deletions scene/3d/cpu_particles_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,8 @@ void CPUParticles3D::_particles_process(float p_delta) {
restart = true;
}

float tv = 0.0;

if (restart) {
if (!emitting) {
p.active = false;
Expand All @@ -660,12 +662,12 @@ void CPUParticles3D::_particles_process(float p_delta) {

float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0);
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}

float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0);
tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}

p.seed = Math::rand();
Expand Down Expand Up @@ -771,61 +773,63 @@ void CPUParticles3D::_particles_process(float p_delta) {
continue;
} else if (p.time > p.lifetime) {
p.active = false;
tv = 1.0;
} else {
uint32_t alt_seed = p.seed;

p.time += local_delta;
p.custom[1] = p.time / lifetime;
tv = p.time / p.lifetime;

float tex_linear_velocity = 0.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]);
tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}

float tex_orbit_velocity = 0.0;
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]);
tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
}

float tex_angular_velocity = 0.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]);
tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}

float tex_linear_accel = 0.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]);
tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}

float tex_tangential_accel = 0.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]);
tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}

float tex_radial_accel = 0.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]);
tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}

float tex_damping = 0.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]);
tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}

float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]);
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_speed = 0.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]);
tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}

float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]);
tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}

Vector3 force = gravity;
Expand Down Expand Up @@ -887,12 +891,12 @@ void CPUParticles3D::_particles_process(float p_delta) {

float tex_scale = 1.0;
if (curve_parameters[PARAM_SCALE].is_valid()) {
tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]);
tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
}

float tex_hue_variation = 0.0;
if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) {
tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]);
tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}

float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
Expand All @@ -911,7 +915,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
}

if (color_ramp.is_valid()) {
p.color = color_ramp->get_color_at_offset(p.custom[1]) * color;
p.color = color_ramp->get_color_at_offset(tv) * color;
} else {
p.color = color;
}
Expand Down
28 changes: 15 additions & 13 deletions scene/resources/particles_material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ void ParticlesMaterial::_update_shader() {
code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n";
code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n";
}
code += " float tv = 0.0;\n";
code += " if (RESTART) {\n";

if (tex_parameters[PARAM_ANGLE].is_valid()) {
Expand Down Expand Up @@ -407,64 +408,65 @@ void ParticlesMaterial::_update_shader() {
code += " } else {\n";

code += " CUSTOM.y += DELTA / LIFETIME;\n";
code += " tv = CUSTOM.y / CUSTOM.w;\n";
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_linear_velocity = 0.0;\n";
}

if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_orbit_velocity = 0.0;\n";
}
}

if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_angular_velocity = 0.0;\n";
}

if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_linear_accel = 0.0;\n";
}

if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_radial_accel = 0.0;\n";
}

if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_tangent_accel = 0.0;\n";
}

if (tex_parameters[PARAM_DAMPING].is_valid()) {
code += " float tex_damping = textureLod(damping_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_damping = textureLod(damping_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_damping = 0.0;\n";
}

if (tex_parameters[PARAM_ANGLE].is_valid()) {
code += " float tex_angle = textureLod(angle_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_angle = textureLod(angle_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_angle = 0.0;\n";
}

if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) {
code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_anim_speed = 0.0;\n";
}

if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_anim_offset = 0.0;\n";
}
Expand Down Expand Up @@ -526,13 +528,13 @@ void ParticlesMaterial::_update_shader() {
// apply color
// apply hue rotation
if (tex_parameters[PARAM_SCALE].is_valid()) {
code += " float tex_scale = textureLod(scale_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_scale = textureLod(scale_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_scale = 1.0;\n";
}

if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) {
code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_hue_variation = 0.0;\n";
}
Expand All @@ -553,7 +555,7 @@ void ParticlesMaterial::_update_shader() {
code += " vec4(1.250, -1.050, -0.203, 0.0),\n";
code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n";
if (color_ramp.is_valid()) {
code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(CUSTOM.y, 0.0), 0.0);\n";
code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(tv, 0.0), 0.0);\n";
} else {
code += " COLOR = hue_rot_mat * color_value;\n";
}
Expand Down