stain dryness

This commit is contained in:
jacob 2026-01-08 09:31:38 -06:00
parent 0f7b6d2ffc
commit 1c042f1c11
6 changed files with 76 additions and 9 deletions

View File

@ -3156,7 +3156,6 @@ void G_D12_CollectionWorkerEntryPoint(WaveLaneCtx *lane)
FmtArg *dst = &args.args[arg_idx];
switch (gpu_kind)
{
// Translate unsigned integer args
case G_FmtArgKind_Uint:
{
@ -3235,6 +3234,7 @@ void G_D12_CollectionWorkerEntryPoint(WaveLaneCtx *lane)
at += 16;
} break;
}
dst->p = 6;
}
}
}

View File

@ -1615,7 +1615,7 @@ void S_TickForever(WaveLaneCtx *lane)
// i64 tick_bullets_count = sim_dt * firer->fire_rate;
f32 fire_rate = 20;
f32 fire_rate = 50;
f32 bullets_per_fire = 1;
// f32 spread = Tau * 0.05;
f32 spread = Tau * 0.01;

View File

@ -354,11 +354,13 @@ void V_TickForever(WaveLaneCtx *lane)
G_ResourceHandle gpu_particles = Zi;
G_ResourceHandle gpu_cells = Zi;
G_ResourceHandle gpu_stains = Zi;
G_ResourceHandle gpu_drynesses = Zi;
G_RWStructuredBufferRef gpu_state_ref = Zi;
G_Texture2DRef gpu_tiles_ref = Zi;
G_RWStructuredBufferRef gpu_particles_ref = Zi;
G_RWTexture2DRef gpu_cells_ref = Zi;
G_RWTexture2DRef gpu_stains_ref = Zi;
G_RWTexture2DRef gpu_drynesses_ref = Zi;
{
G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct);
{
@ -421,6 +423,21 @@ void V_TickForever(WaveLaneCtx *lane)
);
gpu_stains_ref = G_PushRWTexture2DRef(gpu_perm, gpu_stains);
}
// Init drynesses texture
{
gpu_drynesses = G_PushTexture2D(
gpu_perm, cl,
// G_Format_R8_Uint,
// G_Format_R11G11B10_Float,
// G_Format_R10G10B10A2_Unorm,
// G_Format_R16_Float,
G_Format_R32_Float,
cells_dims,
G_Layout_DirectQueue_ShaderReadWrite,
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite
);
gpu_drynesses_ref = G_PushRWTexture2DRef(gpu_perm, gpu_drynesses);
}
}
G_CommitCommandList(cl);
}
@ -2988,6 +3005,8 @@ void V_TickForever(WaveLaneCtx *lane)
emitter.end = emitter.start;
emitter.angle = AngleFromVec2(dir);
// emitter.flags |= V_ParticleFlag_StainTrail;
emitter.count = 128;
// emitter.count = 100;
emitter.speed = 10;
@ -3175,6 +3194,7 @@ void V_TickForever(WaveLaneCtx *lane)
params.should_clear_stains = should_clear_particles;
params.cells = gpu_cells_ref;
params.stains = gpu_stains_ref;
params.drynesses = gpu_drynesses_ref;
}
G_ResourceHandle gpu_params = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromStruct(&params));
G_StructuredBufferRef gpu_params_ref = G_PushStructuredBufferRef(frame->gpu_arena, gpu_params, V_GpuParams);

View File

@ -1,3 +1,22 @@
////////////////////////////////////////////////////////////
//~ Helpers
f32 V_RandFromPos(Vec3 pos)
{
Texture3D<u32> noise3d = G_Dereference<u32>(V_ShaderConst_NoiseTex);
Vec3I32 dims = countof(noise3d);
u32 noise = noise3d[floor(pos) % dims];
f32 rand = (f32)noise / 0xFFFF;
return rand;
}
Vec4 V_DryColor(Vec4 color, f32 dryness)
{
Vec4 result = color;
result.rgb *= 1.0 - (dryness * 0.75);
return result;
}
////////////////////////////////////////////////////////////
//~ Utility shaders
@ -7,13 +26,26 @@ ComputeShader2D(V_ClearCellsCS, 8, 8)
V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
RWTexture2D<Vec4> cells = G_Dereference<Vec4>(params.cells);
RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
RWTexture2D<f32> drynesses = G_Dereference<f32>(params.drynesses);
Vec2 cells_idx = SV_DispatchThreadID;
if (cells_idx.x < countof(cells).x && cells_idx.y < countof(cells).y)
{
// Clear cell
cells[cells_idx] = 0;
// Clear stain
if (params.should_clear_stains)
{
stains[cells_idx] = 0;
drynesses[cells_idx] = 0;
}
// Increase dryness
f32 dry_rate = params.dt * 0.1;
{
f32 old_dryness = drynesses[cells_idx];
f32 new_dryness = lerp(old_dryness, 1, dry_rate);
drynesses[cells_idx] = new_dryness;
}
}
}
@ -159,10 +191,16 @@ ComputeShader2D(V_BackdropCS, 8, 8)
{
RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
RWTexture2D<Vec4> cells = G_Dereference<Vec4>(params.cells);
RWTexture2D<f32> drynesses = G_Dereference<f32>(params.drynesses);
Vec2 cell_pos = floor(mul(params.xf.world_to_cell, Vec3(world_pos, 1)));
Vec4 stain = stains.Load(cell_pos);
Vec4 cell = cells.Load(cell_pos);
f32 dryness = drynesses[cell_pos];
stain = V_DryColor(stain, dryness);
// cell.rgb *= cell.a;
// stain.rgb *= stain.a;
@ -317,6 +355,7 @@ ComputeShader(V_SimParticlesCS, 64)
RWStructuredBuffer<V_Particle> particles = G_Dereference<V_Particle>(params.particles);
RWTexture2D<Vec4> cells = G_Dereference<Vec4>(params.cells);
RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
RWTexture2D<f32> drynesses = G_Dereference<f32>(params.drynesses);
u32 particle_idx = SV_DispatchThreadID;
if (particle_idx < V_MaxParticles)
@ -403,17 +442,18 @@ ComputeShader(V_SimParticlesCS, 64)
cells[cell_pos] = color;
if (should_stain)
{
// stains[cell_pos] = color;
f32 old_dryness = drynesses[cell_pos];
Vec4 old_stain = stains[cell_pos];
// old_stain = V_DryColor(old_stain, drynesses[cell_pos] * 0.5);
// old_stain = V_DryColor(old_stain, old_dryness);
Vec4 new_stain = 0;
new_stain.rgb = (old_stain.rgb * old_stain.a) + (color.rgb * (1.0 - old_stain.a));
new_stain.a = color.a = (old_stain.a * 1) + (color.a * (1.0 - old_stain.a));
new_stain.rgb = (color.rgb * color.a) + (old_stain.rgb * (1.0 - color.a));
new_stain.a = color.a + (old_stain.a * (1.0 - color.a));
// new_stain = V_DryColor(new_stain, old_dryness * 0.1);
// new_stain = V_DryColor(new_stain, old_dryness * 0.5);
stains[cell_pos] = new_stain;
drynesses[cell_pos] = 0;
}
}
else

View File

@ -40,6 +40,12 @@ Struct(V_OverlayPSOutput)
Semantic(Vec4, sv_target0);
};
////////////////////////////////////////////////////////////
//~ Helpers
f32 V_RandFromPos(Vec3 pos);
Vec4 V_DryColor(Vec4 color, f32 dryness);
////////////////////////////////////////////////////////////
//~ Shaders

View File

@ -83,6 +83,7 @@ Struct(V_GpuParams)
b32 should_clear_stains;
G_RWTexture2DRef cells;
G_RWTexture2DRef stains;
G_RWTexture2DRef drynesses;
};
////////////////////////////////////////////////////////////