From e3fd58a0c83deab1ed8375e9af4fc3b9f00d22b5 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 9 Mar 2026 01:34:22 -0400 Subject: [PATCH] feat(theme): Enhance CRTFilter with CRT-Lottes inspired effects --- src/theme_nerv_fx.py | 51 +++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/src/theme_nerv_fx.py b/src/theme_nerv_fx.py index 87a4d4b..b08f676 100644 --- a/src/theme_nerv_fx.py +++ b/src/theme_nerv_fx.py @@ -12,27 +12,54 @@ class CRTFilter: return draw_list = imgui.get_foreground_draw_list() - # Scanlines - scanline_color = imgui.get_color_u32((0.0, 0.0, 0.0, 0.06)) + # 1. Enhanced Scanlines (Horizontal) + # Vary thickness and alpha for a more "analog" feel for y in range(0, int(height), 2): - draw_list.add_line((0.0, float(y)), (float(width), float(y)), scanline_color, 1.0) + # Thicker/Darker every 4 pixels + is_major = (y % 4 == 0) + alpha = 0.08 if is_major else 0.04 + thickness = 1.2 if is_major else 0.8 + s_color = imgui.get_color_u32((0.0, 0.0, 0.0, alpha)) + draw_list.add_line((0.0, float(y)), (float(width), float(y)), s_color, thickness) - # Subtle Vignette - v_steps = 15 + # 2. Shadow Mask (Vertical) + # Simulates aperture grille / phosphor strips + m_color = imgui.get_color_u32((0.0, 0.0, 0.0, 0.05)) + for x in range(0, int(width), 3): + draw_list.add_line((float(x), 0.0), (float(x), float(height)), m_color, 1.0) + + # 3. Enhanced Curved Vignette / Tube Curvature + # Multiple rounded rectangles with increasing thickness and alpha + v_steps = 20 for i in range(v_steps): - alpha = (i / v_steps) ** 2.0 * 0.15 + # Exponential alpha for smoother falloff + alpha = (i / v_steps) ** 3.0 * 0.25 v_color = imgui.get_color_u32((0.0, 0.0, 0.0, alpha)) - inset = (v_steps - i) * 6.0 + + # Inset and rounding grow to simulate tube curvature + inset = (v_steps - i) * 4.5 + rounding = 60.0 + (v_steps - i) * 8.0 + thickness = 15.0 + if width > inset * 2.0 and height > inset * 2.0: - draw_list.add_rect((inset, inset), (width - inset, height - inset), v_color, 40.0, 0, 10.0) + draw_list.add_rect( + (inset, inset), + (width - inset, height - inset), + v_color, + rounding, + 0, + thickness + ) - # Subtle Random Noise - for _ in range(30): + # 4. Subtle Random Noise / Static + t = time.time() + for _ in range(40): nx = random.uniform(0.0, width) ny = random.uniform(0.0, height) - n_alpha = random.uniform(0.01, 0.03) + # Flickering noise + n_alpha = random.uniform(0.01, 0.04) * (0.8 + 0.2 * math.sin(t * 60.0)) n_color = imgui.get_color_u32((1.0, 1.0, 1.0, n_alpha)) - draw_list.add_rect_filled((nx, ny), (nx + 1.0, ny + 1.0), n_color) + draw_list.add_rect_filled((nx, ny), (nx + 1.2, ny + 1.2), n_color) class StatusFlicker: def get_alpha(self) -> float: