From 156735eb0665d2f07a343d611d2c122eeba07c3a Mon Sep 17 00:00:00 2001 From: DanS Date: Sun, 12 Jul 2026 07:41:53 -0500 Subject: [PATCH] feat(modals): fixed modal-backdrop blur, independent of the acrylic slider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The modal backdrop blur was params.blurRadius (96) scaled by the user's global acrylic blur-strength slider (blurRadiusMultiplier), so lowering the slider also weakened every modal's backdrop. Make the modal blur a fixed hardcoded value. Add AcrylicParams::absoluteBlurRadius: when set, applyBlur() uses the radius as-is and skips the multiplier (threaded through both the GL and DX11 blur paths + the no-op stub). DrawFullWindowBlurBackdrop sets it, so the modal backdrop is always a 96px blur regardless of the slider. Panels/other acrylic still scale with the slider as before. Verified: rendering a modal at blur_multiplier 0.1 vs 2.0 now produces an identical backdrop (max pixel diff 1/255) — previously those were ~9.6px vs ~192px of blur. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/ui/effects/acrylic.cpp | 18 +++++++++--------- src/ui/effects/acrylic.h | 9 +++++++-- src/ui/material/draw_helpers.h | 1 + 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/ui/effects/acrylic.cpp b/src/ui/effects/acrylic.cpp index aed0507..7ef20c2 100644 --- a/src/ui/effects/acrylic.cpp +++ b/src/ui/effects/acrylic.cpp @@ -388,14 +388,14 @@ void AcrylicMaterial::setQuality(AcrylicQuality quality) } } -void AcrylicMaterial::applyBlur(float radius) +void AcrylicMaterial::applyBlur(float radius, bool ignoreMultiplier) { if (!blurBuffers_.isValid() || !blurShader_.isValid()) { return; } - - // Apply blur radius multiplier from settings - float scaledRadius = radius * settings_.blurRadiusMultiplier; + + // Apply the user's blur-strength multiplier — unless the caller wants an absolute radius. + float scaledRadius = ignoreMultiplier ? radius : radius * settings_.blurRadiusMultiplier; // Skip blur entirely when multiplier is at or near zero — show sharp background if (scaledRadius < 0.5f) { @@ -566,7 +566,7 @@ void AcrylicMaterial::drawRect(ImDrawList* drawList, const ImVec2& pMin, const I } // Apply blur to captured background - applyBlur(params.blurRadius); + applyBlur(params.blurRadius, params.absoluteBlurRadius); // Calculate UV coordinates for sampling the blur FBO texture. // With multi-viewport enabled, ImGui draw coordinates are in @@ -1274,11 +1274,11 @@ void AcrylicMaterial::captureLiveFramebuffer() blurCacheValid_ = false; } -void AcrylicMaterial::applyBlur(float radius) +void AcrylicMaterial::applyBlur(float radius, bool ignoreMultiplier) { if (!dx_blurSRV_[0] || !dx_blurPS_ || !dx_context_) return; - float scaledRadius = radius * settings_.blurRadiusMultiplier; + float scaledRadius = ignoreMultiplier ? radius : radius * settings_.blurRadiusMultiplier; if (blurCacheValid_ && std::abs(scaledRadius - lastBlurRadius_) < 0.1f) return; int passes = 1; @@ -1540,7 +1540,7 @@ void AcrylicMaterial::drawRect(ImDrawList* drawList, const ImVec2& pMin, const I } // Run DX11 blur pipeline - applyBlur(params.blurRadius); + applyBlur(params.blurRadius, params.absoluteBlurRadius); // DX11 UV: top-left = (0,0), bottom-right = (1,1) — same as ImGui // With multi-viewport, pMin/pMax are in OS screen space; subtract @@ -1704,7 +1704,7 @@ void AcrylicMaterial::resize(int, int) {} void AcrylicMaterial::captureBackground() {} void AcrylicMaterial::captureBackgroundDirect() {} void AcrylicMaterial::captureLiveFramebuffer() {} -void AcrylicMaterial::applyBlur(float) {} +void AcrylicMaterial::applyBlur(float, bool) {} ImTextureID AcrylicMaterial::getBlurredTexture() const { return 0; } ImTextureID AcrylicMaterial::getNoiseTexture() const { return 0; } void AcrylicMaterial::refreshCapabilities() {} diff --git a/src/ui/effects/acrylic.h b/src/ui/effects/acrylic.h index 75933e7..0efcc0d 100644 --- a/src/ui/effects/acrylic.h +++ b/src/ui/effects/acrylic.h @@ -39,7 +39,12 @@ struct AcrylicParams { // Blur radius in pixels (typical: 20-60) float blurRadius = 30.0f; - + + // When true, blurRadius is used AS-IS — NOT scaled by the user's blur-strength slider + // (blurRadiusMultiplier). The modal backdrop sets this so its blur is a fixed value, independent + // of the global acrylic slider. + bool absoluteBlurRadius = false; + // Noise texture opacity (typical: 0.02-0.04) float noiseOpacity = 0.02f; @@ -341,7 +346,7 @@ private: /** * @brief Apply blur passes to captured content */ - void applyBlur(float radius); + void applyBlur(float radius, bool ignoreMultiplier = false); /** * @brief Composite final acrylic appearance diff --git a/src/ui/material/draw_helpers.h b/src/ui/material/draw_helpers.h index fc66aee..8d993c8 100644 --- a/src/ui/material/draw_helpers.h +++ b/src/ui/material/draw_helpers.h @@ -743,6 +743,7 @@ inline void DrawFullWindowBlurBackdrop(ImDrawList* dl, const ImVec2& pMin, const // caller — no other radius contends for the shared, radius-keyed blur cache. auto params = GetCurrentAcrylicTheme().card; params.blurRadius = 96.0f; // strong full-window blur (deeper than panels) + params.absoluteBlurRadius = true; // fixed modal blur — independent of the user's acrylic slider params.fallbackColor.w = 1.0f; // full-strength blur so the live content reads effects::ImGuiAcrylic::DrawAcrylicRect(dl, pMin, pMax, params, 0.0f); // Dim over the blur so the floating (card-less) modal reads as foreground. On DARK themes the