feat(ui): Implement custom UI shaders for soft shadows and glass effects

This commit is contained in:
2026-03-08 22:01:42 -04:00
parent c84a6d7dfc
commit 0b49b3ad39
3 changed files with 88 additions and 0 deletions

View File

@@ -883,6 +883,12 @@ class App:
if self._show_track_proposal_modal: if self._show_track_proposal_modal:
imgui.open_popup("Track Proposal") imgui.open_popup("Track Proposal")
if imgui.begin_popup_modal("Track Proposal", True, imgui.WindowFlags_.always_auto_resize)[0]: if imgui.begin_popup_modal("Track Proposal", True, imgui.WindowFlags_.always_auto_resize)[0]:
from src import shaders
p_min = imgui.get_window_pos()
p_max = imgui.ImVec2(p_min.x + imgui.get_window_size().x, p_min.y + imgui.get_window_size().y)
# Render soft shadow behind the modal
shaders.draw_soft_shadow(imgui.get_background_draw_list(), p_min, p_max, imgui.ImVec4(0, 0, 0, 0.6), 25.0, 6.0)
if not self._show_track_proposal_modal: if not self._show_track_proposal_modal:
imgui.close_current_popup() imgui.close_current_popup()
imgui.end_popup() imgui.end_popup()
@@ -924,6 +930,11 @@ class App:
return return
imgui.open_popup("Apply Patch?") imgui.open_popup("Apply Patch?")
if imgui.begin_popup_modal("Apply Patch?", True, imgui.WindowFlags_.always_auto_resize)[0]: if imgui.begin_popup_modal("Apply Patch?", True, imgui.WindowFlags_.always_auto_resize)[0]:
from src import shaders
p_min = imgui.get_window_pos()
p_max = imgui.ImVec2(p_min.x + imgui.get_window_size().x, p_min.y + imgui.get_window_size().y)
shaders.draw_soft_shadow(imgui.get_background_draw_list(), p_min, p_max, imgui.ImVec4(0, 0, 0, 0.6), 25.0, 6.0)
imgui.text_colored(vec4(255, 230, 77), "Tier 4 QA Generated a Patch") imgui.text_colored(vec4(255, 230, 77), "Tier 4 QA Generated a Patch")
imgui.separator() imgui.separator()
if self._pending_patch_files: if self._pending_patch_files:

72
src/shaders.py Normal file
View File

@@ -0,0 +1,72 @@
from imgui_bundle import imgui
def draw_soft_shadow(draw_list: imgui.ImDrawList, p_min: imgui.ImVec2, p_max: imgui.ImVec2, color: imgui.ImVec4, shadow_size: float = 10.0, rounding: float = 0.0) -> None:
"""
Simulates a soft shadow effect by drawing multiple concentric rounded rectangles
with decreasing alpha values. This is a faux-shader effect using primitive batching.
"""
r, g, b, a = color.x, color.y, color.z, color.w
steps = int(shadow_size)
if steps <= 0:
return
alpha_step = a / steps
for i in range(steps):
current_alpha = a - (i * alpha_step)
# Apply an easing function (e.g., cubic) for a smoother shadow falloff
current_alpha = current_alpha * (1.0 - (i / steps)**2)
if current_alpha <= 0.01:
continue
expand = float(i)
c_min = imgui.ImVec2(p_min.x - expand, p_min.y - expand)
c_max = imgui.ImVec2(p_max.x + expand, p_max.y + expand)
u32_color = imgui.get_color_u32(imgui.ImVec4(r, g, b, current_alpha))
draw_list.add_rect(
c_min,
c_max,
u32_color,
rounding + expand if rounding > 0 else 0.0,
flags=imgui.DrawFlags_.round_corners_all if rounding > 0 else imgui.DrawFlags_.none,
thickness=1.0
)
def apply_faux_acrylic_glass(draw_list: imgui.ImDrawList, p_min: imgui.ImVec2, p_max: imgui.ImVec2, base_color: imgui.ImVec4, rounding: float = 0.0) -> None:
"""
Simulates a faux acrylic/glass effect by drawing a semi-transparent base,
a gradient overlay for 'shine', and a subtle inner border for 'edge glow'.
"""
r, g, b, a = base_color.x, base_color.y, base_color.z, base_color.w
# 1. Base tinted semi-transparent fill (fake blur base)
fill_color = imgui.get_color_u32(imgui.ImVec4(r, g, b, a * 0.7))
draw_list.add_rect_filled(
p_min, p_max, fill_color, rounding,
flags=imgui.DrawFlags_.round_corners_all if rounding > 0 else imgui.DrawFlags_.none
)
# 2. Gradient overlay to simulate light scattering (acrylic reflection)
shine_top = imgui.get_color_u32(imgui.ImVec4(1.0, 1.0, 1.0, 0.15))
shine_bot = imgui.get_color_u32(imgui.ImVec4(1.0, 1.0, 1.0, 0.0))
# We can't do rounded corners with add_rect_filled_multicolor easily, but we can do it with clip rects or just draw it directly if rounding=0
# For now, we'll just draw a subtle overlay in the upper half
if rounding == 0:
draw_list.add_rect_filled_multicolor(
p_min, imgui.ImVec2(p_max.x, p_min.y + (p_max.y - p_min.y) * 0.5),
shine_top, shine_top, shine_bot, shine_bot
)
# 3. Inner bright border to simulate "glass edge" refraction
inner_glow = imgui.get_color_u32(imgui.ImVec4(1.0, 1.0, 1.0, 0.2))
draw_list.add_rect(
imgui.ImVec2(p_min.x + 1, p_min.y + 1),
imgui.ImVec2(p_max.x - 1, p_max.y - 1),
inner_glow, rounding,
flags=imgui.DrawFlags_.round_corners_all if rounding > 0 else imgui.DrawFlags_.none,
thickness=1.0
)

View File

@@ -231,6 +231,11 @@ def apply(palette_name: str) -> None:
style.item_spacing = imgui.ImVec2(8.0, 4.0) style.item_spacing = imgui.ImVec2(8.0, 4.0)
style.item_inner_spacing = imgui.ImVec2(4.0, 4.0) style.item_inner_spacing = imgui.ImVec2(4.0, 4.0)
style.scrollbar_size = 14.0 style.scrollbar_size = 14.0
# Rendering anti-aliasing (Shaders/Quality)
style.anti_aliased_lines = True
style.anti_aliased_fill = True
style.anti_aliased_lines_use_tex = True
if not colours: if not colours:
# Reset to imgui dark defaults # Reset to imgui dark defaults