Files
osu-framework/Acrylic_Implementation_Notes.md
2025-11-10 00:26:32 +08:00

8.8 KiB

Acrylic Container 实现说明 / Implementation Notes

问题分析 / Problem Analysis

原始需求 / Original Requirement

用户希望实现"真正的毛玻璃效果" - 即模糊容器背后的内容,类似于 Windows Acrylic 或 macOS 的毛玻璃效果。

The user wanted to implement a "true frosted glass effect" - blurring content behind the container, similar to Windows Acrylic or macOS frosted glass.

技术限制 / Technical Limitations

经过深入研究后发现,在 osu-framework 的当前架构下,无法实现真正的背景模糊效果:

After thorough research, it was discovered that true background blur is not possible in the current osu-framework architecture:

  1. 渲染顺序 / Rendering Order

    • Framework 使用自上而下的渲染顺序 (top-to-bottom)

    • 当容器被渲染时,背后的内容已经绘制到了后台缓冲区

    • 没有办法"回溯"并捕获已经渲染的内容

    • Framework uses top-to-bottom rendering order

    • When a container is rendered, content behind it is already drawn to the backbuffer

    • There's no way to "retroactively" capture already-rendered content

  2. CaptureScreenToFrameBuffer 未实现 / CaptureScreenToFrameBuffer Not Implemented

    • 发现 IRenderer.CaptureScreenToFrameBuffer 方法存在但未实现

    • DeferredRenderer.CaptureScreenToFrameBuffer 只是一个 TODO 占位符

    • 这个方法原本可以用来捕获当前屏幕内容,但目前不可用

    • The IRenderer.CaptureScreenToFrameBuffer method exists but is not implemented

    • DeferredRenderer.CaptureScreenToFrameBuffer is just a TODO placeholder

    • This method could have been used to capture current screen content, but it's currently unavailable

  3. BufferedContainer 的限制 / BufferedContainer Limitations

    • BufferedContainer 只能模糊自己的子元素

    • 它先将子元素渲染到帧缓冲区,然后应用模糊

    • 无法访问或模糊父容器或兄弟元素的内容

    • BufferedContainer can only blur its own children

    • It renders children to a framebuffer first, then applies blur

    • It cannot access or blur content from parent or sibling containers

实现方案 / Implementation Approach

最终方案 / Final Solution

基于技术限制,改为实现一个视觉上接近毛玻璃效果的容器:

Given the technical constraints, implemented a container that visually approximates the frosted glass effect:

public partial class AcrylicContainer : BufferedContainer
{
    // 模糊一个背景层 (Blur a background layer)
    private Drawable backgroundBox;
    
    // 在上面叠加一个着色覆盖层 (Overlay a tinted layer on top)
    private Drawable tintOverlay;
    
    // 用户内容在最上层 (User content on top)
    public Children { get; set; }
}

工作原理 / How It Works:

  1. 背景层 (Background Layer)

    • 创建一个 Box 作为背景 (可以是纯色或图像)

    • 这个背景层会被 BufferedContainer 的模糊效果处理

    • Creates a Box as background (can be solid color or image)

    • This background layer is processed by BufferedContainer's blur effect

  2. 模糊处理 (Blur Processing)

    • 继承自 BufferedContainer,利用其内置的高斯模糊

    • 通过 BlurTo() 方法应用模糊效果

    • Inherits from BufferedContainer, leveraging its built-in Gaussian blur

    • Applies blur effect via BlurTo() method

  3. 着色覆盖 (Tint Overlay)

    • 在模糊背景上叠加一个半透明的着色层

    • 模拟毛玻璃的着色效果

    • Overlays a semi-transparent tinted layer on the blurred background

    • Simulates the tinting effect of frosted glass

  4. 用户内容 (User Content)

    • 用户添加的子元素显示在最上层

    • 可以透过半透明的覆盖层看到模糊的背景

    • User-added children are displayed on top

    • Blurred background is visible through the semi-transparent overlay

使用方法 / Usage

基本用法 / Basic Usage

var acrylicEffect = new AcrylicContainer
{
    RelativeSizeAxes = Axes.Both,
    BlurStrength = 15f,                           // 模糊强度 (0-100)
    TintColour = new Color4(0, 0, 0, 0.3f),       // 着色 (半透明黑色)
    BackgroundColour = Color4.White,               // 要模糊的背景色
    Children = new Drawable[]
    {
        new SpriteText { Text = "Content" }
    }
};

属性说明 / Properties

属性 / Property 说明 / Description
BlurStrength 模糊强度,值越大越模糊 (0-100) / Blur intensity, higher = more blur (0-100)
TintColour 着色颜色,通常是半透明色 / Tint color, usually semi-transparent
BackgroundColour 背景颜色,这个颜色会被模糊 / Background color that will be blurred

视觉效果 / Visual Result

┌─────────────────────────────────┐
│     用户内容 (User Content)       │  ← 清晰的文字/图像
├─────────────────────────────────┤
│   半透明着色层 (Tint Overlay)     │  ← Alpha < 1.0
├─────────────────────────────────┤
│   模糊的背景 (Blurred Background) │  ← 高斯模糊效果
└─────────────────────────────────┘

局限性 / Limitations

  1. 不是真正的背景模糊 / Not True Background Blur

    • 只模糊容器自己的背景层,不是背后的其他元素

    • 要模糊的内容必须作为背景添加到容器内部

    • Only blurs the container's own background layer, not elements behind it

    • Content to be blurred must be added as a background inside the container

  2. 性能开销 / Performance Overhead

    • 每个 AcrylicContainer 使用一个 BufferedContainer

    • 模糊操作需要额外的帧缓冲区和GPU计算

    • 不建议在一个场景中使用过多此效果

    • Each AcrylicContainer uses a BufferedContainer

    • Blur operations require additional framebuffers and GPU computation

    • Not recommended to use too many instances in one scene

  3. 框架限制 / Framework Limitations

    • 真正的毛玻璃效果需要 framework 级别的支持

    • 需要实现 CaptureScreenToFrameBuffer 或类似机制

    • 这超出了当前任务的范围

    • True frosted glass requires framework-level support

    • Would need to implement CaptureScreenToFrameBuffer or similar mechanism

    • This is beyond the scope of the current task

未来改进 / Future Improvements

如果要实现真正的背景模糊,需要:

To implement true background blur, would need:

  1. 实现屏幕捕获 / Implement Screen Capture

    // 在 DeferredRenderer 中实现
    public override void CaptureScreenToFrameBuffer(IFrameBuffer frameBuffer)
    {
        // 将当前后台缓冲区内容复制到 frameBuffer
        // Copy current backbuffer content to frameBuffer
    }
    
  2. 渲染顺序调整 / Rendering Order Adjustment

    • 在绘制 AcrylicContainer 之前,先绘制所有背后的元素

    • 捕获屏幕内容

    • 应用模糊并绘制

    • Draw all elements behind the AcrylicContainer first

    • Capture screen content

    • Apply blur and render

  3. Z-Order 支持 / Z-Order Support

    • Framework 需要支持基于深度的渲染顺序

    • 或者添加特殊的"背景捕获"阶段

    • Framework needs to support depth-based rendering order

    • Or add a special "background capture" phase

测试 / Testing

运行测试场景查看效果:

Run the test scene to see the effect:

dotnet run --project osu.Framework.Tests -- TestSceneAcrylicContainerNew

预期结果 / Expected Result:

  • 看到带有模糊背景的容器

  • 背景是模糊的白色/黑色

  • 上面有清晰的文字

  • 背后的彩色方块移动 (不会被模糊)

  • See a container with blurred background

  • Background is blurred white/black

  • Clear text on top

  • Colored boxes moving behind (not blurred)

结论 / Conclusion

虽然无法实现用户最初想要的"真正的毛玻璃效果"(模糊背后的内容),但当前实现提供了:

While true "frosted glass effect" (blurring content behind) is not achievable, the current implementation provides:

视觉上接近的效果 / Visually similar effect 简单易用的 API / Simple, easy-to-use API 符合 framework 架构 / Follows framework architecture 良好的性能 / Good performance

如果将来 framework 添加了背景捕获支持,可以在不改变 API 的情况下升级实现。

If the framework adds background capture support in the future, the implementation can be upgraded without changing the API.