GaussianBlurEffect (eg. in AcrylicBrush) doesn't work over a SwapChainPanel
See original GitHub issueDescribe the bug
It looks like the Win2D GaussianBlurEffect
doesn’t work when applied on a brush/surface that’s above a SwapChainPanel
. In my case I’m using an IDXGISwapChain2
with DX12 APIs. The interesting thing is that it’s not like the swap chain is just treated as “on top”, with nothing else going over it. Instead, you can place UI elements over it just fine, and all other Composition/Win2D effects seem to work/sample just fine over it as well, it’s just the blur that’s not working. For instance, the various tint/exposure/border/etc. effects correctly overlay on top of the swap chain. Is this a bug with just the blur effect?
NOTE: I can repro this with both the blur effect from
AcrylicBrush
, as well as with a custom effects pipeline. In both cases, blur just won’t be applied over the swap chain content, unlike all other effects in the pipeline in use.
Steps to reproduce the bug
Admittedly this bug requires a few steps to properly repro, due to the number of components involved. Here’s the most minimal repro I can provide:
- Clone
ComputeSharp
- Checkout to the
feature/winui3-shader-panel
branch - Create a new WinUI 3 Desktop app
- Add a reference to the
ComputeSharp.WinUI
project, and theComputeSharp.SourceGenerators
as an analyzer - Use the following XAML in
MainWindow
:
<Grid>
<Grid.Background>
<ImageBrush ImageSource="http://3.bp.blogspot.com/-84ZrGEHfHr0/UJtqvO07w-I/AAAAAAAAAv0/dMeI3WM5wWA/s1600/Nature-HD-Wallpaper1.jpg"/>
</Grid.Background>
<computesharp:ComputeShaderPanel
x:Name="ShaderPanel"
Height="400"
Width="560"/>
<Border>
<Border.Background>
<AcrylicBrush
BackgroundSource="Backdrop"
TintColor="Gray"
TintOpacity="0.2"/>
</Border.Background>
</Border>
</Grid>
- Add any of the shaders from
samples/ComputeSharp.SwapChain/Shaders
to the project - In
MainWindow.xaml.cs
, add this to the constructor (changing the shader type if needed):
ShaderPanel.ShaderRunner = new ShaderRunner<TwoTiledTruchet>(static (texture, time) => new(texture, (float)time.TotalSeconds));
Expected behavior
The AcrylicBrush
in use should correctly be applied on the entire window content.
Instead, the blur won’t work just over the swap chain (but it will in the rest of the window).
The other acrylic effects will work fine over the swap chain (eg. noise, tint, etc.).
Screenshots
Version Info
Microsoft.ProjectReunion
version0.5.6
Microsoft.ProjectReunion.Foundation
version0.5.6
Microsoft.ProjectReunion.WinUI
version0.5.6
Microsoft.Windows.SDK.NET.Ref
version10.0.18362.16
Windows app type:
UWP | Win32 (WinUI 3 Desktop) |
---|---|
Yes |
Windows 10 version | Saw the problem? |
---|---|
Insider Build (xxxxx) | |
October 2020 Update (19042) | Yes |
May 2020 Update (19041) | |
November 2019 Update (18363) | |
May 2019 Update (18362) | |
October 2018 Update (17763) | |
April 2018 Update (17134) | |
Fall Creators Update (16299) | |
Creators Update (15063) |
Device form factor | Saw the problem? |
---|---|
Desktop | Yes |
Xbox | |
Surface Hub | |
IoT |
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:6 (4 by maintainers)
Top GitHub Comments
The CompositionBackdropBrush in the AcrylicBrush will sample from what the in-proc compositor has drawn up to that point, which will be transparent pixels in the area where the SwapChainPanel. The rest of the AcrylicBrush recipe will then run with that input and draw final pixels.
Notes:
In the case of the AcrylicBrush recipe, it uses the BackdropBrush which (assuming no elements in between) will be fully transparent in the SwapChainPanel area, then it will blur those transparent pixels (which will still be transparent), then the noise gets added which makes the pixels slightly opaque, and finally the tint and luminosity effects will tint and brighten those mostly-transparent pixels to produce a slightly visible effect. I think without the noise layer it would be completely transparent. The blur, of course, does affect the edges of the SwapChainPanel, since it will blend some visible pixels outside the SwapChainPanel into the edges of the SwapChainPanel.
Oh I see, that makes sense. Thank you so much for your time and the detailed explanation @codendone! 😄
@marb2000 I’m going to close this issue since it was a question and that’s been addressed now, I will open a separate one as a proposal and will link this issue from there for future reference as well. This sure would be a neat feature to have in WinUI 3! 🚀