1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-14 13:41:12 +00:00

Implement Particle Trails

-Enable the trails and set the length in seconds
-Provide a mesh with a skeleton and a skin
-Or, alternatively use one of the built-in TubeTrailMesh/RibbonTrailMesh
-Works deterministically
-Fixed particle collisions (were broken)
-Not working in 2D yet (that will happen next)
This commit is contained in:
reduz
2021-04-27 12:43:49 -03:00
parent 0ad03ba052
commit 90056460ad
33 changed files with 1576 additions and 180 deletions

View File

@@ -660,6 +660,11 @@ private:
float time;
float delta;
uint32_t frame;
uint32_t pad0;
uint32_t pad1;
uint32_t pad2;
uint32_t random_seed;
uint32_t attractor_count;
uint32_t collider_count;
@@ -704,10 +709,16 @@ private:
AABB custom_aabb = AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8));
bool use_local_coords = true;
RID process_material;
uint32_t frame_counter = 0;
RS::ParticlesTransformAlign transform_align = RS::PARTICLES_TRANSFORM_ALIGN_DISABLED;
RS::ParticlesDrawOrder draw_order = RS::PARTICLES_DRAW_ORDER_INDEX;
Vector<RID> draw_passes;
Vector<Transform> trail_bind_poses;
bool trail_bind_poses_dirty = false;
RID trail_bind_pose_buffer;
RID trail_bind_pose_uniform_set;
RID particle_buffer;
RID particle_instance_buffer;
@@ -739,7 +750,8 @@ private:
float speed_scale = 1.0;
int fixed_fps = 0;
int fixed_fps = 30;
bool interpolate = true;
bool fractional_delta = false;
float frame_remainder = 0;
float collision_base_size = 0.01;
@@ -759,12 +771,19 @@ private:
Dependency dependency;
ParticlesFrameParams frame_params;
float trail_length = 1.0;
bool trails_enabled = false;
LocalVector<ParticlesFrameParams> frame_history;
LocalVector<ParticlesFrameParams> trail_params;
Particles() {
}
};
void _particles_process(Particles *p_particles, float p_delta);
void _particles_allocate_emission_buffer(Particles *particles);
void _particles_free_data(Particles *particles);
void _particles_update_buffers(Particles *particles);
struct ParticlesShader {
struct PushConstant {
@@ -776,7 +795,7 @@ private:
uint32_t use_fractional_delta;
uint32_t sub_emitter_mode;
uint32_t can_emit;
uint32_t pad;
uint32_t trail_pass;
};
ParticlesShaderRD shader;
@@ -791,6 +810,14 @@ private:
struct CopyPushConstant {
float sort_direction[3];
uint32_t total_particles;
uint32_t trail_size;
uint32_t trail_total;
float frame_delta;
float frame_remainder;
float align_up[3];
uint32_t align_mode;
};
enum {
@@ -804,6 +831,8 @@ private:
RID copy_shader_version;
RID copy_pipelines[COPY_MODE_MAX];
LocalVector<float> pose_update_buffer;
} particles_shader;
Particles *particle_update_list = nullptr;
@@ -2076,10 +2105,17 @@ public:
void particles_set_use_local_coordinates(RID p_particles, bool p_enable);
void particles_set_process_material(RID p_particles, RID p_material);
void particles_set_fixed_fps(RID p_particles, int p_fps);
void particles_set_interpolate(RID p_particles, bool p_enable);
void particles_set_fractional_delta(RID p_particles, bool p_enable);
void particles_set_collision_base_size(RID p_particles, float p_size);
void particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align);
void particles_set_trails(RID p_particles, bool p_enable, float p_length);
void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform> &p_bind_poses);
void particles_restart(RID p_particles);
void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags);
void particles_set_subemitter(RID p_particles, RID p_subemitter_particles);
void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order);
@@ -2097,15 +2133,21 @@ public:
int particles_get_draw_passes(RID p_particles) const;
RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const;
void particles_set_view_axis(RID p_particles, const Vector3 &p_axis);
void particles_set_view_axis(RID p_particles, const Vector3 &p_axis, const Vector3 &p_up_axis);
virtual bool particles_is_inactive(RID p_particles) const;
_FORCE_INLINE_ uint32_t particles_get_amount(RID p_particles) {
_FORCE_INLINE_ uint32_t particles_get_amount(RID p_particles, uint32_t &r_trail_divisor) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, 0);
return particles->amount;
if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) {
r_trail_divisor = particles->trail_bind_poses.size();
} else {
r_trail_divisor = 1;
}
return particles->amount * r_trail_divisor;
}
_FORCE_INLINE_ uint32_t particles_is_using_local_coords(RID p_particles) {
@@ -2119,6 +2161,8 @@ public:
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, RID());
if (particles->particles_transforms_buffer_uniform_set.is_null()) {
_particles_update_buffers(particles);
Vector<RD::Uniform> uniforms;
{