wgpu-py icon indicating copy to clipboard operation
wgpu-py copied to clipboard

Transparent window example

Open panxinmiao opened this issue 1 month ago • 5 comments

I recently revisited the implementation of transparent windows and noticed that in the wgpu documentation (https://docs.rs/wgpu-types/27.0.1/wgpu_types/instance/struct.Dx12BackendOptions.html ), the D3D12 backend provides a presentation_system option that allows selecting a SwapchainKind. According to the documentation, using DxgiFromVisual enables transparent window support.

However, wgpu-native does not currently expose this configuration and instead always uses DxgiFromHwnd. I modified the wgpu-native code locally and built a customized version (https://github.com/panxinmiao/wgpu-native/tree/Dx12SwapchainKind) for testing, and the transparent window functionality works correctly.

The only issue is that the initial window content leaves a white background artifact. As shown in the video:

https://github.com/user-attachments/assets/95a7b8d9-6f08-47d7-bfc1-9aa99e996f5b

After resizing the window, the newly exposed regions become properly transparent, but the original region (the part not affected by resizing) keeps showing a white background.

It seems like the leftover data comes from the system-provided initial window framebuffer, which is outside the control of wgpu. In the wgpu render loop, each frame performs a clear operation (clear_value = (0, 0, 0, 0)), so in theory the entire surface should be cleared, but the initial white region remains unaffected.

I have not yet found a solution to this issue.

Additionally, we may need to consider adding API support for transparent windows and transparent rendering in RenderCanvas and pygfx.

Relaated: https://github.com/pygfx/rendercanvas/issues/29

panxinmiao avatar Nov 18 '25 09:11 panxinmiao

If someone wants to test it, here is the wgpu_native.dll build that I compiled. wgpu_native-release.zip

panxinmiao avatar Nov 18 '25 09:11 panxinmiao

This is a fun feature, reminds me of shader glass: https://github.com/mausimus/ShaderGlass, not sure how they access the swap chain texture below.

side note: I believe transparent canvas works in pyodide already.. Might try that later.

Vipitis avatar Nov 18 '25 11:11 Vipitis

side note: I believe transparent canvas works in pyodide already.. Might try that later.

If I’m not mistaken, the Pyodide environment likely uses an off-screen style rendering setup, where the actual render target is a custom WGPU texture framebuffer rather than a system surface swapchain texture. As a result, transparency should be supported naturally.

panxinmiao avatar Nov 18 '25 12:11 panxinmiao

If I’m not mistaken, the Pyodide environment likely uses an off-screen style rendering setup

Yeah, it's really just a texture provided by the browser. Which is then composited by the browser with the other content to produce the final browser content. Which is actually stored in a texture, provided by the OS, and which is then composited with the other windows on the desktop, and then rendered to screen :)

almarklein avatar Nov 18 '25 14:11 almarklein

I found that when using borderless mode with:

glfw.window_hint(glfw.DECORATED, False)

the transparent window works perfectly.

https://github.com/user-attachments/assets/7ea07f71-ac31-48f8-80c4-5a2c7331d7cf

However, when the window is decorated, the initial white background issue persists. I’ve tried various approaches, but it seems impossible to resolve so far.

Additionally, it seems that the Qt backend does not support transparent windows. I tried using:

canvas.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True)

Similar to the GLFW case, the initial region shows a white background, but the area after resizing remains non-transparent and appears black instead:

https://github.com/user-attachments/assets/4d8e4279-7eb1-459c-a0f0-7a483f4a8478

And when I add:

canvas.setWindowFlags(QtCore.Qt.FramelessWindowHint)

(which I believe corresponds to glfw.window_hint(glfw.DECORATED, False)),

the application runs but no window content is visible at all.

panxinmiao avatar Nov 19 '25 09:11 panxinmiao