Open FireCatMagic opened 1 week ago
So you want to say that at first, after the transformation, particles are not created, but are created only when their velocity changes?
So you want to say that at first, after the transformation, particles are not created, but are created only when their velocity changes?
Not the velocity, but the speed scale of the whole system. And it seems like without the speed scale change, like 3 particles are created
Very thanks! I'm sure that's where the problem lies:
void CPUParticles3D::convert_from_particles(Node *p_particles) {
GPUParticles3D *gpu_particles = Object::cast_to<GPUParticles3D>(p_particles);
ERR_FAIL_NULL_MSG(gpu_particles, "Only GPUParticles3D nodes can be converted to CPUParticles3D.");
set_emitting(gpu_particles->is_emitting());
set_amount(gpu_particles->get_amount());
set_lifetime(gpu_particles->get_lifetime());
set_one_shot(gpu_particles->get_one_shot());
set_pre_process_time(gpu_particles->get_pre_process_time());
set_explosiveness_ratio(gpu_particles->get_explosiveness_ratio());
set_randomness_ratio(gpu_particles->get_randomness_ratio());
set_visibility_aabb(gpu_particles->get_visibility_aabb());
set_use_local_coordinates(gpu_particles->get_use_local_coordinates());
set_fixed_fps(gpu_particles->get_fixed_fps());
set_fractional_delta(gpu_particles->get_fractional_delta());
set_speed_scale(gpu_particles->get_speed_scale());
set_draw_order(DrawOrder(gpu_particles->get_draw_order()));
set_mesh(gpu_particles->get_draw_pass_mesh(0));
Ref<ParticleProcessMaterial> material = gpu_particles->get_process_material();
if (material.is_null()) {
return;
}
set_direction(material->get_direction());
set_spread(material->get_spread());
set_flatness(material->get_flatness());
set_color(material->get_color());
Ref<GradientTexture1D> gt = material->get_color_ramp();
if (gt.is_valid()) {
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(ParticleProcessMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY));
set_particle_flag(PARTICLE_FLAG_ROTATE_Y, material->get_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_ROTATE_Y));
set_particle_flag(PARTICLE_FLAG_DISABLE_Z, material->get_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_DISABLE_Z));
set_emission_shape(EmissionShape(material->get_emission_shape()));
set_emission_sphere_radius(material->get_emission_sphere_radius());
set_emission_box_extents(material->get_emission_box_extents());
Ref<CurveXYZTexture> scale3D = material->get_param_texture(ParticleProcessMaterial::PARAM_SCALE);
if (scale3D.is_valid()) {
split_scale = true;
scale_curve_x = scale3D->get_curve_x();
scale_curve_y = scale3D->get_curve_y();
scale_curve_z = scale3D->get_curve_z();
}
set_gravity(material->get_gravity());
set_lifetime_randomness(material->get_lifetime_randomness());
#define CONVERT_PARAM(m_param) \
set_param_min(m_param, material->get_param_min(ParticleProcessMaterial::m_param)); \
{ \
Ref<CurveTexture> ctex = material->get_param_texture(ParticleProcessMaterial::m_param); \
if (ctex.is_valid()) \
set_param_curve(m_param, ctex->get_curve()); \
} \
set_param_max(m_param, material->get_param_max(ParticleProcessMaterial::m_param));
CONVERT_PARAM(PARAM_INITIAL_LINEAR_VELOCITY);
CONVERT_PARAM(PARAM_ANGULAR_VELOCITY);
CONVERT_PARAM(PARAM_ORBIT_VELOCITY);
CONVERT_PARAM(PARAM_LINEAR_ACCEL);
CONVERT_PARAM(PARAM_RADIAL_ACCEL);
CONVERT_PARAM(PARAM_TANGENTIAL_ACCEL);
CONVERT_PARAM(PARAM_DAMPING);
CONVERT_PARAM(PARAM_ANGLE);
CONVERT_PARAM(PARAM_SCALE);
CONVERT_PARAM(PARAM_HUE_VARIATION);
CONVERT_PARAM(PARAM_ANIM_SPEED);
CONVERT_PARAM(PARAM_ANIM_OFFSET);
#undef CONVERT_PARAM
}
I'll try to open a PR on this topic.
So you want to say that at first, after the transformation, particles are not created, but are created only when their velocity changes?
Not the velocity, but the speed scale of the whole system. And it seems like without the speed scale change, like 3 particles are created
My PR in moderation. Please, wait new version (if of course they accept the changes)
The issue appears more complex than described, as reducing the speed scale back to 1 causes the particles to eventually stop being produced entirely. In fact, minimizing the window and then maximizing it after some time causes the particle count to be closer to what is expected, which then slowly tapers off until no particles are being generated.
This testing is all in editor, but is definitely a slightly different behavior than what is described here
Further testing shows that the described behavior only occurs when the Fixed FPS is set to 0. Resetting it to a value other than 0 causes the particles to spawn in on switching as expected. As it appears that the default fixed FPS for CPU particles is 0, but GPU particles default to 30, this explains why the conversion would cause issues while creating a GPU particle node in the scene would not have the same behavior.
Continued testing shows that turning off the materials "keep scale" setting on the billboard setting fixes the issue with 0 FPS
Tested versions
4.4-dev2
System information
Godot v4.4.dev2 - Windows 10.0.19045 - OpenGL 3 (Compatibility) - NVIDIA GeForce RTX 4050 Laptop GPU (NVIDIA; 32.0.15.6070) - 13th Gen Intel(R) Core(TM) i5-13500HX (20 Threads)
Issue description
Here's a scene falling with beautiful "snow" using CPUParticles3D
Here's what happens when the particles are converted to GPU particles. https://github.com/user-attachments/assets/ae589387-3adf-47e8-ba8b-ebdfa230d872
I'm not sure how to exactly describe it in words but when converting, it doesn't create the amount of particles it should on the default speed scale, and only actually creates the particles at a higher speed scale, and then resetting the speed scale to 1 the created particles fall as they should.
Steps to reproduce
Create a CPUParticles3D such as shown above, convert to GPUParticles3D, then see it doesn't create as many as it shou;d
Minimal reproduction project (MRP)
New Compressed (zipped) Folder.zip