blood wall staining
This commit is contained in:
parent
6957be38b5
commit
fff1b69eff
@ -2190,7 +2190,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
quad->quad_uv_to_world_af = wep_uv_to_world_af;
|
||||
quad->tex = wep.tex;
|
||||
quad->tex_slice_uv = DivRng2Vec2(wep.tex_rect, wep.tex_dims);
|
||||
quad->occluder = V_OccluderKind_Guy;
|
||||
// quad->occluder = V_OccluderKind_Guy;
|
||||
}
|
||||
|
||||
//- Push body quad
|
||||
@ -2560,8 +2560,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Push test emitter
|
||||
|
||||
if (frame->held_buttons[Button_F])
|
||||
// if (frame->held_buttons[Button_F] && !prev_frame->held_buttons[Button_F])
|
||||
// if (frame->held_buttons[Button_F])
|
||||
if (frame->held_buttons[Button_F] && !prev_frame->held_buttons[Button_F])
|
||||
{
|
||||
{
|
||||
V_Emitter emitter = Zi;
|
||||
|
||||
@ -346,8 +346,9 @@ ComputeShader(V_SimParticlesCS, 64)
|
||||
b32 stepped_x = 0;
|
||||
b32 stepped_y = 0;
|
||||
|
||||
// u32 max_iterations = 32;
|
||||
// TODO: Tune this
|
||||
u32 max_iterations = 128;
|
||||
|
||||
b32 done = 0;
|
||||
f32 t_diff = 0;
|
||||
for (u32 iteration_idx = 0; iteration_idx < max_iterations && !done; ++iteration_idx)
|
||||
@ -393,32 +394,45 @@ ComputeShader(V_SimParticlesCS, 64)
|
||||
V_OccluderKind occluder = (V_OccluderKind)occluders[cell_pos];
|
||||
if (occluder != V_OccluderKind_None)
|
||||
{
|
||||
collision = 1;
|
||||
done = 1;
|
||||
u64 collision_seed = MixU64(V_ParticleCellBasis ^ seed0 ^ particle.cells_count);
|
||||
f32 rand_collision_angle = Norm16(collision_seed >> 0);
|
||||
f32 rand_collision_velocity = Norm16(collision_seed >> 16);
|
||||
f32 rand_collision_penetration = Norm16(collision_seed >> 32);
|
||||
if (rand_collision_penetration >= desc.pen_rate)
|
||||
{
|
||||
collision = 1;
|
||||
done = 1;
|
||||
{
|
||||
if (stepped_x)
|
||||
{
|
||||
if (!AnyBit(desc.flags, V_ParticleFlag_NoReflect))
|
||||
{
|
||||
particle.velocity.x *= -1;
|
||||
}
|
||||
t = saturate(t_hit.x);
|
||||
}
|
||||
else if (stepped_y)
|
||||
{
|
||||
if (!AnyBit(desc.flags, V_ParticleFlag_NoReflect))
|
||||
{
|
||||
particle.velocity.y *= -1;
|
||||
}
|
||||
t = saturate(t_hit.y);
|
||||
}
|
||||
{
|
||||
f32 collision_angle = lerp(-0.05 * Tau, 0.05 * Tau, rand_collision_angle);
|
||||
|
||||
if (stepped_x)
|
||||
{
|
||||
particle.velocity.x *= -1;
|
||||
t = saturate(t_hit.x);
|
||||
f32 collision_velocity_falloff = lerp(50, 100, rand_collision_velocity);
|
||||
// f32 collision_velocity_falloff = lerp(5000, 10000, rand_collision_velocity);
|
||||
// f32 collision_velocity_falloff = lerp(500, 10000, rand_collision_velocity);
|
||||
// f32 collision_velocity_falloff = 0;
|
||||
|
||||
particle.velocity = RotateVec2Angle(particle.velocity, collision_angle);
|
||||
particle.velocity *= 1.0f - saturate(collision_velocity_falloff * frame.dt);
|
||||
}
|
||||
}
|
||||
else if (stepped_y)
|
||||
{
|
||||
particle.velocity.y *= -1;
|
||||
t = saturate(t_hit.y);
|
||||
}
|
||||
{
|
||||
u64 collision_seed = MixU64(V_ParticleCollisionBasis ^ seed0 ^ particle.collisions_count);
|
||||
f32 rand_collision_angle = Norm16(collision_seed >> 0);
|
||||
f32 rand_collision_velocity = Norm16(collision_seed >> 16);
|
||||
f32 collision_angle = lerp(-0.05 * Tau, 0.05 * Tau, rand_collision_angle);
|
||||
// f32 collision_velocity_falloff = lerp(0, 1, rand_collision_velocity);
|
||||
f32 collision_velocity_falloff = 0;
|
||||
particle.velocity = RotateVec2Angle(particle.velocity, collision_angle);
|
||||
particle.velocity *= 1.0f - collision_velocity_falloff;
|
||||
}
|
||||
++particle.collisions_count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (AnyBit(desc.flags, V_ParticleFlag_PruneWhenStill))
|
||||
@ -434,31 +448,34 @@ ComputeShader(V_SimParticlesCS, 64)
|
||||
particle.stain_accum += 1;
|
||||
}
|
||||
|
||||
//- Stain
|
||||
u32 stains_count = floor(particle.stain_accum);
|
||||
if (stains_count > 0)
|
||||
if (!collision)
|
||||
{
|
||||
InterlockedMax(stain_cells[cell_pos], packed);
|
||||
InterlockedAdd(stain_densities[cell_pos], stains_count);
|
||||
drynesses[cell_pos] = 0;
|
||||
particle.stain_accum -= stains_count;
|
||||
}
|
||||
|
||||
//- Draw
|
||||
{
|
||||
b32 should_draw_ground = !collision && is_visible && AnyBit(desc.flags, V_ParticleFlag_Ground);
|
||||
b32 should_draw_air = !collision && is_visible && AnyBit(desc.flags, V_ParticleFlag_Air);
|
||||
|
||||
if (should_draw_ground)
|
||||
//- Stain
|
||||
u32 stains_count = floor(particle.stain_accum);
|
||||
if (stains_count > 0)
|
||||
{
|
||||
InterlockedMax(ground_cells[cell_pos], packed);
|
||||
InterlockedAdd(ground_densities[cell_pos], 1);
|
||||
InterlockedMax(stain_cells[cell_pos], packed);
|
||||
InterlockedAdd(stain_densities[cell_pos], stains_count);
|
||||
drynesses[cell_pos] = 0;
|
||||
particle.stain_accum -= stains_count;
|
||||
}
|
||||
|
||||
if (should_draw_air)
|
||||
//- Draw
|
||||
{
|
||||
InterlockedMax(air_cells[cell_pos], packed);
|
||||
InterlockedAdd(air_densities[cell_pos], 1);
|
||||
b32 should_draw_ground = is_visible && AnyBit(desc.flags, V_ParticleFlag_Ground);
|
||||
b32 should_draw_air = is_visible && AnyBit(desc.flags, V_ParticleFlag_Air);
|
||||
|
||||
if (should_draw_ground)
|
||||
{
|
||||
InterlockedMax(ground_cells[cell_pos], packed);
|
||||
InterlockedAdd(ground_densities[cell_pos], 1);
|
||||
}
|
||||
|
||||
if (should_draw_air)
|
||||
{
|
||||
InterlockedMax(air_cells[cell_pos], packed);
|
||||
InterlockedAdd(air_densities[cell_pos], 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -467,6 +484,8 @@ ComputeShader(V_SimParticlesCS, 64)
|
||||
done = 1;
|
||||
prune = 1;
|
||||
}
|
||||
|
||||
particle.cells_count += 1;
|
||||
iteration_idx += 1;
|
||||
}
|
||||
}
|
||||
@ -691,7 +710,7 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
||||
stain_particle_color = V_ColorFromParticle(particle_kind, particle_idx, density, dryness);
|
||||
}
|
||||
}
|
||||
stain_particle_color.rgb *= 1.0 - (0.75 * tile_is_wall); // Darken wall stains
|
||||
stain_particle_color.rgb *= 1.0 - (0.30 * tile_is_wall); // Darken wall stains
|
||||
stain_particle_color.rgb *= stain_particle_color.a;
|
||||
}
|
||||
//- Ground
|
||||
|
||||
@ -11,37 +11,43 @@ V_ParticleDesc V_DescFromParticleKind(V_ParticleKind kind)
|
||||
V_ParticleDesc result;
|
||||
{
|
||||
PERSIST Readonly V_ParticleFlag flags[V_ParticleKind_COUNT] = {
|
||||
#define X(name, flags, stain_rate, r, g, b, a) flags,
|
||||
#define X(name, flags, stain_rate, pen_rate, r, g, b, a) flags,
|
||||
V_ParticlesXList(X)
|
||||
#undef X
|
||||
};
|
||||
PERSIST Readonly f32 stain_rates[V_ParticleKind_COUNT] = {
|
||||
#define X(name, flags, stain_rate, r, g, b, a) stain_rate,
|
||||
#define X(name, flags, stain_rate, pen_rate, r, g, b, a) stain_rate,
|
||||
V_ParticlesXList(X)
|
||||
#undef X
|
||||
};
|
||||
PERSIST Readonly f32 pen_rates[V_ParticleKind_COUNT] = {
|
||||
#define X(name, flags, stain_rate, pen_rate, r, g, b, a) pen_rate,
|
||||
V_ParticlesXList(X)
|
||||
#undef X
|
||||
};
|
||||
PERSIST Readonly f32 r[V_ParticleKind_COUNT] = {
|
||||
#define X(name, flags, stain_rate, r, g, b, a) r,
|
||||
#define X(name, flags, stain_rate, pen_rate, r, g, b, a) r,
|
||||
V_ParticlesXList(X)
|
||||
#undef X
|
||||
};
|
||||
PERSIST Readonly f32 g[V_ParticleKind_COUNT] = {
|
||||
#define X(name, flags, stain_rate, r, g, b, a) g,
|
||||
#define X(name, flags, stain_rate, pen_rate, r, g, b, a) g,
|
||||
V_ParticlesXList(X)
|
||||
#undef X
|
||||
};
|
||||
PERSIST Readonly f32 b[V_ParticleKind_COUNT] = {
|
||||
#define X(name, flags, stain_rate, r, g, b, a) b,
|
||||
#define X(name, flags, stain_rate, pen_rate, r, g, b, a) b,
|
||||
V_ParticlesXList(X)
|
||||
#undef X
|
||||
};
|
||||
PERSIST Readonly f32 a[V_ParticleKind_COUNT] = {
|
||||
#define X(name, flags, stain_rate, r, g, b, a) a,
|
||||
#define X(name, flags, stain_rate, pen_rate, r, g, b, a) a,
|
||||
V_ParticlesXList(X)
|
||||
#undef X
|
||||
};
|
||||
result.flags = flags[kind];
|
||||
result.stain_rate = stain_rates[kind];
|
||||
result.pen_rate = pen_rates[kind];
|
||||
result.color = LinearFromSrgb(VEC4(r[kind], g[kind], b[kind], a[kind]));
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -174,60 +174,64 @@ Enum(V_OccluderKind)
|
||||
|
||||
#define V_ParticleSimBasis 0xb49f2d9e406873b9ull
|
||||
#define V_ParticleColorBasis 0x569aa8341ecc0ea3ull
|
||||
#define V_ParticleCollisionBasis 0xf60c0cff344b0c5dull
|
||||
#define V_ParticleCellBasis 0xf60c0cff344b0c5dull
|
||||
#define V_ParticleStainBasis 0x3c64e8226d98d376ull
|
||||
|
||||
Enum(V_ParticleFlag)
|
||||
{
|
||||
V_ParticleFlag_None = 0,
|
||||
V_ParticleFlag_Ground = (1 << 0),
|
||||
V_ParticleFlag_Air = (1 << 1),
|
||||
V_ParticleFlag_PruneWhenStill = (1 << 2),
|
||||
V_ParticleFlag_StainWhenPruned = (1 << 3),
|
||||
V_ParticleFlag_None = 0,
|
||||
V_ParticleFlag_Ground = (1 << 0),
|
||||
V_ParticleFlag_Air = (1 << 1),
|
||||
V_ParticleFlag_PruneWhenStill = (1 << 2),
|
||||
V_ParticleFlag_StainWhenPruned = (1 << 3),
|
||||
V_ParticleFlag_NoReflect = (1 << 4),
|
||||
};
|
||||
|
||||
// NOTE: Higher particle enum values take priority over lower ones
|
||||
#define V_ParticlesXList(X) \
|
||||
X( \
|
||||
None, \
|
||||
V_ParticleFlag_None, \
|
||||
0, \
|
||||
0, 0, 0, 0 \
|
||||
) \
|
||||
/* Ground particles */ \
|
||||
X( \
|
||||
Blood, \
|
||||
V_ParticleFlag_Ground | V_ParticleFlag_PruneWhenStill, \
|
||||
500, \
|
||||
0.5, 0.1, 0.1, 1 \
|
||||
) \
|
||||
X( \
|
||||
Debris, \
|
||||
V_ParticleFlag_Ground | V_ParticleFlag_PruneWhenStill | V_ParticleFlag_StainWhenPruned , \
|
||||
0, \
|
||||
1, 0.5, 0, 1 \
|
||||
) \
|
||||
/* Air particles */ \
|
||||
X( \
|
||||
Smoke, \
|
||||
V_ParticleFlag_Air, \
|
||||
0, \
|
||||
0.15, 0.15, 0.15, 0.5 \
|
||||
) \
|
||||
X( \
|
||||
BulletTrail, \
|
||||
V_ParticleFlag_Air, \
|
||||
0, \
|
||||
1, 0, 1, 1 \
|
||||
) \
|
||||
/* Test particles */ \
|
||||
X( \
|
||||
Test, \
|
||||
V_ParticleFlag_PruneWhenStill, \
|
||||
0, \
|
||||
1, 1, 0, 1 \
|
||||
) \
|
||||
/* -------------------------------------------------------------------------------- */
|
||||
#define V_ParticlesXList(X) \
|
||||
X( \
|
||||
/* Name */ None, \
|
||||
/* Flags */ V_ParticleFlag_None, \
|
||||
/* Stain rate, pen chance */ 0, 0, \
|
||||
/* Base color */ 0, 0, 0, 0 \
|
||||
) \
|
||||
\
|
||||
/* Ground particles */ \
|
||||
X( \
|
||||
/* Name */ Blood, \
|
||||
/* Flags */ V_ParticleFlag_None | V_ParticleFlag_NoReflect, \
|
||||
/* Stain rate, pen chance */ 500, 0.25, \
|
||||
/* Base color */ 0.5, 0.1, 0.1, 1 \
|
||||
) \
|
||||
X( \
|
||||
/* Name */ Debris, \
|
||||
/* Flags */ V_ParticleFlag_Ground | V_ParticleFlag_PruneWhenStill | V_ParticleFlag_StainWhenPruned, \
|
||||
/* Stain rate, pen chance */ 0, 0, \
|
||||
/* Base color */ 1, 0.5, 0, 1 \
|
||||
) \
|
||||
\
|
||||
/* Air particles */ \
|
||||
X( \
|
||||
/* Name */ Smoke, \
|
||||
/* Flags */ V_ParticleFlag_Air, \
|
||||
/* Stain rate, pen chance */ 0, 0, \
|
||||
/* Base color */ 0.15, 0.15, 0.15, 0.5 \
|
||||
) \
|
||||
X( \
|
||||
/* Name */ BulletTrail, \
|
||||
/* Flags */ V_ParticleFlag_Air, \
|
||||
/* Stain rate, pen chance */ 0, 0, \
|
||||
/* Base color */ 1, 0, 1, 1 \
|
||||
) \
|
||||
\
|
||||
/* Test particles */ \
|
||||
X( \
|
||||
/* Name */ Test, \
|
||||
/* Flags */ V_ParticleFlag_PruneWhenStill, \
|
||||
/* Stain rate, pen chance */ 0, 0, \
|
||||
/* Base color */ 1, 1, 0, 1 \
|
||||
) \
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Enum(V_ParticleKind)
|
||||
{
|
||||
@ -255,7 +259,7 @@ Struct(V_Particle)
|
||||
i32 kind; // If >= 0, then map to V_ParticleKind. Otherwize initialize particle using emitter at index [abs(kind) - 1]
|
||||
f32 life;
|
||||
f32 stain_accum;
|
||||
u32 collisions_count;
|
||||
u32 cells_count;
|
||||
Vec2 pos;
|
||||
Vec2 velocity;
|
||||
};
|
||||
@ -264,6 +268,7 @@ Struct(V_ParticleDesc)
|
||||
{
|
||||
V_ParticleFlag flags;
|
||||
f32 stain_rate;
|
||||
f32 pen_rate;
|
||||
Vec4 color;
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user