From 6a5cf099610bb5ec4450f28e67c40bbd0114223d Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 4 Nov 2025 06:17:26 -0600 Subject: [PATCH] box edge anti aliasing --- src/pp/pp.c | 24 ++++--------- src/ui/ui_core.c | 27 --------------- src/ui/ui_draw.gpu | 84 +++++++++++++++++++++++++++------------------- 3 files changed, 56 insertions(+), 79 deletions(-) diff --git a/src/pp/pp.c b/src/pp/pp.c index 0d6db3e7..659762f6 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -1959,9 +1959,9 @@ void PP_UpdateUser(void) g->lister_pos = SubVec2(g->ui_cursor, rep.activation_offset); } - UI_Push(BackgroundColor, Rgba32F(0.075, 0.075, 0.075, 0.99)); - UI_Push(BorderColor, Rgba32F(0.2, 0.2, 0.2, 1)); - UI_Push(Border, 2); + UI_Push(BackgroundColor, 0xfa1a1d1e); + UI_Push(BorderColor, 0xff343a3b); + UI_Push(Border, 1); // UI_Size padding = UI_FILL(1, 0); // UI_Size padding = UI_PIX(10, 0); @@ -1971,20 +1971,17 @@ void PP_UpdateUser(void) UI_Push(LayoutAxis, Axis_Y); UI_Push(FloatingPos, g->lister_pos); UI_SetNext(Flags, UI_BoxFlag_Floating); - UI_SetNext(Rounding, UI_RPIX(50)); + UI_SetNext(Rounding, UI_RPIX(15)); + // UI_SetNext(Rounding, UI_RFILL(1)); UI_Box *lister_box = UI_BuildBox(Lit("lister")); UI_Box *lister_pad = lister_box; UI_PushCP(lister_pad); { - // UI_BuildSpacer(UI_PIX(10, 0)); UI_Push(BackgroundColor, 0); UI_Push(LayoutAxis, Axis_X); UI_Push(Width, UI_FILL(1, 0)); - UI_Push(Height, UI_FNT(5, 0)); + UI_Push(Height, UI_FNT(2, 0)); { - UI_Push(BackgroundColor, Color_Orange); - UI_Push(Border, 2); - UI_Box *title_bar = UI_BuildBox(Zstr); UI_PushCP(title_bar); { @@ -1994,23 +1991,14 @@ void PP_UpdateUser(void) UI_Push(Border, 0); UI_Box *left_box = UI_BuildBox(Zstr); - // UI_SetNext(LeftPadding, UI_PIX(10, 1)); - // UI_SetNext(Padding, UI_PAD(UI_FILL(1, 0))); UI_Box *center_box = UI_BuildBox(Zstr); UI_Box *right_box = UI_BuildBox(Zstr); - // UI_Pad title_padding = UI_PADEX(.left = UI_PIX(50, 0), .right = UI_PIX(50, 0), .bottom = UI_PIX(10, 0)); - // UI_Pad title_padding = UI_PAD(UI_FILL(1, 0)); - // UI_Box *center_pad = UI_BuildPad(center_box, title_padding); - // UI_Box *center_pad = center_box; UI_PushCP(center_box); { UI_SetNext(Text, Lit("Title")); UI_SetNext(Flags, UI_BoxFlag_DrawText); - // UI_SetNext(Padding, UI_PADEX(.left = UI_PIX(100, 0), .right = UI_PIX(50, 0), .bottom = UI_PIX(10, 0))); - // UI_SetNext(Padding, UI_PADEX(.left = UI_PIX(1, 0))); UI_SetNext(Padding, UI_PADALL(UI_FILL(1, 0))); - // UI_SetNext(Padding, UI_PAD(.left = UI_FILL(1, 0), .right = UI_FILL(1, 0))); UI_Box *title_box = UI_BuildBox(Zstr); } UI_PopCP(); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index d0cb81e1..255363d7 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1106,38 +1106,11 @@ i64 UI_EndFrame(UI_Frame frame) rect->tint_srgb = box->tint; rect->border = box->border; - - /* Rounding */ rect->tl_rounding = box->rounding_tl; rect->tr_rounding = box->rounding_tr; rect->br_rounding = box->rounding_br; rect->bl_rounding = box->rounding_bl; - // { - // UI_Rounding rounding = box->rounding; - // f32 final_rounding = 0; - // { - // Vec2 half_dims = MulVec2(SubVec2(box->p1, box->p0), 0.5); - // f32 min_half_dims = MinF32(half_dims.x, half_dims.y); - // switch(rounding.kind) - // { - // default: break; - // case UI_RoundKind_Pixel: - // { - // final_rounding = rounding.v; - // } break; - // case UI_RoundKind_Fit: - // { - // final_rounding = rounding.v * min_half_dims; - // } break; - // } - // final_rounding = MinF32(final_rounding, min_half_dims); - // } - // rect->tl_rounding = final_rounding; - // rect->tr_rounding = final_rounding; - // rect->br_rounding = final_rounding; - // rect->bl_rounding = final_rounding; - // } /* Texture */ if (box->background_texture != 0) diff --git a/src/ui/ui_draw.gpu b/src/ui/ui_draw.gpu index 9d484017..c2bf8ffe 100644 --- a/src/ui/ui_draw.gpu +++ b/src/ui/ui_draw.gpu @@ -46,33 +46,19 @@ UI_RectPS_Input VSDef(UI_RectVS, Semantic(u32, sv_instanceid), Semantic(u32, sv_ } //- Pixel shader - UI_RectPS_Output PSDef(UI_RectPS, UI_RectPS_Input input) { ConstantBuffer sig = UI_rect_sig; StructuredBuffer rects = UniformResourceFromRid(sig.rects); UI_RectInstance rect = rects[input.rect_idx]; - Vec4 result = 0; Vec2 p = input.sv_position.xy; + Vec2 rect_uv = input.rect_uv; Vec2 p0 = rect.p0; Vec2 p1 = rect.p1; - Vec2 rect_uv = input.rect_uv; - /* Background */ - if (rect.flags & UI_RectFlag_DrawTexture) - { - SamplerState sampler = UniformSamplerFromRid(sig.sampler); - Texture2D tex = NonUniformResourceFromRid(rect.tex); - result = tex.Sample(sampler, input.tex_uv); - } - else - { - result = input.background_lin; - } - - /* Calculate distance to edge (negative means out of bounds) */ - f32 edge_dist = min(min(p.x - p0.x, p1.x - p.x), min(p.y - p0.y, p1.y - p.y)); + /* Calculate rect sdf (negative means pixel is inside of rect) */ + f32 rect_dist = min(min(p.x - p0.x, p1.x - p.x), min(p.y - p0.y, p1.y - p.y)); { f32 tl_radius = rect.tl_rounding; f32 tr_radius = rect.tr_rounding; @@ -82,35 +68,65 @@ UI_RectPS_Output PSDef(UI_RectPS, UI_RectPS_Input input) Vec2 tr = Vec2(p1.x - tr_radius, p0.y + tr_radius); Vec2 br = Vec2(p1.x - br_radius, p1.y - br_radius); Vec2 bl = Vec2(p0.x + bl_radius, p1.y - bl_radius); - if (p.x < tl.x && p.y < tl.y) edge_dist = min(edge_dist, tl_radius - length(tl - p)); - if (p.x > tr.x && p.y < tr.y) edge_dist = min(edge_dist, tr_radius - length(tr - p)); - if (p.x > br.x && p.y > br.y) edge_dist = min(edge_dist, br_radius - length(br - p)); - if (p.x < bl.x && p.y > bl.y) edge_dist = min(edge_dist, bl_radius - length(bl - p)); + if (p.x < tl.x && p.y < tl.y) rect_dist = min(rect_dist, tl_radius - length(tl - p)); + if (p.x > tr.x && p.y < tr.y) rect_dist = min(rect_dist, tr_radius - length(tr - p)); + if (p.x > br.x && p.y > br.y) rect_dist = min(rect_dist, br_radius - length(br - p)); + if (p.x < bl.x && p.y > bl.y) rect_dist = min(rect_dist, bl_radius - length(bl - p)); } + rect_dist = -rect_dist; - /* Border */ - if (edge_dist < rect.border) + /* Calculate border sdf (negative means pixel is inside of border) */ + f32 border_width = 0; + f32 border_dist = 0; + Vec4 border_color = 0; { - result = input.border_lin; + if (rect.border > 0) + { + border_width = rect.border; + border_color = input.border_lin; + } + else + { + border_width = 0; + border_color = input.background_lin; + } + border_dist = abs(rect_dist); + if (rect_dist <= 0) + { + border_dist -= border_width; + } } - /* Out of bounds */ - if (edge_dist < 0) + /* Background */ + Vec4 background_color = 0; { - result = 0; + if (rect_dist <= 0) + { + if (rect.flags & UI_RectFlag_DrawTexture) + { + SamplerState sampler = UniformSamplerFromRid(sig.sampler); + Texture2D tex = NonUniformResourceFromRid(rect.tex); + background_color = tex.Sample(sampler, input.tex_uv); + } + else + { + background_color = input.background_lin; + } + } } - /* Tint */ - result *= input.tint_lin; - - /* Debug */ - if (sig.debug_srgb != 0) + /* Final color */ + Vec4 final_color = 0; { - result = LinearFromSrgbU32(sig.debug_srgb); + f32 w = fwidth(border_dist); + f32 border_blend = saturate(0.5 - border_dist / w); + // f32 border_blend = 0; + final_color = lerp(background_color, border_color, border_blend); } + final_color *= input.tint_lin; UI_RectPS_Output output; - output.sv_target0 = result; + output.sv_target0 = sig.debug_srgb != 0 ? LinearFromSrgbU32(sig.debug_srgb) : final_color; return output; }