From aa395bfd5a6cbcc2f2a8aa05939fbe7d2db68063 Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 18 Jul 2025 12:04:06 -0500 Subject: [PATCH] tone mapping --- res/sh/blit.hlsl | 6 ++--- res/sh/common.hlsl | 17 +++++++----- res/sh/flood.hlsl | 2 +- res/sh/material.hlsl | 2 +- res/sh/sh_common.h | 34 ++++++++++++++---------- res/sh/shade.hlsl | 62 +++++++++++++++++++++++++++++++++----------- res/sh/shape.hlsl | 6 ++--- res/sh/ui.hlsl | 6 ++--- src/draw.c | 3 ++- src/draw.h | 3 ++- src/gp.h | 4 ++- src/gp_dx12.c | 23 +++++++++------- src/sim_ent.h | 1 + src/sim_step.c | 13 ++++++++-- src/user.c | 8 +++--- 15 files changed, 127 insertions(+), 63 deletions(-) diff --git a/res/sh/blit.hlsl b/res/sh/blit.hlsl index 4764259c..5750c535 100644 --- a/res/sh/blit.hlsl +++ b/res/sh/blit.hlsl @@ -5,7 +5,7 @@ * ========================== */ #define ROOTSIG \ - "RootConstants(num32BitConstants = 18, b0), " \ + "RootConstants(num32BitConstants = 17, b0), " \ "DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ \ "StaticSampler(s0, " \ @@ -65,7 +65,7 @@ struct ps_output { SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) { struct ps_output output; - const float gamma = g_constants.gamma; - output.SV_Target = pow(abs(g_textures[g_constants.tex_urid].Sample(g_sampler, input.vs.uv)), 1/gamma); + float4 color = g_textures[g_constants.tex_urid].Sample(g_sampler, input.vs.uv); + output.SV_Target = color; return output; } diff --git a/res/sh/common.hlsl b/res/sh/common.hlsl index fa5b075c..cdb2487b 100644 --- a/res/sh/common.hlsl +++ b/res/sh/common.hlsl @@ -11,6 +11,16 @@ # define INLINE /* For intellisense */ #endif +INLINE float4 float4_norm_from_uint(uint v) +{ + float4 res; + res.r = ((v >> 0) & 0xFF) / 255.0; + res.g = ((v >> 8) & 0xFF) / 255.0; + res.b = ((v >> 16) & 0xFF) / 255.0; + res.a = ((v >> 24) & 0xFF) / 255.0; + return res; +} + /* Linear color from normalized sRGB */ INLINE float4 linear_from_srgb(float4 srgb) { @@ -20,10 +30,5 @@ INLINE float4 linear_from_srgb(float4 srgb) /* Linear color from R8G8B8A8 sRGB */ INLINE float4 linear_from_srgb32(uint srgb32) { - float4 res; - res.r = ((srgb32 >> 0) & 0xFF) / 255.0; - res.g = ((srgb32 >> 8) & 0xFF) / 255.0; - res.b = ((srgb32 >> 16) & 0xFF) / 255.0; - res.a = ((srgb32 >> 24) & 0xFF) / 255.0; - return linear_from_srgb(res); + return linear_from_srgb(float4_norm_from_uint(srgb32)); } diff --git a/res/sh/flood.hlsl b/res/sh/flood.hlsl index 94d5b80b..7744bdd4 100644 --- a/res/sh/flood.hlsl +++ b/res/sh/flood.hlsl @@ -24,7 +24,7 @@ RWTexture2D g_flood_textures[]: register(u0, space1); SamplerState g_sampler : register(s0); /* ========================== * - * Compute shader + * Entry point * ========================== */ struct cs_input { diff --git a/res/sh/material.hlsl b/res/sh/material.hlsl index a7c0c504..cf14d2a5 100644 --- a/res/sh/material.hlsl +++ b/res/sh/material.hlsl @@ -61,7 +61,7 @@ SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) output.grid_id = instance.grid_id; output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); output.tint_lin = linear_from_srgb32(instance.tint_srgb); - output.emittance_lin = linear_from_srgb32(instance.emittance_srgb); + output.emittance_lin = linear_from_srgb(float4(instance.light_emittance_srgb, instance.is_light)); return output; } diff --git a/res/sh/sh_common.h b/res/sh/sh_common.h index e39468c9..7b1470cd 100644 --- a/res/sh/sh_common.h +++ b/res/sh/sh_common.h @@ -30,6 +30,12 @@ INLINE struct sh_float2 sh_float2_from_v2(struct v2 v) return (struct sh_float2) { .v[0] = v.x, .v[1] = v.y }; } +struct sh_float3 { f32 v[3]; }; +INLINE struct sh_float3 sh_float3_from_v3(struct v3 v) +{ + return (struct sh_float3) { .v[0] = v.x, .v[1] = v.y, .v[2] = v.z }; +} + struct sh_float4x4 { f32 v[4][4]; }; INLINE struct sh_float4x4 sh_float4x4_from_mat4x4(struct mat4x4 v) { @@ -58,17 +64,6 @@ INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v) #endif -/* ========================== * - * Blit shader structures - * ========================== */ - -SH_STRUCT(sh_blit_constants { - SH_DECL(float4x4, projection); - SH_DECL(uint, tex_urid); - SH_DECL(float, gamma); -}); -SH_ASSERT_32BIT(struct sh_blit_constants, 18); /* Expected 32bit root constant size in shader */ - /* ========================== * * Material shader structures * ========================== */ @@ -85,7 +80,8 @@ SH_STRUCT(sh_material_instance { SH_DECL(float2, uv0); SH_DECL(float2, uv1); SH_DECL(uint, tint_srgb); - SH_DECL(uint, emittance_srgb); + SH_DECL(uint, is_light); + SH_DECL(float3, light_emittance_srgb); }); SH_STRUCT(sh_material_grid { @@ -125,8 +121,10 @@ SH_STRUCT(sh_shade_constants { SH_DECL(uint, write_tex_urid); SH_DECL(uint, tex_width); SH_DECL(uint, tex_height); + SH_DECL(float, exposure); + SH_DECL(float, gamma); }); -SH_ASSERT_32BIT(struct sh_shade_constants, 7); /* Expected 32bit root constant size in shader */ +SH_ASSERT_32BIT(struct sh_shade_constants, 9); /* Expected 32bit root constant size in shader */ /* ========================== * * Shape shader structures @@ -159,3 +157,13 @@ SH_STRUCT(sh_ui_instance { SH_DECL(float2, uv1); SH_DECL(uint, tint_srgb); }); + +/* ========================== * + * Blit shader structures + * ========================== */ + +SH_STRUCT(sh_blit_constants { + SH_DECL(float4x4, projection); + SH_DECL(uint, tex_urid); +}); +SH_ASSERT_32BIT(struct sh_blit_constants, 17); /* Expected 32bit root constant size in shader */ diff --git a/res/sh/shade.hlsl b/res/sh/shade.hlsl index 1457a301..524a841f 100644 --- a/res/sh/shade.hlsl +++ b/res/sh/shade.hlsl @@ -5,7 +5,7 @@ * ========================== */ #define ROOTSIG \ - "RootConstants(num32BitConstants = 7, b0), " \ + "RootConstants(num32BitConstants = 9, b0), " \ "DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ "DescriptorTable(SRV(t0, space = 1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ "DescriptorTable(UAV(u0, space = 2, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ @@ -25,10 +25,6 @@ RWTexture2D g_write_textures[]: register(u0, space2); SamplerState g_sampler : register(s0); -/* ========================== * - * Compute shader - * ========================== */ - struct cs_input { DECLS(uint3, SV_DispatchThreadID); }; @@ -36,19 +32,31 @@ struct cs_input { #define SAMPLES 4 #define MARCHES 16 -INLINE float4 get_light_in_dir(uint2 pos, float2 dir) +/* ========================== * + * Lighting + * ========================== */ + +#define AMBIENT float4(1, 1, 1, 1) + +INLINE float4 get_light_in_dir(uint2 ray_start, float2 ray_dir) { - float4 result = 0; - uint2 at = pos; + float4 result = AMBIENT; + float2 at_float = ray_start; + uint2 at_uint = ray_start; for (uint i = 0; i < MARCHES; ++i) { - uint2 flood = g_emittance_flood_textures[g_constants.emittance_flood_tex_urid][at]; - int2 dist_vec = (int2)at - (int2)flood; + uint2 flood = g_emittance_flood_textures[g_constants.emittance_flood_tex_urid][at_uint]; + float2 dist_vec = at_float - (float2)flood; float dist = length(dist_vec); - if (dist <= 2) { + if (dist <= 1) { result = g_gbuff_textures[g_constants.emittance_tex_urid][flood]; break; } else { - at += dir * dist; + at_float += ray_dir * dist; + 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) { + /* Ambient lighting (ray hit edge of screen) */ + break; + } } } return result; @@ -63,7 +71,7 @@ INLINE float4 get_light_at_pos(uint2 pos) float4 result = 0; for (int i = 0; i < SAMPLES; ++i) { float angle = TAU * (((float)i + rand_float_from_float2(pos + (float)i + sin(g_constants.time))) / ((float)SAMPLES - 1)); - float2 dir = float2(sin(angle), cos(angle)); + float2 dir = float2(cos(angle), sin(angle)); float4 light_in_dir = get_light_in_dir(pos, dir); result += light_in_dir; } @@ -72,6 +80,21 @@ INLINE float4 get_light_at_pos(uint2 pos) return result; } +/* ========================== * + * Tone map + * ========================== */ + +/* ACES approximation by Krzysztof Narkowicz + * https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ */ +INLINE float3 tone_map(float3 v) +{ + return saturate((v * (2.51f * v + 0.03f)) / (v * (2.43f * v + 0.59f) + 0.14f)); +} + +/* ========================== * + * Entry point + * ========================== */ + [numthreads(8, 8, 1)] SH_ENTRY(ROOTSIG) void cs(struct cs_input input) { @@ -82,7 +105,16 @@ SH_ENTRY(ROOTSIG) void cs(struct cs_input input) float4 albedo = g_gbuff_textures[g_constants.albedo_tex_urid][id]; float4 lighting = get_light_at_pos(id); - float4 final_color = albedo * lighting; + float4 color = albedo * lighting; + // float4 color = albedo + lighting; - g_write_textures[g_constants.write_tex_urid][id] = final_color; + /* Tonemap */ + /* TODO: Dynamic exposure based on average scene luminance */ + color *= g_constants.exposure; + color.rgb = tone_map(color.rgb); + + /* Gamma correct */ + color = pow(abs(color), 1/g_constants.gamma); + + g_write_textures[g_constants.write_tex_urid][id] = color; } diff --git a/res/sh/shape.hlsl b/res/sh/shape.hlsl index d9460d77..47729c5f 100644 --- a/res/sh/shape.hlsl +++ b/res/sh/shape.hlsl @@ -21,14 +21,14 @@ struct vs_input { struct vs_output { DECLS(float4, SV_Position); - DECLS(float4, color_lin); + DECLS(float4, color_srgb); }; SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) { struct vs_output output; output.SV_Position = mul(g_constants.projection, float4(input.pos.xy, 0, 1)); - output.color_lin = linear_from_srgb(input.color_srgb); + output.color_srgb = input.color_srgb; return output; } @@ -47,6 +47,6 @@ struct ps_output { SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) { struct ps_output output; - output.SV_Target = input.vs.color_lin; + output.SV_Target = input.vs.color_srgb; return output; } diff --git a/res/sh/ui.hlsl b/res/sh/ui.hlsl index 104fa523..f5f7dbc9 100644 --- a/res/sh/ui.hlsl +++ b/res/sh/ui.hlsl @@ -34,7 +34,7 @@ struct vs_input { struct vs_output { nointerpolation DECLS(int, tex_nurid); DECLS(float2, uv); - DECLS(float4, tint_lin); + DECLS(float4, tint_srgb); DECLS(float4, SV_Position); }; @@ -55,7 +55,7 @@ SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input) output.SV_Position = mul(g_constants.projection, float4(world_pos, 0, 1)); output.tex_nurid = instance.tex_nurid; output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); - output.tint_lin = linear_from_srgb32(instance.tint_srgb); + output.tint_srgb = float4_norm_from_uint(instance.tint_srgb); return output; } @@ -74,7 +74,7 @@ struct ps_output { SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input) { struct ps_output output; - float4 color = input.vs.tint_lin; + float4 color = input.vs.tint_srgb; /* Texture */ if (input.vs.tex_nurid >= 0) { diff --git a/src/draw.c b/src/draw.c index 630c5c9e..adb2267a 100644 --- a/src/draw.c +++ b/src/draw.c @@ -35,7 +35,8 @@ void draw_material(struct gp_render_sig *sig, struct draw_material_params params cmd.material.texture = params.texture; cmd.material.clip = params.clip; cmd.material.tint = params.tint; - cmd.material.emittance = params.emittance; + cmd.material.is_light = params.is_light; + cmd.material.light_emittance = params.light_emittance; gp_push_render_cmd(sig, &cmd); } diff --git a/src/draw.h b/src/draw.h index 32d5fc2b..3cd64750 100644 --- a/src/draw.h +++ b/src/draw.h @@ -25,7 +25,8 @@ struct draw_material_params { struct sprite_tag sprite; struct clip_rect clip; u32 tint; - u32 emittance; + b32 is_light; + struct v3 light_emittance; }; void draw_material(struct gp_render_sig *sig, struct draw_material_params params); diff --git a/src/gp.h b/src/gp.h index 6e62948d..4578b3d5 100644 --- a/src/gp.h +++ b/src/gp.h @@ -36,6 +36,7 @@ enum gp_texture_format { GP_TEXTURE_FORMAT_NONE, GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, + GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT, NUM_GP_TEXTURE_FORMATS }; @@ -70,7 +71,8 @@ struct gp_render_cmd_desc { struct gp_resource *texture; struct clip_rect clip; u32 tint; - u32 emittance; + b32 is_light; + struct v3 light_emittance; i32 grid_cmd_id; } material; struct { diff --git a/src/gp_dx12.c b/src/gp_dx12.c index a14a907e..48c8ec75 100644 --- a/src/gp_dx12.c +++ b/src/gp_dx12.c @@ -680,7 +680,7 @@ INTERNAL void dx12_init_pipelines(void) desc->ps.func = LIT("ps"); desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; desc->rtvs[0].blending = 1; - desc->rtvs[1].format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc->rtvs[1].format = DXGI_FORMAT_R16G16B16A16_FLOAT; desc->rtvs[1].blending = 1; dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); } @@ -710,7 +710,7 @@ INTERNAL void dx12_init_pipelines(void) desc->ps.func = LIT("ps"); desc->ia[0] = (D3D12_INPUT_ELEMENT_DESC) { "pos", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }; desc->ia[1] = (D3D12_INPUT_ELEMENT_DESC) { "color_srgb", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }; - desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc->rtvs[0].format = DXGI_FORMAT_R16G16B16A16_FLOAT; desc->rtvs[0].blending = 1; dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); } @@ -722,7 +722,7 @@ INTERNAL void dx12_init_pipelines(void) desc->ps.file = LIT("sh/ui.hlsl"); desc->vs.func = LIT("vs"); desc->ps.func = LIT("ps"); - desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc->rtvs[0].format = DXGI_FORMAT_R16G16B16A16_FLOAT; desc->rtvs[0].blending = 1; dict_set(G.pipelines_arena, G.pipeline_descs, hash_fnv64(HASH_FNV64_BASIS, desc->name), (u64)desc); } @@ -2251,7 +2251,8 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s struct dxgi_format_info { DXGI_FORMAT format; u32 size; }; LOCAL_PERSIST const struct dxgi_format_info formats[] = { [GP_TEXTURE_FORMAT_R8G8B8A8_UNORM] = { DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, - [GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 4 } + [GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 4 }, + [GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT] = { DXGI_FORMAT_R16G16B16A16_FLOAT, 8 } }; DXGI_FORMAT dxgi_format = ZI; @@ -2538,7 +2539,8 @@ struct material_instance_desc { struct dx12_resource *texture; struct clip_rect clip; u32 tint; - u32 emittance; + b32 is_light; + struct v3 light_emittance; i32 grid_id; }; @@ -2605,7 +2607,8 @@ i32 gp_push_render_cmd(struct gp_render_sig *render_sig, struct gp_render_cmd_de instance_desc->texture = (struct dx12_resource *)cmd_desc->material.texture; instance_desc->clip = cmd_desc->material.clip; instance_desc->tint = cmd_desc->material.tint; - instance_desc->emittance = cmd_desc->material.emittance; + instance_desc->is_light = cmd_desc->material.is_light; + instance_desc->light_emittance = cmd_desc->material.light_emittance; instance_desc->grid_id = cmd_desc->material.grid_cmd_id - 1; ret = ++sig->num_material_instance_descs; } break; @@ -2654,7 +2657,7 @@ void gp_run_render(struct gp_render_sig *render_sig, struct gp_render_params par } /* Alloc buffers */ sig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size, D3D12_RESOURCE_STATE_RENDER_TARGET); - sig->emittance = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size, D3D12_RESOURCE_STATE_RENDER_TARGET); + sig->emittance = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, final_target_size, D3D12_RESOURCE_STATE_RENDER_TARGET); sig->emittance_flood_a = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, final_target_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); sig->emittance_flood_b = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, final_target_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); } @@ -2706,7 +2709,8 @@ void gp_run_render(struct gp_render_sig *render_sig, struct gp_render_params par instance->uv0 = sh_float2_from_v2(desc->clip.p0); instance->uv1 = sh_float2_from_v2(desc->clip.p1); instance->tint_srgb = sh_uint_from_u32(desc->tint); - instance->emittance_srgb = sh_uint_from_u32(desc->emittance); + instance->is_light = sh_uint_from_u32(desc->is_light); + instance->light_emittance_srgb = sh_float3_from_v3(desc->light_emittance); } } @@ -2905,6 +2909,8 @@ void gp_run_render(struct gp_render_sig *render_sig, struct gp_render_params par constants.write_tex_urid = sh_uint_from_u32(final_target->uav_descriptor->index); constants.tex_width = sh_uint_from_u32(final_target_size.x); constants.tex_height = sh_uint_from_u32(final_target_size.y); + constants.exposure = sh_float_from_f32(1.0); + constants.gamma = sh_float_from_f32(2.2); /* Set parameters */ command_list_set_compute_root_constant(cl, &constants, sizeof(constants)); @@ -3435,7 +3441,6 @@ INTERNAL void present_blit(struct swapchain_buffer *dst, struct dx12_resource *s struct sh_blit_constants constants = ZI; constants.projection = sh_float4x4_from_mat4x4(vp_matrix); constants.tex_urid = sh_uint_from_u32(src->srv_descriptor->index); - constants.gamma = sh_float_from_f32(2.2); /* Set parameters */ command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); diff --git a/src/sim_ent.h b/src/sim_ent.h index 3e10ca03..e2ab14f5 100644 --- a/src/sim_ent.h +++ b/src/sim_ent.h @@ -270,6 +270,7 @@ struct sim_ent { struct sprite_tag sprite; struct string sprite_span_name; u32 sprite_tint; + struct v3 sprite_emittance; struct string sprite_collider_slice; /* Collider will sync to bounds of this slice if set */ diff --git a/src/sim_step.c b/src/sim_step.c index 7293c46a..f7b09b97 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -254,9 +254,9 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos) //struct sim_ent *e = sim_ent_alloc_local(parent); struct sim_ent *e = sim_ent_alloc_sync_src(parent); - f32 r = 0; + f32 rot = 0; struct v2 size = V2(1, 0.5); - struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size); + struct xform xf = XFORM_TRS(.t = pos, .r = rot, .s = size); sim_ent_set_xform(e, xf); e->sprite = sprite_tag_from_path(LIT("sprite/box.ase")); @@ -270,6 +270,15 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos) sim_ent_enable_prop(e, SEPROP_LIGHT_TEST); + /* FIXME: Remove this */ + { + static struct rand_state rand = ZI; + f32 r = rand_f64_from_state(&rand, 1, 5); + f32 g = rand_f64_from_state(&rand, 1, 5); + f32 b = rand_f64_from_state(&rand, 1, 5); + e->sprite_emittance = V3(r, g, b); + } + sim_ent_enable_prop(e, SEPROP_DYNAMIC); e->mass_unscaled = 100; e->inertia_unscaled = 50; diff --git a/src/user.c b/src/user.c index 15365448..75e66dd4 100644 --- a/src/user.c +++ b/src/user.c @@ -1200,10 +1200,10 @@ INTERNAL void user_update(struct sys_window *window) /* TODO: Fade in placeholder if texture isn't loaded */ if (sheet->loaded) { b32 is_light = sim_ent_has_prop(ent, SEPROP_LIGHT_TEST); - u32 emittance = is_light ? COLOR_WHITE : 0; + struct v3 emittance = ent->sprite_emittance; u32 tint = ent->sprite_tint; struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, ent->animation_frame); - struct draw_material_params params = DRAW_MATERIAL_PARAMS(.xf = sprite_xform, .sprite = sprite, .tint = tint, .clip = frame.clip, .emittance = emittance); + struct draw_material_params params = DRAW_MATERIAL_PARAMS(.xf = sprite_xform, .sprite = sprite, .tint = tint, .clip = frame.clip, .is_light = is_light, .light_emittance = emittance); draw_material(G.world_render_sig, params); } } @@ -1223,7 +1223,7 @@ INTERNAL void user_update(struct sys_window *window) struct v2i32 world_tile_index = sim_world_tile_index_from_local_tile_index(chunk_index, local_tile_index); struct v2 pos = sim_pos_from_world_tile_index(world_tile_index); struct xform tile_xf = xform_from_rect(RECT_FROM_V2(pos, V2(tile_size, tile_size))); - struct draw_material_params params = DRAW_MATERIAL_PARAMS(.xf = tile_xf, .sprite = tile_sprite, .emittance = COLOR_BLACK); + struct draw_material_params params = DRAW_MATERIAL_PARAMS(.xf = tile_xf, .sprite = tile_sprite, .is_light = 1, .light_emittance = V3(0, 0, 0)); draw_material(G.world_render_sig, params); } } @@ -2030,7 +2030,7 @@ INTERNAL void user_update(struct sys_window *window) if (G.user_texture) { gp_resource_release(G.user_texture); } - G.user_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, GP_TEXTURE_FLAG_TARGETABLE, user_resolution, 0); + G.user_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT, GP_TEXTURE_FLAG_TARGETABLE, user_resolution, 0); } /* Draw world to user texture */