Merge pull request #30590 from clayjohn/particle_life
Added individual particle random lifetime
This commit is contained in:
commit
7d413f075c
9 changed files with 93 additions and 1 deletions
|
@ -220,6 +220,9 @@
|
|||
<member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" default="1.0">
|
||||
Amount of time each particle will exist.
|
||||
</member>
|
||||
<member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0">
|
||||
Particle lifetime randomness ratio.
|
||||
</member>
|
||||
<member name="linear_accel" type="float" setter="set_param" getter="get_param" default="0.0">
|
||||
Linear acceleration applied to each particle in the direction of motion.
|
||||
</member>
|
||||
|
|
|
@ -214,6 +214,9 @@
|
|||
<member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" default="1.0">
|
||||
Amount of time each particle will exist.
|
||||
</member>
|
||||
<member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0">
|
||||
Particle lifetime randomness ratio.
|
||||
</member>
|
||||
<member name="linear_accel" type="float" setter="set_param" getter="get_param" default="0.0">
|
||||
Linear acceleration applied to each particle in the direction of motion.
|
||||
</member>
|
||||
|
|
|
@ -192,6 +192,9 @@
|
|||
<member name="initial_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
|
||||
Initial velocity randomness ratio.
|
||||
</member>
|
||||
<member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0">
|
||||
Particle lifetime randomness ratio.
|
||||
</member>
|
||||
<member name="linear_accel" type="float" setter="set_param" getter="get_param" default="0.0">
|
||||
Linear acceleration applied to each particle in the direction of motion.
|
||||
</member>
|
||||
|
|
|
@ -83,6 +83,10 @@ void CPUParticles2D::set_randomness_ratio(float p_ratio) {
|
|||
|
||||
randomness_ratio = p_ratio;
|
||||
}
|
||||
void CPUParticles2D::set_lifetime_randomness(float p_random) {
|
||||
|
||||
lifetime_randomness = p_random;
|
||||
}
|
||||
void CPUParticles2D::set_use_local_coordinates(bool p_enable) {
|
||||
|
||||
local_coords = p_enable;
|
||||
|
@ -123,6 +127,10 @@ float CPUParticles2D::get_randomness_ratio() const {
|
|||
|
||||
return randomness_ratio;
|
||||
}
|
||||
float CPUParticles2D::get_lifetime_randomness() const {
|
||||
|
||||
return lifetime_randomness;
|
||||
}
|
||||
|
||||
bool CPUParticles2D::get_use_local_coordinates() const {
|
||||
|
||||
|
@ -611,6 +619,10 @@ void CPUParticles2D::_particles_process(float p_delta) {
|
|||
}
|
||||
}
|
||||
|
||||
if (p.time * (1.0 - explosiveness_ratio) > p.lifetime) {
|
||||
restart = true;
|
||||
}
|
||||
|
||||
if (restart) {
|
||||
|
||||
if (!emitting) {
|
||||
|
@ -654,6 +666,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
|
|||
p.custom[3] = 0.0;
|
||||
p.transform = Transform2D();
|
||||
p.time = 0;
|
||||
p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness);
|
||||
p.base_color = Color(1, 1, 1, 1);
|
||||
|
||||
switch (emission_shape) {
|
||||
|
@ -696,6 +709,8 @@ void CPUParticles2D::_particles_process(float p_delta) {
|
|||
|
||||
} else if (!p.active) {
|
||||
continue;
|
||||
} else if (p.time > p.lifetime) {
|
||||
p.active = false;
|
||||
} else {
|
||||
|
||||
uint32_t alt_seed = p.seed;
|
||||
|
@ -1153,6 +1168,7 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) {
|
|||
|
||||
Vector2 gravity = Vector2(material->get_gravity().x, material->get_gravity().y);
|
||||
set_gravity(gravity);
|
||||
set_lifetime_randomness(material->get_lifetime_randomness());
|
||||
|
||||
#define CONVERT_PARAM(m_param) \
|
||||
set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \
|
||||
|
@ -1187,6 +1203,7 @@ void CPUParticles2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &CPUParticles2D::set_pre_process_time);
|
||||
ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &CPUParticles2D::set_explosiveness_ratio);
|
||||
ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &CPUParticles2D::set_randomness_ratio);
|
||||
ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "random"), &CPUParticles2D::set_lifetime_randomness);
|
||||
ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &CPUParticles2D::set_use_local_coordinates);
|
||||
ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &CPUParticles2D::set_fixed_fps);
|
||||
ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &CPUParticles2D::set_fractional_delta);
|
||||
|
@ -1199,6 +1216,7 @@ void CPUParticles2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_pre_process_time"), &CPUParticles2D::get_pre_process_time);
|
||||
ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &CPUParticles2D::get_explosiveness_ratio);
|
||||
ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &CPUParticles2D::get_randomness_ratio);
|
||||
ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &CPUParticles2D::get_lifetime_randomness);
|
||||
ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &CPUParticles2D::get_use_local_coordinates);
|
||||
ClassDB::bind_method(D_METHOD("get_fixed_fps"), &CPUParticles2D::get_fixed_fps);
|
||||
ClassDB::bind_method(D_METHOD("get_fractional_delta"), &CPUParticles2D::get_fractional_delta);
|
||||
|
@ -1225,6 +1243,7 @@ void CPUParticles2D::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta");
|
||||
ADD_GROUP("Drawing", "");
|
||||
|
@ -1404,6 +1423,7 @@ CPUParticles2D::CPUParticles2D() {
|
|||
set_pre_process_time(0);
|
||||
set_explosiveness_ratio(0);
|
||||
set_randomness_ratio(0);
|
||||
set_lifetime_randomness(0);
|
||||
set_use_local_coordinates(true);
|
||||
|
||||
set_draw_order(DRAW_ORDER_INDEX);
|
||||
|
|
|
@ -96,6 +96,7 @@ private:
|
|||
float hue_rot_rand;
|
||||
float anim_offset_rand;
|
||||
float time;
|
||||
float lifetime;
|
||||
Color base_color;
|
||||
|
||||
uint32_t seed;
|
||||
|
@ -139,6 +140,7 @@ private:
|
|||
float pre_process_time;
|
||||
float explosiveness_ratio;
|
||||
float randomness_ratio;
|
||||
float lifetime_randomness;
|
||||
float speed_scale;
|
||||
bool local_coords;
|
||||
int fixed_fps;
|
||||
|
@ -200,6 +202,7 @@ public:
|
|||
void set_pre_process_time(float p_time);
|
||||
void set_explosiveness_ratio(float p_ratio);
|
||||
void set_randomness_ratio(float p_ratio);
|
||||
void set_lifetime_randomness(float p_random);
|
||||
void set_visibility_aabb(const Rect2 &p_aabb);
|
||||
void set_use_local_coordinates(bool p_enable);
|
||||
void set_speed_scale(float p_scale);
|
||||
|
@ -211,6 +214,7 @@ public:
|
|||
float get_pre_process_time() const;
|
||||
float get_explosiveness_ratio() const;
|
||||
float get_randomness_ratio() const;
|
||||
float get_lifetime_randomness() const;
|
||||
Rect2 get_visibility_aabb() const;
|
||||
bool get_use_local_coordinates() const;
|
||||
float get_speed_scale() const;
|
||||
|
|
|
@ -92,6 +92,10 @@ void CPUParticles::set_randomness_ratio(float p_ratio) {
|
|||
|
||||
randomness_ratio = p_ratio;
|
||||
}
|
||||
void CPUParticles::set_lifetime_randomness(float p_random) {
|
||||
|
||||
lifetime_randomness = p_random;
|
||||
}
|
||||
void CPUParticles::set_use_local_coordinates(bool p_enable) {
|
||||
|
||||
local_coords = p_enable;
|
||||
|
@ -130,6 +134,10 @@ float CPUParticles::get_randomness_ratio() const {
|
|||
|
||||
return randomness_ratio;
|
||||
}
|
||||
float CPUParticles::get_lifetime_randomness() const {
|
||||
|
||||
return lifetime_randomness;
|
||||
}
|
||||
|
||||
bool CPUParticles::get_use_local_coordinates() const {
|
||||
|
||||
|
@ -583,6 +591,10 @@ void CPUParticles::_particles_process(float p_delta) {
|
|||
}
|
||||
}
|
||||
|
||||
if (p.time * (1.0 - explosiveness_ratio) > p.lifetime) {
|
||||
restart = true;
|
||||
}
|
||||
|
||||
if (restart) {
|
||||
|
||||
if (!emitting) {
|
||||
|
@ -636,6 +648,7 @@ void CPUParticles::_particles_process(float p_delta) {
|
|||
p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1)
|
||||
p.transform = Transform();
|
||||
p.time = 0;
|
||||
p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness);
|
||||
p.base_color = Color(1, 1, 1, 1);
|
||||
|
||||
switch (emission_shape) {
|
||||
|
@ -701,6 +714,8 @@ void CPUParticles::_particles_process(float p_delta) {
|
|||
|
||||
} else if (!p.active) {
|
||||
continue;
|
||||
} else if (p.time > p.lifetime) {
|
||||
p.active = false;
|
||||
} else {
|
||||
|
||||
uint32_t alt_seed = p.seed;
|
||||
|
@ -1221,6 +1236,7 @@ void CPUParticles::convert_from_particles(Node *p_particles) {
|
|||
set_emission_box_extents(material->get_emission_box_extents());
|
||||
|
||||
set_gravity(material->get_gravity());
|
||||
set_lifetime_randomness(material->get_lifetime_randomness());
|
||||
|
||||
#define CONVERT_PARAM(m_param) \
|
||||
set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \
|
||||
|
@ -1255,6 +1271,7 @@ void CPUParticles::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &CPUParticles::set_pre_process_time);
|
||||
ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &CPUParticles::set_explosiveness_ratio);
|
||||
ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &CPUParticles::set_randomness_ratio);
|
||||
ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "random"), &CPUParticles::set_lifetime_randomness);
|
||||
ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &CPUParticles::set_use_local_coordinates);
|
||||
ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &CPUParticles::set_fixed_fps);
|
||||
ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &CPUParticles::set_fractional_delta);
|
||||
|
@ -1267,6 +1284,7 @@ void CPUParticles::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_pre_process_time"), &CPUParticles::get_pre_process_time);
|
||||
ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &CPUParticles::get_explosiveness_ratio);
|
||||
ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &CPUParticles::get_randomness_ratio);
|
||||
ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &CPUParticles::get_lifetime_randomness);
|
||||
ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &CPUParticles::get_use_local_coordinates);
|
||||
ClassDB::bind_method(D_METHOD("get_fixed_fps"), &CPUParticles::get_fixed_fps);
|
||||
ClassDB::bind_method(D_METHOD("get_fractional_delta"), &CPUParticles::get_fractional_delta);
|
||||
|
@ -1290,6 +1308,7 @@ void CPUParticles::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta");
|
||||
ADD_GROUP("Drawing", "");
|
||||
|
@ -1472,6 +1491,7 @@ CPUParticles::CPUParticles() {
|
|||
set_pre_process_time(0);
|
||||
set_explosiveness_ratio(0);
|
||||
set_randomness_ratio(0);
|
||||
set_lifetime_randomness(0);
|
||||
set_use_local_coordinates(true);
|
||||
|
||||
set_draw_order(DRAW_ORDER_INDEX);
|
||||
|
|
|
@ -95,6 +95,7 @@ private:
|
|||
float hue_rot_rand;
|
||||
float anim_offset_rand;
|
||||
float time;
|
||||
float lifetime;
|
||||
Color base_color;
|
||||
|
||||
uint32_t seed;
|
||||
|
@ -137,6 +138,7 @@ private:
|
|||
float pre_process_time;
|
||||
float explosiveness_ratio;
|
||||
float randomness_ratio;
|
||||
float lifetime_randomness;
|
||||
float speed_scale;
|
||||
bool local_coords;
|
||||
int fixed_fps;
|
||||
|
@ -200,6 +202,7 @@ public:
|
|||
void set_pre_process_time(float p_time);
|
||||
void set_explosiveness_ratio(float p_ratio);
|
||||
void set_randomness_ratio(float p_ratio);
|
||||
void set_lifetime_randomness(float p_random);
|
||||
void set_visibility_aabb(const AABB &p_aabb);
|
||||
void set_use_local_coordinates(bool p_enable);
|
||||
void set_speed_scale(float p_scale);
|
||||
|
@ -211,6 +214,7 @@ public:
|
|||
float get_pre_process_time() const;
|
||||
float get_explosiveness_ratio() const;
|
||||
float get_randomness_ratio() const;
|
||||
float get_lifetime_randomness() const;
|
||||
AABB get_visibility_aabb() const;
|
||||
bool get_use_local_coordinates() const;
|
||||
float get_speed_scale() const;
|
||||
|
|
|
@ -101,6 +101,8 @@ void ParticlesMaterial::init_shaders() {
|
|||
shader_names->trail_color_modifier = "trail_color_modifier";
|
||||
|
||||
shader_names->gravity = "gravity";
|
||||
|
||||
shader_names->lifetime_randomness = "lifetime_randomness";
|
||||
}
|
||||
|
||||
void ParticlesMaterial::finish_shaders() {
|
||||
|
@ -173,6 +175,7 @@ void ParticlesMaterial::_update_shader() {
|
|||
code += "uniform float hue_variation_random;\n";
|
||||
code += "uniform float anim_speed_random;\n";
|
||||
code += "uniform float anim_offset_random;\n";
|
||||
code += "uniform float lifetime_randomness;\n";
|
||||
|
||||
switch (emission_shape) {
|
||||
case EMISSION_SHAPE_POINT: {
|
||||
|
@ -285,7 +288,11 @@ 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 += " if (RESTART) {\n";
|
||||
code += " bool restart = false;\n";
|
||||
code += " if (CUSTOM.y > CUSTOM.w) {\n";
|
||||
code += " restart = true;\n";
|
||||
code += " }\n\n";
|
||||
code += " if (RESTART || restart) {\n";
|
||||
|
||||
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
|
||||
code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(0.0, 0.0), 0.0).r;\n";
|
||||
|
@ -325,6 +332,7 @@ void ParticlesMaterial::_update_shader() {
|
|||
code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n";
|
||||
code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle
|
||||
code += " CUSTOM.y = 0.0;\n"; // phase
|
||||
code += " CUSTOM.w = LIFETIME * (1.0 - lifetime_randomness * rand_from_seed(alt_seed));\n";
|
||||
code += " CUSTOM.z = (anim_offset + tex_anim_offset) * mix(1.0, anim_offset_rand, anim_offset_random);\n"; // animation offset (0-1)
|
||||
|
||||
switch (emission_shape) {
|
||||
|
@ -576,6 +584,9 @@ void ParticlesMaterial::_update_shader() {
|
|||
code += " VELOCITY.z = 0.0;\n";
|
||||
code += " TRANSFORM[3].z = 0.0;\n";
|
||||
}
|
||||
code += " if (CUSTOM.y > CUSTOM.w) {";
|
||||
code += " ACTIVE = false;\n";
|
||||
code += " }\n";
|
||||
code += "}\n";
|
||||
code += "\n";
|
||||
|
||||
|
@ -1014,6 +1025,17 @@ Vector3 ParticlesMaterial::get_gravity() const {
|
|||
return gravity;
|
||||
}
|
||||
|
||||
void ParticlesMaterial::set_lifetime_randomness(float p_lifetime) {
|
||||
|
||||
lifetime_randomness = p_lifetime;
|
||||
VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->lifetime_randomness, lifetime_randomness);
|
||||
}
|
||||
|
||||
float ParticlesMaterial::get_lifetime_randomness() const {
|
||||
|
||||
return lifetime_randomness;
|
||||
}
|
||||
|
||||
RID ParticlesMaterial::get_shader_rid() const {
|
||||
|
||||
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
|
||||
|
@ -1118,6 +1140,11 @@ void ParticlesMaterial::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_gravity"), &ParticlesMaterial::get_gravity);
|
||||
ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &ParticlesMaterial::set_gravity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "randomness"), &ParticlesMaterial::set_lifetime_randomness);
|
||||
ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &ParticlesMaterial::get_lifetime_randomness);
|
||||
|
||||
ADD_GROUP("Time", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness");
|
||||
ADD_GROUP("Trail", "trail_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_divisor", PROPERTY_HINT_RANGE, "1,1000000,1"), "set_trail_divisor", "get_trail_divisor");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_size_modifier", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_trail_size_modifier", "get_trail_size_modifier");
|
||||
|
@ -1240,6 +1267,7 @@ ParticlesMaterial::ParticlesMaterial() :
|
|||
set_emission_box_extents(Vector3(1, 1, 1));
|
||||
set_trail_divisor(1);
|
||||
set_gravity(Vector3(0, -9.8, 0));
|
||||
set_lifetime_randomness(0);
|
||||
emission_point_count = 1;
|
||||
|
||||
for (int i = 0; i < PARAM_MAX; i++) {
|
||||
|
|
|
@ -185,6 +185,8 @@ private:
|
|||
StringName trail_color_modifier;
|
||||
|
||||
StringName gravity;
|
||||
|
||||
StringName lifetime_randomness;
|
||||
};
|
||||
|
||||
static ShaderNames *shader_names;
|
||||
|
@ -225,6 +227,8 @@ private:
|
|||
|
||||
Vector3 gravity;
|
||||
|
||||
float lifetime_randomness;
|
||||
|
||||
//do not save emission points here
|
||||
|
||||
protected:
|
||||
|
@ -287,6 +291,9 @@ public:
|
|||
void set_gravity(const Vector3 &p_gravity);
|
||||
Vector3 get_gravity() const;
|
||||
|
||||
void set_lifetime_randomness(float p_lifetime);
|
||||
float get_lifetime_randomness() const;
|
||||
|
||||
static void init_shaders();
|
||||
static void finish_shaders();
|
||||
static void flush_changes();
|
||||
|
|
Loading…
Reference in a new issue