From 988d39d241d3a931ee2e1414580d5befe2fae1c7 Mon Sep 17 00:00:00 2001 From: jacob Date: Sat, 4 Apr 2026 21:42:43 -0500 Subject: [PATCH] vis quad drop shadows --- src/pp/pp_vis/pp_vis_core.c | 37 ++++++++++++++++++++++--------- src/pp/pp_vis/pp_vis_gpu.g | 39 +++++++++++++++++++++------------ src/pp/pp_vis/pp_vis_shared.cgh | 12 +++++----- 3 files changed, 59 insertions(+), 29 deletions(-) diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index b688aeb7..b06b11a6 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -7975,6 +7975,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- GPU upload pass + V_GpuFlag gpu_flags = V_GpuFlag_None; G_ProfZoneDF(cl, "Setup") { // Backdrop @@ -8143,7 +8144,6 @@ void V_TickForever(WaveLaneCtx *lane) ); // Init registers - V_GpuFlag gpu_flags = V_GpuFlag_None; G_SetRegister(cl, V_GpuReg_Flags, gpu_flags); G_SetRegister(cl, V_GpuReg_Frame, gpu_frame); G_SetRegister(cl, V_GpuReg_NoiseTex, G_BasicNoise3D()); @@ -8212,16 +8212,33 @@ void V_TickForever(WaveLaneCtx *lane) G_ProfZoneDF(cl, "Quads & emitters") { - // Draw quads G_ClearRenderTarget(cl, frame->albedo, VEC4(0, 0, 0, 0), 0); - G_Draw( - cl, - V_QuadVS, V_QuadPS, - frame->quads_count, G_QuadIndices(), - 1, &G_RT(frame->albedo, G_BlendMode_CompositeStraightAlpha), - screen_viewport, screen_scissor, - G_DrawMode_TriangleList - ); + // Draw quad drop shadows + { + G_SetRegister(cl, V_GpuReg_Flags, SetBit(gpu_flags, V_GpuFlag_DrawShadows, 1)); + { + G_Draw( + cl, + V_QuadVS, V_QuadPS, + frame->quads_count, G_QuadIndices(), + 1, &G_RT(frame->albedo, G_BlendMode_CompositeStraightAlpha), + screen_viewport, screen_scissor, + G_DrawMode_TriangleList + ); + } + G_SetRegister(cl, V_GpuReg_Flags, SetBit(gpu_flags, V_GpuFlag_DrawShadows, 0)); + } + // Draw quads + { + G_Draw( + cl, + V_QuadVS, V_QuadPS, + frame->quads_count, G_QuadIndices(), + 1, &G_RT(frame->albedo, G_BlendMode_CompositeStraightAlpha), + screen_viewport, screen_scissor, + G_DrawMode_TriangleList + ); + } // Emit particles G_Compute(cl, V_EmitParticlesCS, frame->emitters_count); diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index 608656ac..1d78184d 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -375,8 +375,12 @@ VertexShader(V_QuadVS, V_QuadPSInput) Vec2 rect_uv = RectUvFromIdx(SV_VertexID); Vec2 world_pos = mul(quad.quad_uv_to_world_af, Vec3(rect_uv, 1)); + if (V_GpuReg_Flags & V_GpuFlag_DrawShadows) + { + // Offset quad for shadow + world_pos += Vec2(V_QuadShadowOffsetMeters, V_QuadShadowOffsetMeters); + } Vec2 screen_pos = mul(frame.af.world_to_screen, Vec3(world_pos, 1)); - Vec2 samp_uv = lerp(quad.tex_slice_uv.p0, quad.tex_slice_uv.p1, rect_uv); V_QuadPSInput result; @@ -404,24 +408,31 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input) b32 is_in_world = IsInside(cell_pos, P_WorldCellsDims); - Vec4 albedo = tex.Sample(sampler, input.samp_uv); + Vec4 result = tex.Sample(sampler, input.samp_uv); - if (quad.mask_color_lin.a != 0 && all(albedo == Color_White)) + if (quad.mask_color_lin.a != 0 && all(result == Color_White)) { - albedo = quad.mask_color_lin; + result = quad.mask_color_lin; } - if (is_in_world) + b32 is_drawing_shadow = !!(V_GpuReg_Flags & V_GpuFlag_DrawShadows); + + if (is_in_world && !is_drawing_shadow) { // TODO: Don't write occluders using screen space result. Do separate draw pass instead. - if (quad.occluder_id > 0 && albedo.a > 0) + if (quad.occluder_id > 0 && result.a > 0) { InterlockedMax(occluders[cell_pos], quad.occluder_id); } } + if (is_drawing_shadow) + { + result = V_QuadShadowColor * (result.a > 0); + } + V_QuadPSOutput output; - output.sv_target0 = albedo; + output.sv_target0 = result; return output; } @@ -1050,13 +1061,13 @@ ComputeShader(V_CompositeCS) ////////////////////////////// - //- Shadow + //- Tile shadow - Vec4 shadow_color = 0; - if (!tile_is_wall && !tile_is_empty) + Vec4 tile_shadow_color = 0; + if (!tile_is_wall) { // TODO: Move this to a frame var - f32 shadow_size = 0.05; + f32 shadow_size = V_TileShadowOffsetMeters; Vec2 tile_shadow_pos = mul(frame.af.world_to_tile, Vec3(world_pos.xy - Vec2(shadow_size, shadow_size), 1)); b32 is_in_shadow = 0; @@ -1064,7 +1075,7 @@ ComputeShader(V_CompositeCS) is_in_shadow = shadow_tile == P_TileKind_Wall; if (is_in_shadow) { - shadow_color = Vec4(0, 0, 0, 0.75); + tile_shadow_color = V_TileShadowColor; } } @@ -1081,8 +1092,8 @@ ComputeShader(V_CompositeCS) world_color = BlendPremul(ground_particle_color, world_color); // Blend ground particle // TODO: Blend shadows over tex? - world_color = BlendPremul(shadow_color, world_color); // Blend shadow - // if (shadow_color.a != 0) + world_color = BlendPremul(tile_shadow_color, world_color); // Blend shadow + // if (tile_shadow_color.a != 0) // { // world_color.rgb *= 0.5; // Blend shadow // } diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index cf034c6b..36b23612 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -1,14 +1,16 @@ -// #define V_ParticlesCap Kibi(128) -// #define V_ParticlesCap Mebi(1) -#define V_ParticlesCap Mebi(2) -// #define V_ParticlesCap Mebi(16) +#define V_ParticlesCap Mebi(2) +#define V_TileShadowOffsetMeters 0.05 +#define V_QuadShadowOffsetMeters 0.05 +#define V_TileShadowColor VEC4(0, 0, 0, 0.5) +#define V_QuadShadowColor VEC4(0, 0, 0, 0.25) //////////////////////////////////////////////////////////// //~ Shader register types Enum(V_GpuFlag) { - V_GpuFlag_None = 0, + V_GpuFlag_None = 0, + V_GpuFlag_DrawShadows = (1 << 0), }; G_DeclRegister(V_GpuFlag, V_GpuReg_Flags, 0);