diff --git a/res/sh/sh_common.h b/res/sh/sh_common.h index 9947e05a..c2b283f2 100644 --- a/res/sh/sh_common.h +++ b/res/sh/sh_common.h @@ -150,10 +150,18 @@ SH_ASSERT_ROOT_CONST(struct sh_flood_constants, 8); /* Expected to match num32B * Shade shader structures * ========================== */ +#define SH_SHADE_FLAG_NONE (0 << 0) +#define SH_SHADE_FLAG_LIGHTING_ENABLED (1 << 0) + SH_STRUCT(sh_shade_constants { /* ---------------------------------------------------- */ SH_DECL(uint4, frame_seed); /* 04 consts */ /* ---------------------------------------------------- */ + SH_DECL(uint, flags); /* 01 consts */ + SH_DECL(uint, _pad0); /* 01 consts (padding) */ + SH_DECL(uint, tex_width); /* 01 consts */ + SH_DECL(uint, tex_height); /* 01 consts */ + /* ---------------------------------------------------- */ SH_DECL(float2, camera_offset); /* 02 consts */ SH_DECL(uint, frame_index); /* 01 consts */ SH_DECL(uint, albedo_tex_urid); /* 01 consts */ @@ -163,10 +171,6 @@ SH_STRUCT(sh_shade_constants { SH_DECL(uint, read_tex_urid); /* 01 consts */ SH_DECL(uint, target_tex_urid); /* 01 consts */ /* ---------------------------------------------------- */ - SH_DECL(uint, tex_width); /* 01 consts */ - SH_DECL(uint, tex_height); /* 01 consts */ - SH_DECL(uint2, _pad0); /* 02 consts (padding) */ - /* ---------------------------------------------------- */ }); SH_ASSERT_ROOT_CONST(struct sh_shade_constants, 16); /* Expected to match num32BitConstants in shader's root signature */ diff --git a/res/sh/shade.hlsl b/res/sh/shade.hlsl index e7d1f1cf..b664cc4f 100644 --- a/res/sh/shade.hlsl +++ b/res/sh/shade.hlsl @@ -100,7 +100,9 @@ SH_ENTRY(ROOTSIG) void cs(struct cs_input input) color *= albedo_tex[id]; /* Apply lighting */ - color.rgb *= get_light_at_pos(id); + if (g_constants.flags & SH_SHADE_FLAG_LIGHTING_ENABLED) { + color.rgb *= get_light_at_pos(id); + } /* Apply temporal accumulation */ float hysterisis = 0; diff --git a/src/config.h b/src/config.h index 30aebbf4..e68e046f 100644 --- a/src/config.h +++ b/src/config.h @@ -23,12 +23,15 @@ #define RESOURCES_EMBEDDED (!DEVELOPER) #define RESOURCE_RELOADING (DEVELOPER && !RESOURCES_EMBEDDED) -#define DEFAULT_CAMERA_WIDTH (15.0) +#define DEFAULT_CAMERA_WIDTH (10.0) #define DEFAULT_CAMERA_HEIGHT (DEFAULT_CAMERA_WIDTH / (16.0 / 9.0)) -#define IMAGE_PIXELS_PER_UNIT 128.0 +/* Rendered image size will be (camera_width * pixels_per_unit) x (camera_height * pixels_per_unit) */ +#define PIXELS_PER_UNIT 64.0 -#define RENDER_MARGIN (512) +/* Rendered texture size + extra room for off-screen lights */ +#define RENDER_WIDTH (640 + 512) +#define RENDER_HEIGHT (360 + 512) /* How many ticks back in time should the user thread blend between? * = * diff --git a/src/gp.h b/src/gp.h index df2703be..15f64956 100644 --- a/src/gp.h +++ b/src/gp.h @@ -108,6 +108,7 @@ struct gp_render_params { struct v2i32 render_size; struct xform world_to_render_xf; struct xform render_to_ui_xf; + b32 lighting_enabled; }; struct gp_render_sig *gp_render_sig_alloc(void); diff --git a/src/gp_dx12.c b/src/gp_dx12.c index 547f1145..c1d5595e 100644 --- a/src/gp_dx12.c +++ b/src/gp_dx12.c @@ -2959,29 +2959,35 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re struct rect ui_viewport = RECT_FROM_V2(V2(0, 0), V2(ui_size.x, ui_size.y)); struct rect render_viewport = RECT_FROM_V2(V2(0, 0), V2(render_size.x, render_size.y)); - /* Release buffers if size changed */ - if (sig->ui_target && !v2i32_eq(ui_size, sig->ui_target->texture_size)) { + + /* Allocate render buffers */ + if (sig->shade_target && !v2i32_eq(render_size, sig->shade_target->texture_size)) { __profn("Release sig resources"); - fenced_release(sig->albedo, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->emittance, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->emittance_flood_read, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->emittance_flood_target, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->shade_read, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->shade_target, FENCED_RELEASE_KIND_RESOURCE); - fenced_release(sig->ui_target, FENCED_RELEASE_KIND_RESOURCE); - sig->ui_target = 0; + fenced_release(sig->albedo, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(sig->emittance, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(sig->emittance_flood_read, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(sig->emittance_flood_target, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(sig->shade_read, FENCED_RELEASE_KIND_RESOURCE); + fenced_release(sig->shade_target, FENCED_RELEASE_KIND_RESOURCE); + sig->shade_target = 0; + } + if (!sig->shade_target) { + __profn("Allocate sig resources"); + sig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); + sig->emittance = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); + sig->emittance_flood_read = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + sig->emittance_flood_target = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + sig->shade_read = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + sig->shade_target = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); } - /* Allocate buffers */ + /* Allocate ui buffers */ + if (sig->ui_target && !v2i32_eq(ui_size, sig->ui_target->texture_size)) { + fenced_release(sig->ui_target, FENCED_RELEASE_KIND_RESOURCE); + sig->ui_target = 0; + } if (!sig->ui_target) { - __profn("Allocate sig resources"); - sig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); - sig->emittance = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); - sig->emittance_flood_read = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - sig->emittance_flood_target = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - sig->shade_read = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - sig->shade_target = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - sig->ui_target = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, ui_size, D3D12_RESOURCE_STATE_RENDER_TARGET); + sig->ui_target = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, ui_size, D3D12_RESOURCE_STATE_RENDER_TARGET); } struct sprite_scope *sprite_scope = sprite_scope_begin(); @@ -3188,7 +3194,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re } /* Flood pass */ - if (flood_pipeline->success) { + if (flood_pipeline->success && params.lighting_enabled) { __profn("Flood pass"); __profnc_dx12(cl->cq->prof, cl->cl, "Flood pass", RGB32_F(0.5, 0.2, 0.2)); @@ -3281,8 +3287,16 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re ID3D12GraphicsCommandList_SetPipelineState(cl->cl, shade_pipeline->pso); ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, shade_pipeline->rootsig); + u32 shade_flags = SH_SHADE_FLAG_NONE; + if (params.lighting_enabled) { + shade_flags |= SH_SHADE_FLAG_LIGHTING_ENABLED; + } + /* Set constants */ struct sh_shade_constants constants = ZI; + constants.flags = sh_uint_from_u32(shade_flags); + constants.tex_width = sh_uint_from_u32(render_size.x); + constants.tex_height = sh_uint_from_u32(render_size.y); constants.frame_seed = sh_uint4_from_u32((u32)rand_u64_from_state(&sig->rand), (u32)rand_u64_from_state(&sig->rand), (u32)rand_u64_from_state(&sig->rand), @@ -3294,8 +3308,6 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re constants.emittance_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_read->srv_descriptor->index); constants.read_tex_urid = sh_uint_from_u32(sig->shade_read->uav_descriptor->index); constants.target_tex_urid = sh_uint_from_u32(sig->shade_target->uav_descriptor->index); - constants.tex_width = sh_uint_from_u32(render_size.x); - constants.tex_height = sh_uint_from_u32(render_size.y); /* Set parameters */ command_list_set_compute_root_constant(cl, &constants, sizeof(constants)); diff --git a/src/sim_step.c b/src/sim_step.c index bb9171a9..d6893432 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -402,7 +402,7 @@ INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos) { struct sprite_scope *scope = sprite_scope_begin(); struct sprite_sheet *sheet = sprite_sheet_from_tag_await(scope, e->sprite); - e->sprite_local_xform = XFORM_TRS(.s = v2_div(sheet->frame_size, IMAGE_PIXELS_PER_UNIT)); + e->sprite_local_xform = XFORM_TRS(.s = v2_div(sheet->frame_size, PIXELS_PER_UNIT)); sprite_scope_end(scope); } @@ -1224,7 +1224,7 @@ void sim_step(struct sim_step_ctx *ctx) /* Update sprite local xform */ { struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("pivot"), ent->animation_frame); - struct v2 sprite_size = v2_div(sheet->frame_size, (f32)IMAGE_PIXELS_PER_UNIT); + struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT); struct v2 dir = v2_mul_v2(sprite_size, slice.dir); f32 rot = v2_angle(dir) + PI / 2; diff --git a/src/sprite.c b/src/sprite.c index 0822f7e7..902d2284 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -228,13 +228,13 @@ struct sprite_startup_receipt sprite_startup(void) /* Init loading sheet */ G.loading_sheet = arena_push(G.perm_arena, struct sprite_sheet); - G.loading_sheet->image_size = V2(IMAGE_PIXELS_PER_UNIT, IMAGE_PIXELS_PER_UNIT); - G.loading_sheet->frame_size = V2(IMAGE_PIXELS_PER_UNIT, IMAGE_PIXELS_PER_UNIT); + G.loading_sheet->image_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT); + G.loading_sheet->frame_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT); /* Init nil sheet */ G.nil_sheet = arena_push(G.perm_arena, struct sprite_sheet); - G.nil_sheet->image_size = V2(IMAGE_PIXELS_PER_UNIT, IMAGE_PIXELS_PER_UNIT); - G.nil_sheet->frame_size = V2(IMAGE_PIXELS_PER_UNIT, IMAGE_PIXELS_PER_UNIT); + G.nil_sheet->image_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT); + G.nil_sheet->frame_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT); G.nil_sheet->loaded = 1; } arena_set_readonly(G.perm_arena); diff --git a/src/user.c b/src/user.c index ea519a53..c0ff2d6c 100644 --- a/src/user.c +++ b/src/user.c @@ -134,7 +134,6 @@ GLOBAL struct { struct xform render_to_ui_xf; struct v2 render_size; - struct v2 render_vis_size; struct xform world_to_render_xf; struct xform world_to_ui_xf; @@ -987,25 +986,21 @@ INTERNAL void user_update(struct sys_window *window) * Update world to render xform from world to ui xform * ========================== */ - G.render_vis_size = V2(640, 360); - G.render_size = G.render_vis_size; - G.render_size.x += RENDER_MARGIN; - G.render_size.y += RENDER_MARGIN; + b32 lighting_enabled = 1; + G.render_size = V2(RENDER_WIDTH, RENDER_HEIGHT); - { + if (G.debug_camera) { + G.render_size = G.ui_size; + lighting_enabled = 0; + G.world_to_render_xf = G.world_to_ui_xf; + } else { struct xform ui_to_world_xf = xform_invert(G.world_to_ui_xf); struct v2 world_center = xform_mul_v2(ui_to_world_xf, v2_mul(G.ui_size, 0.5)); - struct v2 vis_scale = v2_div_v2(G.render_vis_size, G.render_size); - vis_scale.x = min_f32(vis_scale.x, vis_scale.y); - vis_scale.y = vis_scale.x; - - struct v2 scale = V2(IMAGE_PIXELS_PER_UNIT, IMAGE_PIXELS_PER_UNIT); - scale = v2_mul_v2(scale, vis_scale); + struct v2 scale = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT); struct xform xf = XFORM_IDENT; - /*xf = xform_translated(xf, v2_mul(world_center, -1));*/ xf = xform_translated(xf, v2_mul(G.render_size, 0.5)); xf = xform_scaled(xf, scale); @@ -2083,6 +2078,7 @@ INTERNAL void user_update(struct sys_window *window) params.render_size = world_resolution; params.world_to_render_xf = G.world_to_render_xf; params.render_to_ui_xf = G.render_to_ui_xf; + params.lighting_enabled = lighting_enabled; render_texture = gp_run_render(G.render_sig, params); }