track emitter particle sequence on cpu
This commit is contained in:
parent
f30ed79e91
commit
d0e119c476
@ -2633,25 +2633,37 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
frame->emitters_count += 1;
|
frame->emitters_count += 1;
|
||||||
emitter = &en->emitter;
|
emitter = &en->emitter;
|
||||||
}
|
}
|
||||||
V_ParticleFlag flags = V_ParticleFlag_StainOnPrune;
|
V_ParticleFlag flags = 0;
|
||||||
|
flags |= V_ParticleFlag_StainOnPrune;
|
||||||
|
if (TweakBool("Emitter stain trail", 0))
|
||||||
|
{
|
||||||
|
flags |= V_ParticleFlag_StainTrail;
|
||||||
|
}
|
||||||
|
|
||||||
emitter->flags = flags;
|
emitter->flags = flags;
|
||||||
|
|
||||||
Vec2 dir = victim_raycast.normal;
|
Vec2 dir = victim_raycast.normal;
|
||||||
emitter->pos = victim_raycast.p;
|
emitter->pos = victim_raycast.p;
|
||||||
|
|
||||||
emitter->count = 50;
|
f32 count = TweakFloat("Emitter count", 50, 0, 10000);
|
||||||
|
f32 speed = TweakFloat("Emitter speed", 10, 0, 100);
|
||||||
|
f32 falloff = TweakFloat("Emitter falloff", 30, 0, 100);
|
||||||
|
// f32 angle_spread = TweakFloat("Emitter spread", Tau / 20, 0, Tau);
|
||||||
|
f32 angle_spread = TweakFloat("Emitter spread", 0.1, 0, 1) * Tau;
|
||||||
|
|
||||||
|
emitter->count = count;
|
||||||
// emitter->count = 100;
|
// emitter->count = 100;
|
||||||
// emitter->count = 500;
|
// emitter->count = 500;
|
||||||
|
|
||||||
emitter->speed = 10;
|
emitter->speed = speed;
|
||||||
emitter->speed_spread = 20;
|
emitter->speed_spread = speed * 2;
|
||||||
|
|
||||||
emitter->velocity_falloff = 30;
|
emitter->velocity_falloff = falloff;
|
||||||
emitter->velocity_falloff_spread = 60;
|
emitter->velocity_falloff_spread = falloff * 2;
|
||||||
|
|
||||||
emitter->angle = AngleFromVec2(dir);
|
emitter->angle = AngleFromVec2(dir);
|
||||||
// emitter->angle_spread = Tau / 4;
|
// emitter->angle_spread = Tau / 4;
|
||||||
emitter->angle_spread = Tau / 20;
|
emitter->angle_spread = angle_spread;
|
||||||
// emitter->angle_spread = Tau / 32;
|
// emitter->angle_spread = Tau / 32;
|
||||||
|
|
||||||
emitter->color_lin = LinearFromSrgb(VEC4(0.5, 0.1, 0.1, 1));
|
emitter->color_lin = LinearFromSrgb(VEC4(0.5, 0.1, 0.1, 1));
|
||||||
@ -2666,6 +2678,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
// V_DrawPoint(victim_raycast.p, Color_Green);
|
// V_DrawPoint(victim_raycast.p, Color_Green);
|
||||||
// V_DrawLine(victim_raycast.p, AddVec2(victim_raycast.p, MulVec2(victim_raycast.normal, 0.5)), Color_White);
|
// V_DrawLine(victim_raycast.p, AddVec2(victim_raycast.p, MulVec2(victim_raycast.normal, 0.5)), Color_White);
|
||||||
|
|
||||||
|
emitter->first_particle_seq = V.particle_seq;
|
||||||
|
V.particle_seq += emitter->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2778,7 +2793,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
case S_DebugDrawKind_Shape:
|
case S_DebugDrawKind_Shape:
|
||||||
{
|
{
|
||||||
S_Shape ui_shape = S_MulXformShape(frame->xf.world_to_ui, desc->shape);
|
S_Shape ui_shape = S_MulXformShape(frame->xf.world_to_ui, desc->shape);
|
||||||
V_DrawShape(ui_shape, color, detail, V_DrawFlag_Line);
|
// V_DrawShape(ui_shape, color, detail, V_DrawFlag_Line);
|
||||||
|
V_DrawShape(ui_shape, color, detail, V_DrawFlag_None);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2814,6 +2830,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
// emitter->angle_spread = 0.5;
|
// emitter->angle_spread = 0.5;
|
||||||
emitter->angle_spread = Tau / 4;
|
emitter->angle_spread = Tau / 4;
|
||||||
// emitter->angle_spread = Tau;
|
// emitter->angle_spread = Tau;
|
||||||
|
|
||||||
|
emitter->first_particle_seq = V.particle_seq;
|
||||||
|
V.particle_seq += emitter->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|||||||
@ -289,6 +289,9 @@ Struct(V_Ctx)
|
|||||||
V_Panel *root_panel;
|
V_Panel *root_panel;
|
||||||
V_Window *dragging_window;
|
V_Window *dragging_window;
|
||||||
|
|
||||||
|
// Atomic monotonically increasing allocation counter sequence for GPU particle ring buffer
|
||||||
|
u32 particle_seq;
|
||||||
|
|
||||||
Atomic32 shutdown;
|
Atomic32 shutdown;
|
||||||
Fence shutdown_complete;
|
Fence shutdown_complete;
|
||||||
|
|
||||||
|
|||||||
@ -259,18 +259,13 @@ ComputeShader(V_EmitParticlesCS, 64)
|
|||||||
{
|
{
|
||||||
V_Emitter emitter = emitters[emitter_idx];
|
V_Emitter emitter = emitters[emitter_idx];
|
||||||
|
|
||||||
u32 first_particle_seq;
|
for (u32 i = 0; i < emitter.count; ++i)
|
||||||
InterlockedAdd(state_buff[0].particle_seq, emitter.count, first_particle_seq);
|
|
||||||
u32 last_particle_seq = first_particle_seq + emitter.count;
|
|
||||||
|
|
||||||
u32 particles_created_count = 0;
|
|
||||||
for (u32 particle_seq = first_particle_seq; particle_seq < last_particle_seq; ++particle_seq)
|
|
||||||
{
|
{
|
||||||
|
u32 particle_seq = emitter.first_particle_seq + i;
|
||||||
u32 particle_idx = particle_seq % params.max_particles;
|
u32 particle_idx = particle_seq % params.max_particles;
|
||||||
particles[particle_idx].exists = 1;
|
particles[particle_idx].exists = 1;
|
||||||
particles[particle_idx].emitter_init_num = emitter_idx + 1;
|
particles[particle_idx].emitter_init_num = emitter_idx + 1;
|
||||||
particles[particle_idx].idx_in_emitter = particles_created_count;
|
particles[particle_idx].seq = particle_seq;
|
||||||
particles_created_count += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +291,7 @@ ComputeShader(V_SimParticlesCS, 64)
|
|||||||
{
|
{
|
||||||
V_Emitter emitter = G_Dereference<V_Emitter>(params.emitters)[particle.emitter_init_num - 1];
|
V_Emitter emitter = G_Dereference<V_Emitter>(params.emitters)[particle.emitter_init_num - 1];
|
||||||
|
|
||||||
u64 seed = MixU64(emitter.seed + particle.idx_in_emitter);
|
u64 seed = MixU64(emitter.seed + particle.seq);
|
||||||
|
|
||||||
// u32 speed_noise = (u32)((seed >> 0) & 0xFF);
|
// u32 speed_noise = (u32)((seed >> 0) & 0xFF);
|
||||||
// u32 angle_noise = (u32)((seed >> 8) & 0xFF);
|
// u32 angle_noise = (u32)((seed >> 8) & 0xFF);
|
||||||
@ -321,6 +316,7 @@ ComputeShader(V_SimParticlesCS, 64)
|
|||||||
f32 velocity_falloff = emitter.velocity_falloff + rand_falloff * emitter.velocity_falloff;
|
f32 velocity_falloff = emitter.velocity_falloff + rand_falloff * emitter.velocity_falloff;
|
||||||
Vec3 color = emitter.color_lin.rgb + Vec3(rand_r, rand_g, rand_b) * emitter.color_spread;
|
Vec3 color = emitter.color_lin.rgb + Vec3(rand_r, rand_g, rand_b) * emitter.color_spread;
|
||||||
|
|
||||||
|
particle.flags = emitter.flags;
|
||||||
particle.pos = emitter.pos;
|
particle.pos = emitter.pos;
|
||||||
particle.velocity = Vec2(cos(angle), sin(angle)) * speed;
|
particle.velocity = Vec2(cos(angle), sin(angle)) * speed;
|
||||||
particle.velocity_falloff = velocity_falloff;
|
particle.velocity_falloff = velocity_falloff;
|
||||||
@ -333,7 +329,7 @@ ComputeShader(V_SimParticlesCS, 64)
|
|||||||
{
|
{
|
||||||
particle.pos += particle.velocity * params.dt;
|
particle.pos += particle.velocity * params.dt;
|
||||||
particle.velocity = lerp(particle.velocity, 0, particle.velocity_falloff * params.dt);
|
particle.velocity = lerp(particle.velocity, 0, particle.velocity_falloff * params.dt);
|
||||||
if (particle.exists < 0.0001)
|
if (particle.exists < 0.001 || dot(particle.velocity, particle.velocity) < (0.001 * 0.001))
|
||||||
{
|
{
|
||||||
particle.exists = 0;
|
particle.exists = 0;
|
||||||
}
|
}
|
||||||
@ -346,7 +342,7 @@ ComputeShader(V_SimParticlesCS, 64)
|
|||||||
if (cell_pos.x >= 0 && cell_pos.y >= 0 && cell_pos.x < countof(stains).x && cell_pos.y < countof(stains).y)
|
if (cell_pos.x >= 0 && cell_pos.y >= 0 && cell_pos.x < countof(stains).x && cell_pos.y < countof(stains).y)
|
||||||
{
|
{
|
||||||
b32 should_stain = 0;
|
b32 should_stain = 0;
|
||||||
if (particle.flags & V_ParticleFlag_StainOnPrune && particle.exists == 0)
|
if (particle.flags & V_ParticleFlag_StainTrail || ((particle.flags & V_ParticleFlag_StainOnPrune) && particle.exists == 0))
|
||||||
{
|
{
|
||||||
should_stain = 1;
|
should_stain = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,7 +35,8 @@ Struct(V_Xforms)
|
|||||||
|
|
||||||
Struct(V_GpuState)
|
Struct(V_GpuState)
|
||||||
{
|
{
|
||||||
u32 particle_seq; // Atomic monotonically increasing allocation counter sequence for particle ring buffer
|
// u32 particle_seq; // Atomic monotonically increasing allocation counter sequence for particle ring buffer
|
||||||
|
i32 _;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(V_GpuParams)
|
Struct(V_GpuParams)
|
||||||
@ -87,16 +88,19 @@ Enum(V_ParticleFlag)
|
|||||||
{
|
{
|
||||||
V_ParticleFlag_None = 0,
|
V_ParticleFlag_None = 0,
|
||||||
V_ParticleFlag_StainOnPrune = (1 << 0),
|
V_ParticleFlag_StainOnPrune = (1 << 0),
|
||||||
|
V_ParticleFlag_StainTrail = (1 << 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(V_Emitter)
|
Struct(V_Emitter)
|
||||||
{
|
{
|
||||||
V_ParticleFlag flags;
|
V_ParticleFlag flags;
|
||||||
|
|
||||||
Vec2 pos;
|
u32 first_particle_seq;
|
||||||
u32 count;
|
u32 count;
|
||||||
u64 seed;
|
u64 seed;
|
||||||
|
|
||||||
|
Vec2 pos;
|
||||||
|
|
||||||
f32 speed;
|
f32 speed;
|
||||||
f32 speed_spread;
|
f32 speed_spread;
|
||||||
|
|
||||||
@ -113,11 +117,10 @@ Struct(V_Emitter)
|
|||||||
// TODO: Pack this efficiently
|
// TODO: Pack this efficiently
|
||||||
Struct(V_Particle)
|
Struct(V_Particle)
|
||||||
{
|
{
|
||||||
V_ParticleFlag flags;
|
u32 emitter_init_num; // if != 0, then initialize using emitter at index [emitter_init_num - 1]
|
||||||
|
|
||||||
u32 emitter_init_num; // if != 0, then initialize using emitter at index (emitter_init_num - 1)
|
|
||||||
u32 seq;
|
u32 seq;
|
||||||
u32 idx_in_emitter;
|
|
||||||
|
V_ParticleFlag flags;
|
||||||
|
|
||||||
Vec2 pos;
|
Vec2 pos;
|
||||||
Vec2 velocity;
|
Vec2 velocity;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user