draw crosshair via shader sdf

This commit is contained in:
jacob 2026-02-01 21:50:22 -06:00
parent 399f3a1528
commit e3ae1a789f
7 changed files with 153 additions and 82 deletions

View File

@ -163,6 +163,16 @@ Inline Vec4 LinearFromSrgb(Vec4 srgb)
return result; return result;
} }
Inline f32 LuminanceFromColor(Vec4 v)
{
return 0.2126 * v.r + 0.7152 * v.g + 0.0722 * v.b;
};
Inline Vec4 InvertColor(Vec4 v)
{
return Vec4(Vec3(1, 1, 1) - v.rgb, v.a);
};
Inline Vec4 Premul(Vec4 v) Inline Vec4 Premul(Vec4 v)
{ {
Vec4 result; Vec4 result;

View File

@ -908,7 +908,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
////////////////////////////// //////////////////////////////
//- Initialize heap info //- Initialize heap info
b32 can_reuse = 0; b32 can_reuse = 1;
D3D12_HEAP_FLAGS heap_flags = 0; D3D12_HEAP_FLAGS heap_flags = 0;
D3D12_HEAP_PROPERTIES heap_props = Zi; D3D12_HEAP_PROPERTIES heap_props = Zi;
@ -931,7 +931,6 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
} }
else else
{ {
can_reuse = 1;
heap_flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; heap_flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
} }
// Heap props // Heap props
@ -2389,11 +2388,11 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
{ {
if (G_D12.pending_releases.last) if (G_D12.pending_releases.last)
{ {
G_D12.pending_releases.last->next = cl->releases.last; G_D12.pending_releases.last->next = cl->releases.first;
} }
else else
{ {
G_D12.pending_releases.first = cl->releases.last; G_D12.pending_releases.first = cl->releases.first;
} }
G_D12.pending_releases.last = cl->releases.last; G_D12.pending_releases.last = cl->releases.last;
} }
@ -2663,6 +2662,8 @@ void G_MemorySyncEx(G_CommandListHandle cl_handle, G_MemoryBarrierDesc desc)
//- Compute //- Compute
void G_Compute(G_CommandListHandle cl_handle, ComputeShader cs, Vec3I32 groups) void G_Compute(G_CommandListHandle cl_handle, ComputeShader cs, Vec3I32 groups)
{
if (groups.x > 0 && groups.y > 0 && groups.z > 0)
{ {
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Cmd *cmd = G_D12_PushCmd(cl); G_D12_Cmd *cmd = G_D12_PushCmd(cl);
@ -2670,6 +2671,7 @@ void G_Compute(G_CommandListHandle cl_handle, ComputeShader cs, Vec3I32 groups)
cmd->compute.cs = cs; cmd->compute.cs = cs;
cmd->compute.groups = groups; cmd->compute.groups = groups;
} }
}
//- Rasterize //- Rasterize
@ -2681,6 +2683,8 @@ void G_Rasterize(
Rng3 viewport, Rng2 scissor, Rng3 viewport, Rng2 scissor,
G_RasterMode raster_mode G_RasterMode raster_mode
) )
{
if (instances_count > 0 && index_buffer.index_count > 0)
{ {
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Cmd *cmd = G_D12_PushCmd(cl); G_D12_Cmd *cmd = G_D12_PushCmd(cl);
@ -2697,6 +2701,7 @@ void G_Rasterize(
cmd->rasterize.scissor = scissor; cmd->rasterize.scissor = scissor;
cmd->rasterize.raster_mode = raster_mode; cmd->rasterize.raster_mode = raster_mode;
} }
}
//- Clear //- Clear

View File

@ -536,7 +536,7 @@ void BuildEntryPoint(WaveLaneCtx *lane)
: kind == M_EntryKind_ComputeShader ? Lit("ComputeShader") : kind == M_EntryKind_ComputeShader ? Lit("ComputeShader")
: Lit(""); : Lit("");
String shader_name = arg0_tok->s; String shader_name = arg0_tok->s;
u64 shader_resource_hash = HashStringEx(shader_store_hash, shader_name); u64 shader_resource_hash = HashStringEx(shader_store_hash, StringF(perm, "%F.dxil", FmtString(shader_name)));
String line = StringF(perm, "%F %F = { 0x%F };", FmtString(shader_type), FmtString(shader_name), FmtHex(shader_resource_hash)); String line = StringF(perm, "%F %F = { 0x%F };", FmtString(shader_type), FmtString(shader_name), FmtHex(shader_resource_hash));
PushStringToList(perm, &c_shader_lines, line); PushStringToList(perm, &c_shader_lines, line);
} }
@ -660,7 +660,7 @@ void BuildEntryPoint(WaveLaneCtx *lane)
{ {
String file = n->s; String file = n->s;
// Safety check to prevent non-shader files from being removed // Safety check to prevent non-shader files from being removed
if (StringEndsWith(file, Lit("VS")) || StringEndsWith(file, Lit("CS")) || StringEndsWith(file, Lit("PS"))) if (StringEndsWith(file, Lit(".dxil")))
{ {
OS_Rm(n->s); OS_Rm(n->s);
} }
@ -874,7 +874,7 @@ void BuildEntryPoint(WaveLaneCtx *lane)
{ {
String shader_name = e->name; String shader_name = e->name;
GpuObj *gpu_obj = &Build.gpu_objs.array[gpu_obj_idx]; GpuObj *gpu_obj = &Build.gpu_objs.array[gpu_obj_idx];
String out_file = StringF(perm, "%F/%F", FmtString(shader_store_name), FmtString(e->name)); String out_file = StringF(perm, "%F/%F.dxil", FmtString(shader_store_name), FmtString(e->name));
String target = e->kind == ShaderEntryKind_VS ? Lit("vs_6_6") String target = e->kind == ShaderEntryKind_VS ? Lit("vs_6_6")
: e->kind == ShaderEntryKind_PS ? Lit("ps_6_6") : e->kind == ShaderEntryKind_PS ? Lit("ps_6_6")
: e->kind == ShaderEntryKind_CS ? Lit("cs_6_6") : e->kind == ShaderEntryKind_CS ? Lit("cs_6_6")

View File

@ -831,16 +831,7 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Compute movement & look //- Compute movement & look
f32 look_radius = 0; f32 look_radius = 5;
{
Vec2 world_screen_dims = MulAffineBasisVec2(prev_frame->af.screen_to_world, prev_frame->screen_dims);
// look_radius = MinF32(world_screen_dims.x, world_screen_dims.y) * 0.5;
look_radius = MinF32(world_screen_dims.x, world_screen_dims.y) * 0.75;
// FIXME: Lower
f32 max_look_radius = 10;
look_radius = ClampF32(look_radius, 1, max_look_radius);
}
if (!frame->is_editing && !frame->palette.is_showing) if (!frame->is_editing && !frame->palette.is_showing)
{ {
@ -961,30 +952,51 @@ void V_TickForever(WaveLaneCtx *lane)
// } // }
// } // }
// Vec2 look_ratio = Zi;
// {
// Vec2 max_look = Vec2WithLen(frame->look, look_radius);
// Vec2 look_ratio_of_radius = DivVec2Vec2(frame->look, Vec2WithLen(frame->look, look_radius));
// look_ratio = look_ratio_of_radius;
// // Vec2 screen_look = MulAffineVec2(frame->af.world_to_screen, frame->look);
// // Vec2 screen_max_look = MulAffineVec2(frame->af.world_to_screen, frame->look)
// // look_ratio.x = screen_look.x / frame->screen_dims.x;
// // look_ratio.x = frame->look.x / look_radius;
// if (IsNan(look_ratio.x) || IsNan(look_ratio.y))
// {
// look_ratio = VEC2(0, 0);
// }
// // look_ratio = MulVec2(look_ratio, 0.5);
// look_ratio = VEC2(0.5, 0.5);
// }
Vec2 look_ratio = Zi; Vec2 look_ratio = Zi;
{ {
Vec2 max_look = Vec2WithLen(frame->look, look_radius);
Vec2 look_ratio_of_radius = DivVec2Vec2(frame->look, Vec2WithLen(frame->look, look_radius));
look_ratio = look_ratio_of_radius;
// Vec2 screen_look = MulAffineVec2(frame->af.world_to_screen, frame->look);
// Vec2 screen_max_look = MulAffineVec2(frame->af.world_to_screen, frame->look)
// look_ratio.x = screen_look.x / frame->screen_dims.x;
// look_ratio.x = frame->look.x / look_radius;
if (IsNan(look_ratio.x) || IsNan(look_ratio.y))
{
look_ratio = VEC2(0, 0);
}
// look_ratio = MulVec2(look_ratio, 0.5);
look_ratio = VEC2(0.5, 0.5); look_ratio = VEC2(0.5, 0.5);
// look_ratio = VEC2(0.5, 0.5 * (16.0 / 9.0));
} }
P_Ent *player = P_EntFromKey(local_world->last_frame, V.player_key); P_Ent *player = P_EntFromKey(local_world->last_frame, V.player_key);
P_Ent *guy = P_EntFromKey(local_world->last_frame, player->guy); P_Ent *guy = P_EntFromKey(local_world->last_frame, player->guy);
Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid; Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid;
@ -2154,11 +2166,13 @@ void V_TickForever(WaveLaneCtx *lane)
// f32 cross_dist = 1.0; // f32 cross_dist = 1.0;
f32 cross_dist = Vec2Len(look) - Vec2Len(SubVec2(desired_fire_pos, desired_ent_to_world_af.og)); f32 cross_dist = Vec2Len(look) - Vec2Len(SubVec2(desired_fire_pos, desired_ent_to_world_af.og));
Vec2 cross = AddVec2(desired_fire_pos, MulVec2(look_rot, cross_dist)); frame->world_crosshair = AddVec2(desired_fire_pos, MulVec2(look_rot, cross_dist));
frame->screen_crosshair = MulAffineVec2(frame->af.world_to_screen, frame->world_crosshair);
frame->shade_crosshair = MulAffineVec2(frame->af.world_to_shade, frame->world_crosshair);
// P_DebugDrawPoint(AddVec2(MulAffineVec2(frame->af.screen_to_world, MulVec2(frame->screen_dims, 0.5)), look), Color_Red); // P_DebugDrawPoint(AddVec2(MulAffineVec2(frame->af.screen_to_world, MulVec2(frame->screen_dims, 0.5)), look), Color_Red);
// P_DebugDrawPoint(AddVec2(desired_ent_to_world_af.og, look), Color_Red); // P_DebugDrawPoint(AddVec2(desired_ent_to_world_af.og, look), Color_Red);
P_DebugDrawPoint(cross, Color_Green); // P_DebugDrawPoint(frame->crosshair, Color_Green);
} }
@ -4507,6 +4521,10 @@ void V_TickForever(WaveLaneCtx *lane)
params.shade_selection = frame->shade_selection; params.shade_selection = frame->shade_selection;
params.world_selection = frame->world_selection; params.world_selection = frame->world_selection;
params.screen_crosshair = frame->screen_crosshair;
params.shade_crosshair = frame->shade_crosshair;
params.world_crosshair = frame->world_crosshair;
params.camera_pos = frame->camera_pos; params.camera_pos = frame->camera_pos;
params.camera_zoom = frame->camera_zoom; params.camera_zoom = frame->camera_zoom;
@ -4645,14 +4663,6 @@ void V_TickForever(WaveLaneCtx *lane)
G_DumbGlobalMemorySync(frame->cl); G_DumbGlobalMemorySync(frame->cl);
} }
//////////////////////////////
//- Transition G-buffers
{
// Make albedo readonly
G_DumbMemoryLayoutSync(frame->cl, albedo_target, G_Layout_DirectQueue_ShaderRead);
}
////////////////////////////// //////////////////////////////
//- Shading pass //- Shading pass
@ -4662,11 +4672,19 @@ void V_TickForever(WaveLaneCtx *lane)
G_Compute(frame->cl, V_ShadeCS, V_ThreadGroupSizeFromTexSize(frame->shade_dims)); G_Compute(frame->cl, V_ShadeCS, V_ThreadGroupSizeFromTexSize(frame->shade_dims));
} }
//////////////////////////////
//- Transition G-buffers to readonly
{
G_DumbMemoryLayoutSync(frame->cl, albedo_target, G_Layout_DirectQueue_ShaderRead);
G_DumbMemoryLayoutSync(frame->cl, shade_target, G_Layout_DirectQueue_ShaderRead);
}
////////////////////////////// //////////////////////////////
//- Composite pass //- Composite pass
G_DumbMemoryLayoutSync(frame->cl, screen_target, G_Layout_DirectQueue_RenderTargetWrite); G_DumbMemoryLayoutSync(frame->cl, screen_target, G_Layout_DirectQueue_RenderTargetWrite);
G_DumbMemoryLayoutSync(frame->cl, shade_target, G_Layout_DirectQueue_ShaderRead);
{ {
G_Rasterize( G_Rasterize(

View File

@ -273,7 +273,7 @@ Struct(V_Frame)
// affines; // affines;
V_Affines af; V_Affines af;
// Cursors // Cursor
Vec2 screen_cursor; Vec2 screen_cursor;
Vec2 shade_cursor; Vec2 shade_cursor;
Vec2 world_cursor; Vec2 world_cursor;
@ -281,6 +281,11 @@ Struct(V_Frame)
Rng2 shade_selection; Rng2 shade_selection;
Rng2 world_selection; Rng2 world_selection;
// Crosshair
Vec2 screen_crosshair;
Vec2 shade_crosshair;
Vec2 world_crosshair;
// Vis commands // Vis commands
i64 cmds_count; i64 cmds_count;
V_CmdNode *first_cmd_node; V_CmdNode *first_cmd_node;

View File

@ -746,25 +746,25 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
} }
////////////////////////////// //////////////////////////////
//- Grid overlay //- Grid
Vec4 overlay_color = 0; Vec4 grid_color = 0;
if (is_in_world_bounds) if (is_in_world_bounds)
{ {
// Grid outline // Grid outline
if (V_ShaderConst_GpuFlags & V_GpuFlag_DebugDraw) if (V_ShaderConst_GpuFlags & V_GpuFlag_DebugDraw)
{ {
const Vec4 grid_color = LinearFromSrgb(Vec4(1, 1, 1, 0.1)); const Vec4 line_color = LinearFromSrgb(Vec4(1, 1, 1, 0.1));
Vec2 grid_screen_p0 = mul(params.af.world_to_screen, Vec3(floor(world_pos), 1)); Vec2 line_screen_p0 = mul(params.af.world_to_screen, Vec3(floor(world_pos), 1));
Vec2 grid_screen_p1 = mul(params.af.world_to_screen, Vec3(ceil(world_pos), 1)); Vec2 line_screen_p1 = mul(params.af.world_to_screen, Vec3(ceil(world_pos), 1));
f32 grid_dist = 100000; f32 line_dist = 100000;
grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p0.x)); line_dist = min(line_dist, abs(screen_pos.x - line_screen_p0.x));
grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p1.x)); line_dist = min(line_dist, abs(screen_pos.x - line_screen_p1.x));
grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p0.y)); line_dist = min(line_dist, abs(screen_pos.y - line_screen_p0.y));
grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p1.y)); line_dist = min(line_dist, abs(screen_pos.y - line_screen_p1.y));
if (grid_dist <= half_thickness * 0.5) if (line_dist <= half_thickness * 0.5)
{ {
overlay_color = grid_color; grid_color = line_color;
} }
} }
@ -779,11 +779,11 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
f32 y_dist = abs(screen_pos.y - zero_screen.y); f32 y_dist = abs(screen_pos.y - zero_screen.y);
if (y_dist <= half_thickness) if (y_dist <= half_thickness)
{ {
overlay_color = x_axis_color; grid_color = x_axis_color;
} }
else if (x_dist <= half_thickness) else if (x_dist <= half_thickness)
{ {
overlay_color = y_axis_color; grid_color = y_axis_color;
} }
} }
@ -797,12 +797,27 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
bounds_dist = min(bounds_dist, abs(screen_pos.y - world_bounds_screen_p1.y)); bounds_dist = min(bounds_dist, abs(screen_pos.y - world_bounds_screen_p1.y));
if (bounds_dist <= half_thickness) if (bounds_dist <= half_thickness)
{ {
overlay_color = bounds_color; grid_color = bounds_color;
} }
} }
// Premultiply // Premultiply
overlay_color.rgb *= overlay_color.a; grid_color.rgb *= grid_color.a;
}
//////////////////////////////
//- Crosshair
Vec4 crosshair_color = 0;
{
f32 screen_dist = length(params.screen_crosshair - screen_pos);
if (screen_dist < 5)
{
crosshair_color = Color_White;
}
crosshair_color.rgb *= crosshair_color.a;
} }
////////////////////////////// //////////////////////////////
@ -813,7 +828,20 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
result = BlendPremul(albedo_color, result); result = BlendPremul(albedo_color, result);
result = BlendPremul(particle_color, result); result = BlendPremul(particle_color, result);
result = BlendPremul(selection_color, result); result = BlendPremul(selection_color, result);
result = BlendPremul(overlay_color, result); result = BlendPremul(grid_color, result);
// Adaptively blend crosshair
{
f32 luminance = LuminanceFromColor(result);
f32 adaptive_threshold = 0.5;
Vec4 adapted_crosshair_color = crosshair_color;
if (luminance > adaptive_threshold)
{
adapted_crosshair_color = InvertColor(Unpremul(crosshair_color));
adapted_crosshair_color = Premul(adapted_crosshair_color);
}
result = BlendPremul(adapted_crosshair_color, result);
}
result = Unpremul(result); result = Unpremul(result);

View File

@ -74,10 +74,15 @@ Struct(V_GpuParams)
Vec2 screen_cursor; Vec2 screen_cursor;
Vec2 shade_cursor; Vec2 shade_cursor;
Vec2 world_cursor; Vec2 world_cursor;
Rng2 screen_selection; Rng2 screen_selection;
Rng2 shade_selection; Rng2 shade_selection;
Rng2 world_selection; Rng2 world_selection;
Vec2 screen_crosshair;
Vec2 shade_crosshair;
Vec2 world_crosshair;
Vec2 camera_pos; Vec2 camera_pos;
f32 camera_zoom; f32 camera_zoom;