offscreen light falloff

This commit is contained in:
jacob 2025-07-23 18:05:25 -05:00
parent 75a5177444
commit 87b6e3b909
8 changed files with 25 additions and 21 deletions

View File

@ -151,7 +151,7 @@ SH_ASSERT_ROOT_CONST(struct sh_flood_constants, 8); /* Expected to match num32B
* ========================== */ * ========================== */
#define SH_SHADE_FLAG_NONE (0 << 0) #define SH_SHADE_FLAG_NONE (0 << 0)
#define SH_SHADE_FLAG_LIGHTING_ENABLED (1 << 0) #define SH_SHADE_FLAG_DISABLE_EFFECTS (1 << 0)
SH_STRUCT(sh_shade_constants { SH_STRUCT(sh_shade_constants {
/* ---------------------------------------------------- */ /* ---------------------------------------------------- */

View File

@ -27,7 +27,7 @@ struct cs_input {
#define SAMPLES 16 #define SAMPLES 16
#define MARCHES 16 #define MARCHES 16
#define AMBIENT float3(0, 0, 0) #define EDGE_FALLOFF 100
float rand_angle(uint2 pos, uint ray_index) { float rand_angle(uint2 pos, uint ray_index) {
Texture3D<uint> noise_tex = g_noise_textures[SH_BLUE_NOISE_TEX_ID]; Texture3D<uint> noise_tex = g_noise_textures[SH_BLUE_NOISE_TEX_ID];
@ -46,7 +46,7 @@ INLINE float3 get_light_in_dir(uint2 ray_start, float2 ray_dir)
Texture2D<uint2> flood_tex = g_textures_uint2[g_constants.emittance_flood_tex_urid]; Texture2D<uint2> flood_tex = g_textures_uint2[g_constants.emittance_flood_tex_urid];
Texture2D<float4> emittance_tex = g_textures_float4[g_constants.emittance_tex_urid]; Texture2D<float4> emittance_tex = g_textures_float4[g_constants.emittance_tex_urid];
float3 result = AMBIENT; float3 result = float3(0, 0, 0);
float2 at_float = ray_start; float2 at_float = ray_start;
uint2 at_uint = ray_start; uint2 at_uint = ray_start;
for (uint i = 0; i < MARCHES; ++i) { for (uint i = 0; i < MARCHES; ++i) {
@ -54,13 +54,17 @@ INLINE float3 get_light_in_dir(uint2 ray_start, float2 ray_dir)
float2 dist_vec = at_float - (float2)flood; float2 dist_vec = at_float - (float2)flood;
float dist = length(dist_vec); float dist = length(dist_vec);
if (dist < 1) { if (dist < 1) {
result = emittance_tex[flood].rgb; /* Scale light by distance from edge so that offscreen-lights fade in/out rather than popping in */
float dist_x = min(abs(g_constants.tex_width - at_float.x), at_float.x);
float dist_y = min(abs(g_constants.tex_height - at_float.y), at_float.y);
float dist_scale = min(min(dist_x, dist_y) / EDGE_FALLOFF, 1);
result = emittance_tex[flood].rgb * dist_scale;
break; break;
} else { } else {
at_float += ray_dir * dist; at_float += ray_dir * dist;
at_uint = round(at_float); at_uint = round(at_float);
if (at_uint.x < 0 || at_uint.x >= g_constants.tex_width || at_uint.y < 0 || at_uint.y >= g_constants.tex_height) { if (at_uint.x < 0 || at_uint.x >= g_constants.tex_width || at_uint.y < 0 || at_uint.y >= g_constants.tex_height) {
/* Ambient lighting (ray hit edge of screen) */ /* Ray hit edge of screen */
break; break;
} }
} }
@ -100,7 +104,7 @@ SH_ENTRY(ROOTSIG) void cs(struct cs_input input)
color *= albedo_tex[id]; color *= albedo_tex[id];
/* Apply lighting */ /* Apply lighting */
if (g_constants.flags & SH_SHADE_FLAG_LIGHTING_ENABLED) { if (!(g_constants.flags & SH_SHADE_FLAG_DISABLE_EFFECTS)) {
color.rgb *= get_light_at_pos(id); color.rgb *= get_light_at_pos(id);
} }

BIN
res/sprite/tim.ase (Stored with Git LFS)

Binary file not shown.

View File

@ -23,15 +23,15 @@
#define RESOURCES_EMBEDDED (!DEVELOPER) #define RESOURCES_EMBEDDED (!DEVELOPER)
#define RESOURCE_RELOADING (DEVELOPER && !RESOURCES_EMBEDDED) #define RESOURCE_RELOADING (DEVELOPER && !RESOURCES_EMBEDDED)
#define DEFAULT_CAMERA_WIDTH (10.0) #define DEFAULT_CAMERA_WIDTH (16)
#define DEFAULT_CAMERA_HEIGHT (DEFAULT_CAMERA_WIDTH / (16.0 / 9.0)) #define DEFAULT_CAMERA_HEIGHT (DEFAULT_CAMERA_WIDTH / (16.0 / 9.0))
/* Rendered image size will be (camera_width * pixels_per_unit) x (camera_height * pixels_per_unit) */ /* Rendered image size will be (camera_width * pixels_per_unit) x (camera_height * pixels_per_unit) */
#define PIXELS_PER_UNIT 64.0 #define PIXELS_PER_UNIT 40.0
/* Rendered texture size + extra room for off-screen lights */ /* Rendered texture size + extra room for off-screen light falloff */
#define RENDER_WIDTH (640 + 512) #define RENDER_WIDTH (640 + 200)
#define RENDER_HEIGHT (360 + 512) #define RENDER_HEIGHT (360 + 200)
/* How many ticks back in time should the user thread blend between? /* How many ticks back in time should the user thread blend between?
* <Delay> = <USER_INTERP_RATIO> * <Tick interval> * <Delay> = <USER_INTERP_RATIO> * <Tick interval>

View File

@ -108,7 +108,7 @@ struct gp_render_params {
struct v2i32 render_size; struct v2i32 render_size;
struct xform world_to_render_xf; struct xform world_to_render_xf;
struct xform render_to_ui_xf; struct xform render_to_ui_xf;
b32 lighting_enabled; b32 effects_disabled;
}; };
struct gp_render_sig *gp_render_sig_alloc(void); struct gp_render_sig *gp_render_sig_alloc(void);

View File

@ -3194,7 +3194,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
} }
/* Flood pass */ /* Flood pass */
if (flood_pipeline->success && params.lighting_enabled) { if (flood_pipeline->success && !params.effects_disabled) {
__profn("Flood pass"); __profn("Flood pass");
__profnc_dx12(cl->cq->prof, cl->cl, "Flood pass", RGB32_F(0.5, 0.2, 0.2)); __profnc_dx12(cl->cq->prof, cl->cl, "Flood pass", RGB32_F(0.5, 0.2, 0.2));
@ -3288,8 +3288,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, shade_pipeline->rootsig); ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, shade_pipeline->rootsig);
u32 shade_flags = SH_SHADE_FLAG_NONE; u32 shade_flags = SH_SHADE_FLAG_NONE;
if (params.lighting_enabled) { if (params.effects_disabled) {
shade_flags |= SH_SHADE_FLAG_LIGHTING_ENABLED; shade_flags |= SH_SHADE_FLAG_DISABLE_EFFECTS;
} }
/* Set constants */ /* Set constants */

View File

@ -269,7 +269,7 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos)
struct sim_ent *e = sim_ent_alloc_sync_src(parent); struct sim_ent *e = sim_ent_alloc_sync_src(parent);
f32 rot = 0; f32 rot = 0;
struct v2 size = V2(0.1, 0.1); struct v2 size = V2(0.125, 0.125);
struct xform xf = XFORM_TRS(.t = pos, .r = rot, .s = size); struct xform xf = XFORM_TRS(.t = pos, .r = rot, .s = size);
sim_ent_set_xform(e, xf); sim_ent_set_xform(e, xf);

View File

@ -986,12 +986,12 @@ INTERNAL void user_update(struct sys_window *window)
* Update world to render xform from world to ui xform * Update world to render xform from world to ui xform
* ========================== */ * ========================== */
b32 lighting_enabled = 1; b32 effects_disabled = 0;
G.render_size = V2(RENDER_WIDTH, RENDER_HEIGHT); G.render_size = V2(RENDER_WIDTH, RENDER_HEIGHT);
if (G.debug_camera) { if (G.debug_camera) {
G.render_size = G.ui_size; G.render_size = G.ui_size;
lighting_enabled = 0; effects_disabled = 1;
G.world_to_render_xf = G.world_to_ui_xf; G.world_to_render_xf = G.world_to_ui_xf;
} else { } else {
struct xform ui_to_world_xf = xform_invert(G.world_to_ui_xf); struct xform ui_to_world_xf = xform_invert(G.world_to_ui_xf);
@ -2078,7 +2078,7 @@ INTERNAL void user_update(struct sys_window *window)
params.render_size = world_resolution; params.render_size = world_resolution;
params.world_to_render_xf = G.world_to_render_xf; params.world_to_render_xf = G.world_to_render_xf;
params.render_to_ui_xf = G.render_to_ui_xf; params.render_to_ui_xf = G.render_to_ui_xf;
params.lighting_enabled = lighting_enabled; params.effects_disabled = effects_disabled;
render_texture = gp_run_render(G.render_sig, params); render_texture = gp_run_render(G.render_sig, params);
} }