Random initial color parameter for ParticleMaterial
Works with 2D and 3D GPU Particles
This commit is contained in:
parent
dd10213d6e
commit
ddf82697d7
|
@ -116,6 +116,9 @@
|
|||
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)">
|
||||
Each particle's initial color. If [member texture] is defined, it will be multiplied by this color.
|
||||
</member>
|
||||
<member name="color_initial_ramp" type="Gradient" setter="set_color_initial_ramp" getter="get_color_initial_ramp">
|
||||
Each particle's initial color will vary along this [GradientTexture1D] (multiplied with [member color]).
|
||||
</member>
|
||||
<member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp">
|
||||
Each particle's color will vary along this [Gradient] (multiplied with [member color]).
|
||||
</member>
|
||||
|
|
|
@ -125,6 +125,9 @@
|
|||
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)">
|
||||
Each particle's initial color. To have particle display color in a [BaseMaterial3D] make sure to set [member BaseMaterial3D.vertex_color_use_as_albedo] to [code]true[/code].
|
||||
</member>
|
||||
<member name="color_initial_ramp" type="Gradient" setter="set_color_initial_ramp" getter="get_color_initial_ramp">
|
||||
Each particle's initial color will vary along this [GradientTexture1D] (multiplied with [member color]).
|
||||
</member>
|
||||
<member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp">
|
||||
Each particle's color will vary along this [GradientTexture1D] over its lifetime (multiplied with [member color]).
|
||||
</member>
|
||||
|
|
|
@ -127,6 +127,9 @@
|
|||
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)">
|
||||
Each particle's initial color. If the [GPUParticles2D]'s [code]texture[/code] is defined, it will be multiplied by this color. To have particle display color in a [BaseMaterial3D] make sure to set [member BaseMaterial3D.vertex_color_use_as_albedo] to [code]true[/code].
|
||||
</member>
|
||||
<member name="color_initial_ramp" type="Texture2D" setter="set_color_initial_ramp" getter="get_color_initial_ramp">
|
||||
Each particle's initial color will vary along this [GradientTexture1D] (multiplied with [member color]).
|
||||
</member>
|
||||
<member name="color_ramp" type="Texture2D" setter="set_color_ramp" getter="get_color_ramp">
|
||||
Each particle's color will vary along this [GradientTexture1D] over its lifetime (multiplied with [member color]).
|
||||
</member>
|
||||
|
|
|
@ -398,6 +398,14 @@ Ref<Gradient> CPUParticles2D::get_color_ramp() const {
|
|||
return color_ramp;
|
||||
}
|
||||
|
||||
void CPUParticles2D::set_color_initial_ramp(const Ref<Gradient> &p_ramp) {
|
||||
color_initial_ramp = p_ramp;
|
||||
}
|
||||
|
||||
Ref<Gradient> CPUParticles2D::get_color_initial_ramp() const {
|
||||
return color_initial_ramp;
|
||||
}
|
||||
|
||||
void CPUParticles2D::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) {
|
||||
ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX);
|
||||
particle_flags[p_particle_flag] = p_enable;
|
||||
|
@ -727,6 +735,12 @@ void CPUParticles2D::_particles_process(double p_delta) {
|
|||
p.hue_rot_rand = Math::randf();
|
||||
p.anim_offset_rand = Math::randf();
|
||||
|
||||
if (color_initial_ramp.is_valid()) {
|
||||
p.start_color_rand = color_initial_ramp->get_color_at_offset(Math::randf());
|
||||
} else {
|
||||
p.start_color_rand = Color(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
real_t angle1_rad = direction.angle() + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
|
||||
Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad));
|
||||
p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], Math::randf());
|
||||
|
@ -946,7 +960,7 @@ void CPUParticles2D::_particles_process(double p_delta) {
|
|||
p.color.g = color_rgb.y;
|
||||
p.color.b = color_rgb.z;
|
||||
|
||||
p.color *= p.base_color;
|
||||
p.color *= p.base_color * p.start_color_rand;
|
||||
|
||||
if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) {
|
||||
if (p.velocity.length() > 0.0) {
|
||||
|
@ -1173,6 +1187,11 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) {
|
|||
set_color_ramp(gt->get_gradient());
|
||||
}
|
||||
|
||||
Ref<GradientTexture1D> gti = material->get_color_initial_ramp();
|
||||
if (gti.is_valid()) {
|
||||
set_color_initial_ramp(gti->get_gradient());
|
||||
}
|
||||
|
||||
set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY));
|
||||
|
||||
set_emission_shape(EmissionShape(material->get_emission_shape()));
|
||||
|
@ -1295,6 +1314,9 @@ void CPUParticles2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &CPUParticles2D::set_color_ramp);
|
||||
ClassDB::bind_method(D_METHOD("get_color_ramp"), &CPUParticles2D::get_color_ramp);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_color_initial_ramp", "ramp"), &CPUParticles2D::set_color_initial_ramp);
|
||||
ClassDB::bind_method(D_METHOD("get_color_initial_ramp"), &CPUParticles2D::get_color_initial_ramp);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &CPUParticles2D::set_particle_flag);
|
||||
ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &CPUParticles2D::get_particle_flag);
|
||||
|
||||
|
@ -1386,6 +1408,7 @@ void CPUParticles2D::_bind_methods() {
|
|||
ADD_GROUP("Color", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_initial_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_initial_ramp", "get_color_initial_ramp");
|
||||
|
||||
ADD_GROUP("Hue Variation", "hue_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION);
|
||||
|
|
|
@ -89,6 +89,7 @@ private:
|
|||
real_t scale_rand = 0.0;
|
||||
real_t hue_rot_rand = 0.0;
|
||||
real_t anim_offset_rand = 0.0;
|
||||
Color start_color_rand;
|
||||
double time = 0.0;
|
||||
double lifetime = 0.0;
|
||||
Color base_color;
|
||||
|
@ -156,6 +157,7 @@ private:
|
|||
Ref<Curve> curve_parameters[PARAM_MAX];
|
||||
Color color;
|
||||
Ref<Gradient> color_ramp;
|
||||
Ref<Gradient> color_initial_ramp;
|
||||
|
||||
bool particle_flags[PARTICLE_FLAG_MAX];
|
||||
|
||||
|
@ -250,6 +252,9 @@ public:
|
|||
void set_color_ramp(const Ref<Gradient> &p_ramp);
|
||||
Ref<Gradient> get_color_ramp() const;
|
||||
|
||||
void set_color_initial_ramp(const Ref<Gradient> &p_ramp);
|
||||
Ref<Gradient> get_color_initial_ramp() const;
|
||||
|
||||
void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable);
|
||||
bool get_particle_flag(ParticleFlags p_particle_flag) const;
|
||||
|
||||
|
|
|
@ -368,6 +368,14 @@ Ref<Gradient> CPUParticles3D::get_color_ramp() const {
|
|||
return color_ramp;
|
||||
}
|
||||
|
||||
void CPUParticles3D::set_color_initial_ramp(const Ref<Gradient> &p_ramp) {
|
||||
color_initial_ramp = p_ramp;
|
||||
}
|
||||
|
||||
Ref<Gradient> CPUParticles3D::get_color_initial_ramp() const {
|
||||
return color_initial_ramp;
|
||||
}
|
||||
|
||||
void CPUParticles3D::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) {
|
||||
ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX);
|
||||
particle_flags[p_particle_flag] = p_enable;
|
||||
|
@ -748,6 +756,12 @@ void CPUParticles3D::_particles_process(double p_delta) {
|
|||
p.hue_rot_rand = Math::randf();
|
||||
p.anim_offset_rand = Math::randf();
|
||||
|
||||
if (color_initial_ramp.is_valid()) {
|
||||
p.start_color_rand = color_initial_ramp->get_color_at_offset(Math::randf());
|
||||
} else {
|
||||
p.start_color_rand = Color(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
|
||||
real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
|
||||
Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0);
|
||||
|
@ -1046,7 +1060,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
|
|||
p.color.g = color_rgb.y;
|
||||
p.color.b = color_rgb.z;
|
||||
|
||||
p.color *= p.base_color;
|
||||
p.color *= p.base_color * p.start_color_rand;
|
||||
|
||||
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
|
||||
if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) {
|
||||
|
@ -1333,6 +1347,11 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) {
|
|||
set_color_ramp(gt->get_gradient());
|
||||
}
|
||||
|
||||
Ref<GradientTexture1D> gti = material->get_color_initial_ramp();
|
||||
if (gti.is_valid()) {
|
||||
set_color_initial_ramp(gti->get_gradient());
|
||||
}
|
||||
|
||||
set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY));
|
||||
set_particle_flag(PARTICLE_FLAG_ROTATE_Y, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ROTATE_Y));
|
||||
set_particle_flag(PARTICLE_FLAG_DISABLE_Z, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_DISABLE_Z));
|
||||
|
@ -1459,6 +1478,9 @@ void CPUParticles3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &CPUParticles3D::set_color_ramp);
|
||||
ClassDB::bind_method(D_METHOD("get_color_ramp"), &CPUParticles3D::get_color_ramp);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_color_initial_ramp", "ramp"), &CPUParticles3D::set_color_initial_ramp);
|
||||
ClassDB::bind_method(D_METHOD("get_color_initial_ramp"), &CPUParticles3D::get_color_initial_ramp);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &CPUParticles3D::set_particle_flag);
|
||||
ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &CPUParticles3D::get_particle_flag);
|
||||
|
||||
|
@ -1572,6 +1594,7 @@ void CPUParticles3D::_bind_methods() {
|
|||
ADD_GROUP("Color", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_initial_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_initial_ramp", "get_color_initial_ramp");
|
||||
|
||||
ADD_GROUP("Hue Variation", "hue_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION);
|
||||
|
|
|
@ -91,6 +91,7 @@ private:
|
|||
real_t scale_rand = 0.0;
|
||||
real_t hue_rot_rand = 0.0;
|
||||
real_t anim_offset_rand = 0.0;
|
||||
Color start_color_rand;
|
||||
double time = 0.0;
|
||||
double lifetime = 0.0;
|
||||
Color base_color;
|
||||
|
@ -160,6 +161,7 @@ private:
|
|||
Ref<Curve> curve_parameters[PARAM_MAX];
|
||||
Color color = Color(1, 1, 1, 1);
|
||||
Ref<Gradient> color_ramp;
|
||||
Ref<Gradient> color_initial_ramp;
|
||||
|
||||
bool particle_flags[PARTICLE_FLAG_MAX] = {};
|
||||
|
||||
|
@ -261,6 +263,9 @@ public:
|
|||
void set_color_ramp(const Ref<Gradient> &p_ramp);
|
||||
Ref<Gradient> get_color_ramp() const;
|
||||
|
||||
void set_color_initial_ramp(const Ref<Gradient> &p_ramp);
|
||||
Ref<Gradient> get_color_initial_ramp() const;
|
||||
|
||||
void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable);
|
||||
bool get_particle_flag(ParticleFlags p_particle_flag) const;
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ void ParticlesMaterial::init_shaders() {
|
|||
|
||||
shader_names->color = "color_value";
|
||||
shader_names->color_ramp = "color_ramp";
|
||||
shader_names->color_initial_ramp = "color_initial_ramp";
|
||||
|
||||
shader_names->emission_sphere_radius = "emission_sphere_radius";
|
||||
shader_names->emission_box_extents = "emission_box_extents";
|
||||
|
@ -232,6 +233,10 @@ void ParticlesMaterial::_update_shader() {
|
|||
code += "uniform sampler2D color_ramp;\n";
|
||||
}
|
||||
|
||||
if (color_initial_ramp.is_valid()) {
|
||||
code += "uniform sampler2D color_initial_ramp;\n";
|
||||
}
|
||||
|
||||
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
|
||||
code += "uniform sampler2D linear_velocity_texture;\n";
|
||||
}
|
||||
|
@ -311,6 +316,9 @@ void ParticlesMaterial::_update_shader() {
|
|||
code += " float scale_rand = rand_from_seed(alt_seed);\n";
|
||||
code += " float hue_rot_rand = rand_from_seed(alt_seed);\n";
|
||||
code += " float anim_offset_rand = rand_from_seed(alt_seed);\n";
|
||||
if (color_initial_ramp.is_valid()) {
|
||||
code += " float color_initial_rand = rand_from_seed(alt_seed);\n";
|
||||
}
|
||||
code += " float pi = 3.14159;\n";
|
||||
code += " float degree_to_rad = pi / 180.0;\n";
|
||||
code += "\n";
|
||||
|
@ -462,6 +470,10 @@ void ParticlesMaterial::_update_shader() {
|
|||
code += " float scale_rand = rand_from_seed(alt_seed);\n";
|
||||
code += " float hue_rot_rand = rand_from_seed(alt_seed);\n";
|
||||
code += " float anim_offset_rand = rand_from_seed(alt_seed);\n";
|
||||
if (color_initial_ramp.is_valid()) {
|
||||
code += " float color_initial_rand = rand_from_seed(alt_seed);\n";
|
||||
}
|
||||
|
||||
code += " float pi = 3.14159;\n";
|
||||
code += " float degree_to_rad = pi / 180.0;\n";
|
||||
code += "\n";
|
||||
|
@ -620,6 +632,12 @@ void ParticlesMaterial::_update_shader() {
|
|||
} else {
|
||||
code += " COLOR = hue_rot_mat * color_value;\n";
|
||||
}
|
||||
|
||||
if (color_initial_ramp.is_valid()) {
|
||||
code += " vec4 start_color = textureLod(color_initial_ramp, vec2(color_initial_rand, 0.0), 0.0);\n";
|
||||
code += " COLOR *= start_color;\n";
|
||||
}
|
||||
|
||||
if (emission_color_texture.is_valid() && (emission_shape == EMISSION_SHAPE_POINTS || emission_shape == EMISSION_SHAPE_DIRECTED_POINTS)) {
|
||||
code += " COLOR *= texelFetch(emission_texture_color, emission_tex_ofs, 0);\n";
|
||||
}
|
||||
|
@ -988,6 +1006,18 @@ Ref<Texture2D> ParticlesMaterial::get_color_ramp() const {
|
|||
return color_ramp;
|
||||
}
|
||||
|
||||
void ParticlesMaterial::set_color_initial_ramp(const Ref<Texture2D> &p_texture) {
|
||||
color_initial_ramp = p_texture;
|
||||
RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
|
||||
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_initial_ramp, tex_rid);
|
||||
_queue_shader_change();
|
||||
notify_property_list_changed();
|
||||
}
|
||||
|
||||
Ref<Texture2D> ParticlesMaterial::get_color_initial_ramp() const {
|
||||
return color_initial_ramp;
|
||||
}
|
||||
|
||||
void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) {
|
||||
ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX);
|
||||
particle_flags[p_particle_flag] = p_enable;
|
||||
|
@ -1282,6 +1312,9 @@ void ParticlesMaterial::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &ParticlesMaterial::set_color_ramp);
|
||||
ClassDB::bind_method(D_METHOD("get_color_ramp"), &ParticlesMaterial::get_color_ramp);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_color_initial_ramp", "ramp"), &ParticlesMaterial::set_color_initial_ramp);
|
||||
ClassDB::bind_method(D_METHOD("get_color_initial_ramp"), &ParticlesMaterial::get_color_initial_ramp);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &ParticlesMaterial::set_particle_flag);
|
||||
ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &ParticlesMaterial::get_particle_flag);
|
||||
|
||||
|
@ -1414,6 +1447,7 @@ void ParticlesMaterial::_bind_methods() {
|
|||
ADD_GROUP("Color", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture1D"), "set_color_ramp", "get_color_ramp");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_initial_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture1D"), "set_color_initial_ramp", "get_color_initial_ramp");
|
||||
|
||||
ADD_GROUP("Hue Variation", "hue_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION);
|
||||
|
|
|
@ -194,6 +194,7 @@ private:
|
|||
|
||||
StringName color;
|
||||
StringName color_ramp;
|
||||
StringName color_initial_ramp;
|
||||
|
||||
StringName emission_sphere_radius;
|
||||
StringName emission_box_extents;
|
||||
|
@ -237,6 +238,7 @@ private:
|
|||
Ref<Texture2D> tex_parameters[PARAM_MAX];
|
||||
Color color;
|
||||
Ref<Texture2D> color_ramp;
|
||||
Ref<Texture2D> color_initial_ramp;
|
||||
|
||||
bool particle_flags[PARTICLE_FLAG_MAX];
|
||||
|
||||
|
@ -299,6 +301,9 @@ public:
|
|||
void set_color_ramp(const Ref<Texture2D> &p_texture);
|
||||
Ref<Texture2D> get_color_ramp() const;
|
||||
|
||||
void set_color_initial_ramp(const Ref<Texture2D> &p_texture);
|
||||
Ref<Texture2D> get_color_initial_ramp() const;
|
||||
|
||||
void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable);
|
||||
bool get_particle_flag(ParticleFlags p_particle_flag) const;
|
||||
|
||||
|
|
Loading…
Reference in New Issue