use non-atlas mirror sampling for backdrop

This commit is contained in:
jacob 2026-02-24 03:05:31 -06:00
parent cbf0961f4c
commit c3c9be43e3
3 changed files with 11 additions and 22 deletions

View File

@ -4763,9 +4763,8 @@ void V_TickForever(WaveLaneCtx *lane)
frame->backdrop_parallax = TweakFloat("Backdrop parallax", 4, 0, 20); frame->backdrop_parallax = TweakFloat("Backdrop parallax", 4, 0, 20);
{ {
SPR_SheetKey sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("backdrop.ase"))); SPR_SheetKey sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("backdrop.ase")));
SPR_Sprite sprite = SPR_SpriteFromSheet(sheet, SPR_NilSpanKey, 0); SPR_Sprite sprite = SPR_SpriteFromSheetEx(sheet, SPR_NilSpanKey, 0, SPR_SheetFlag_NoAtlas);
frame->backdrop_src = sprite.tex; frame->backdrop_src = sprite.tex;
frame->backdrop_src_slice_uv = DivRng2Vec2(sprite.tex_rect, sprite.tex_dims);
} }
// Tiles // Tiles
@ -4846,7 +4845,7 @@ void V_TickForever(WaveLaneCtx *lane)
G_ResourceHandle backdrop_target = G_PushTexture2D( G_ResourceHandle backdrop_target = G_PushTexture2D(
gpu_frame_arena, frame->cl, gpu_frame_arena, frame->cl,
G_Format_R16G16B16A16_Float, G_Format_R16G16B16A16_Float,
G_DimsFromMip2D(G_Count2D(screen_target), 0), G_DimsFromMip2D(G_Count2D(screen_target), 1),
G_Layout_DirectQueue_General, G_Layout_DirectQueue_General,
.flags = G_ResourceFlag_AllowShaderReadWrite, .flags = G_ResourceFlag_AllowShaderReadWrite,
.name = StringF(frame->arena, "Backdrop target [%F]", FmtSint(frame->tick)), .name = StringF(frame->arena, "Backdrop target [%F]", FmtSint(frame->tick)),

View File

@ -182,7 +182,7 @@ ImplComputeShader2D(V_BackdropDownCS)
V_SharedFrame frame = G_Dereference<V_SharedFrame>(V_GpuConst_Frame)[0]; V_SharedFrame frame = G_Dereference<V_SharedFrame>(V_GpuConst_Frame)[0];
SamplerState sampler = G_Dereference(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp]); SamplerState sampler = G_Dereference(frame.basic_samplers[G_BasicSamplerKind_BilinearMirror]);
Texture2D<Vec4> bd_up; Texture2D<Vec4> bd_up;
if (is_first_pass) if (is_first_pass)
@ -203,21 +203,18 @@ ImplComputeShader2D(V_BackdropDownCS)
Vec2 off_uv = 0.5 / down_dims; Vec2 off_uv = 0.5 / down_dims;
Vec2 screen_pos = bd_uv * frame.screen_dims; Vec2 screen_pos = bd_uv * frame.screen_dims;
Vec2 world_pos = mul(frame.af.screen_to_world_raw, Vec3(screen_pos, 1)); Vec2 world_pos = mul(frame.af.screen_to_world, Vec3(screen_pos, 1));
Rng2 world_bounds = { Vec2(-P_WorldPitch, -P_WorldPitch) * 0.5, Vec2(P_WorldPitch, P_WorldPitch) * 0.5 }; Rng2 world_bounds = { Vec2(-P_WorldPitch, -P_WorldPitch) * 0.5, Vec2(P_WorldPitch, P_WorldPitch) * 0.5 };
Vec4 result = 0; Vec4 result = 0;
if (is_first_pass) if (is_first_pass)
{ {
// Parallax sample
f32 parallax = frame.backdrop_parallax; f32 parallax = frame.backdrop_parallax;
Vec2 cam_center = frame.camera_pos; Vec2 cam_center = frame.camera_pos;
Vec2 backdrop_pos = lerp(cam_center, world_pos, parallax); Vec2 backdrop_pos = lerp(cam_center, world_pos, parallax);
Vec2 samp_uv = (backdrop_pos - world_bounds.p0) / (world_bounds.p1 - world_bounds.p0);
Vec2 samp_t = frac(abs(backdrop_pos - world_bounds.p0) / (world_bounds.p1 - world_bounds.p0)); result = bd_up.SampleLevel(sampler, samp_uv, 0);
Vec2 samp_uv = lerp(frame.backdrop_src_slice_uv.p0, frame.backdrop_src_slice_uv.p1, samp_t);
result = bd_up[samp_uv * countof(bd_up)];
} }
else else
{ {
@ -249,12 +246,11 @@ ImplComputeShader2D(V_BackdropDownCS)
ImplComputeShader2D(V_BackdropUpCS) ImplComputeShader2D(V_BackdropUpCS)
{ {
i32 mip_idx = V_GpuConst_MipIdx; i32 mip_idx = V_GpuConst_MipIdx;
i32 is_last_pass = mip_idx == 0;
V_SharedFrame frame = G_Dereference<V_SharedFrame>(V_GpuConst_Frame)[0]; V_SharedFrame frame = G_Dereference<V_SharedFrame>(V_GpuConst_Frame)[0];
Texture2D<Vec4> bd_down = G_Dereference<Vec4>(frame.backdrop_mips_ro[mip_idx + 1]); Texture2D<Vec4> bd_down = G_Dereference<Vec4>(frame.backdrop_mips_ro[mip_idx + 1]);
RWTexture2D<Vec4> bd_up = G_Dereference<Vec4>(frame.backdrop_mips_rw[mip_idx]); RWTexture2D<Vec4> bd_up = G_Dereference<Vec4>(frame.backdrop_mips_rw[mip_idx]);
SamplerState sampler = G_Dereference(frame.basic_samplers[G_BasicSamplerKind_BilinearClamp]); SamplerState sampler = G_Dereference(frame.basic_samplers[G_BasicSamplerKind_BilinearMirror]);
Vec2 down_dims = countof(bd_down); Vec2 down_dims = countof(bd_down);
Vec2 up_dims = countof(bd_up); Vec2 up_dims = countof(bd_up);
@ -266,11 +262,6 @@ ImplComputeShader2D(V_BackdropUpCS)
// 13-tap sample // 13-tap sample
Vec4 result = 0; Vec4 result = 0;
if (is_last_pass)
{
result = bd_down.SampleLevel(sampler, bd_uv, 0);
}
else
{ {
// Center // Center
result += bd_down.SampleLevel(sampler, bd_uv, 0) * 9.0f / 41.0f; result += bd_down.SampleLevel(sampler, bd_uv, 0) * 9.0f / 41.0f;
@ -1001,7 +992,7 @@ ImplComputeShader2D(V_CompositeCS)
//- Grid //- Grid
Vec4 grid_color = 0; Vec4 grid_color = 0;
if (is_in_world && frame.is_editing) if (is_in_world)
{ {
b32 debug_draw = !!frame.show_console; b32 debug_draw = !!frame.show_console;
@ -1042,6 +1033,7 @@ ImplComputeShader2D(V_CompositeCS)
} }
// World bounds // World bounds
if (frame.show_console || frame.is_editing)
{ {
const Vec4 bounds_color = LinearFromSrgb(Vec4(0.75, 0.75, 0, 1)); const Vec4 bounds_color = LinearFromSrgb(Vec4(0.75, 0.75, 0, 1));
f32 bounds_dist = 100000; f32 bounds_dist = 100000;

View File

@ -348,10 +348,8 @@ Struct(V_SharedFrame)
V_TileDesc tile_descs[P_TileKind_COUNT]; V_TileDesc tile_descs[P_TileKind_COUNT];
G_Texture2DRef tiles; G_Texture2DRef tiles;
G_Texture2DRef backdrop_src;
Rng2 backdrop_src_slice_uv;
f32 backdrop_parallax; f32 backdrop_parallax;
G_Texture2DRef backdrop_src;
G_Texture2DRef backdrop_mips_ro[G_MaxMips]; G_Texture2DRef backdrop_mips_ro[G_MaxMips];
G_RWTexture2DRef backdrop_mips_rw[G_MaxMips]; G_RWTexture2DRef backdrop_mips_rw[G_MaxMips];