feat(modals): fixed modal-backdrop blur, independent of the acrylic slider
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) <noreply@anthropic.com>
This commit is contained in:
@@ -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() {}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user