bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
33.84k stars 3.3k forks source link

Bevy Transparent Window not working #10929

Open Maufeat opened 7 months ago

Maufeat commented 7 months ago

Bevy version

0.12.1

What you did

Running the "transparent_window" example.

What went wrong

Window is not transparent.

Additional information

Screenshot 2023-12-10 193840

alice-i-cecile commented 6 months ago

What OS are you on? Can you reproduce this on main following the winit 0.29 update?

Maufeat commented 6 months ago

What OS are you on? Can you reproduce this on main following the winit 0.29 update?

Thanks for the reply. I am on Windows 11 Home. I have quickly downloaded the recent Bevy main-branch, but the same result here.

grafik

Maufeat commented 6 months ago

Looks like this is the issue from winit: https://github.com/rust-windowing/winit/issues/2960

irate-devil commented 6 months ago

https://github.com/rust-windowing/winit/issues/2960 shouldn't affect us. It only affects winit's own examples

Can confirm transparency is broken on main with Windows 10. I remember it working at some point.

irate-devil commented 6 months ago

Appears to be an issue with wgpu not correctly detecting surface capabilities. SurfaceCapabilities::alpha_modes only contains Opaque on my machine, Windows 10, nvidia gpu.

mockersf commented 6 months ago

transparent windows work on main on macos

irate-devil commented 6 months ago

Broken on Wayland as well, but working on X11 natively and via XWayland.

TeamDman commented 6 months ago

This discussion https://github.com/bevyengine/bevy/discussions/9696#discussioncomment-6920260 points to this PR https://github.com/rust-windowing/winit/pull/2895 and searching that repo for open PRs on transparency leads to this open PR https://github.com/rust-windowing/winit/pull/2503 which attempts to fix the winit transparency example but it just makes everything transparent not just the background

There's also this issue https://github.com/gfx-rs/wgpu/issues/3486 which may be relevant

torsteingrindvik commented 3 months ago

I had this problem on XFCE and I was debugging it within winit since their example didn't work for me either.

Turns out my problem was very simple... I had disabled my compositor. So in my case I just had to run the OS's Window Manager Tweaks program and enable display compositing.

rydb commented 2 months ago

I'm facing a similar issue running this example and getting window transparency on linux as well.

I've tried x11, wayland, and I tried switching from gnome to KDE, and I still can't get transparency to work.

minimizing transparency to just:

        app
        .add_plugins(DefaultPlugins
        .set(
            WindowPlugin {
                primary_window: Some(
                    Window {
                        transparent: true,
                        composite_alpha_mode: bevy::window::CompositeAlphaMode::PostMultiplied,
                        ..default()
                    }
                ),
                ..default()
            }
        )

causes an error:

thread 'main' panicked at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-0.19.3/src/backend/wgpu_core.rs:724:18:
Error in Surface::configure: Validation Error

Caused by:
    Requested alpha mode PostMultiplied is not in the list of supported alpha modes: [Opaque]

I've also tried setting the backend target to vulkan, and the issue still persists.

richchurcher commented 2 months ago

@rydb Purely by trial and error, I discovered that (on Wayland at least) setting mode to PreMultiplied is the secret sauce, otherwise I could only get X11 working.

rydb commented 2 months ago

@rydb Purely by trial and error, I discovered that (on Wayland at least) setting mode to PreMultiplied is the secret sauce, otherwise I could only get X11 working.

the problem I have is that is not selectable either. its Opaque only on my end.

Lightnet commented 1 month ago

I got the same bug for windows 10 64bit. Use the same file from https://github.com/bevyengine/bevy/blob/main/examples/window/transparent_window.rs as well with the https://github.com/bevyengine/bevy/blob/main/examples/window/multiple_windows.rs

The first window fail to do transparent. Second window works. Just trying see what wrong. I did look at the youtube video example that was months ago. https://www.youtube.com/watch?v=Sljhkwu3WDo

0.13.2

use bevy::{prelude::*, render::camera::RenderTarget, window::{CompositeAlphaMode, WindowRef}};
#[cfg(target_os = "macos")]
use bevy::window::CompositeAlphaMode;

fn main() {
    App::new()
        .insert_resource(ClearColor(Color::NONE))
        //.insert_resource(ClearColor(Color::Rgba {red: 0.0, green:0.0, blue: 100.0, alpha: 255.0 }))
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                // Setting `transparent` allows the `ClearColor`'s alpha value to take effect
                transparent: true,
                // Disabling window decorations to make it feel more like a widget than a window
                //decorations: false,
                window_level: bevy::window::WindowLevel::AlwaysOnTop,
                composite_alpha_mode: CompositeAlphaMode::Auto,
                #[cfg(target_os = "macos")]
                composite_alpha_mode: CompositeAlphaMode::PostMultiplied,
                ..default()
            }),
            ..default()
        }))
        // ClearColor must have 0 alpha, otherwise some color will bleed through

        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    //commands.spawn(Camera2dBundle::default());
    let first_window_camera = commands.spawn(Camera2dBundle {
      // camera:Camera {
      //   //clear_color: Color::Rgba {red: 0.0, green:0.0, blue: 0.0, alpha: 255.0 },
      //   //clear_color: ClearColorConfig::None,
      //   //clear_color: ClearColorConfig::Custom(Color::rgba(0.0, 0.0, 0.0, 255.0)),
      //   ..Default::default()
      // },
      ..Default::default()
    }).id();

    commands.spawn(SpriteBundle {
        texture: asset_server.load("branding/icon.png"),
        ..default()
    });

    // Spawn a second window
    let second_window = commands
        .spawn(Window {
            title: "Second window".to_owned(),
            transparent: true,
            composite_alpha_mode: CompositeAlphaMode::Auto,
            ..default()
        })
        .id();

    let second_window_camera = commands
    .spawn(Camera3dBundle {
        transform: Transform::from_xyz(6.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
        camera: Camera {
            target: RenderTarget::Window(WindowRef::Entity(second_window)),
            ..default()
        },
        ..default()
    })
    .id();

   // Since we are using multiple cameras, we need to specify which camera UI should be rendered to
   commands
   .spawn((NodeBundle::default(), TargetCamera(first_window_camera)))
   .with_children(|parent| {
       parent.spawn(TextBundle::from_section(
           "First window",
           TextStyle::default(),
       ));
   });

    commands
    .spawn((NodeBundle::default(), TargetCamera(second_window_camera)))
    .with_children(|parent| {
        parent.spawn(TextBundle::from_section(
            "Second window",
            TextStyle::default(),
        ));
    });

}

I wonder how DefaultPlugins and entity commands.spawn window any different setup?