bevyengine / bevy

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

UI components not respecting RenderLayers #6069

Open paulkre opened 2 years ago

paulkre commented 2 years ago

The visibility of UI entities like text is not affected by the RenderLayers component. This is a problem when trying to prerender a scene with RenderTarget::Image to use it as a mesh texture (the game UI will also be visible on the texture).

Is there a way to make UI components respect RenderLayers?

paulkre commented 2 years ago

I modified the render_to_texture example to demonstrate the bug: https://github.com/paulkre/bevy/blob/ui-renderlayers-demo/examples/3d/render_to_texture.rs

https://user-images.githubusercontent.com/13008492/192303297-2b443737-1545-4139-9c97-153149b3a038.mp4

paulkre commented 2 years ago

I just found an acceptable workaround. You can add the UiCameraConfig { show_ui: false } component to your RenderTarget::Image-camera which hides all UI elements for that camera. This helps most of the time but sometimes you might want to render different UI elements in both cameras. In these situations it would be great if RenderLayers worked for UI.

jdm commented 1 year ago

Updated example change that demonstrates the issue:

diff --git a/examples/3d/render_to_texture.rs b/examples/3d/render_to_texture.rs
index 81c687e5a..e4473bcae 100644
--- a/examples/3d/render_to_texture.rs
+++ b/examples/3d/render_to_texture.rs
@@ -35,6 +35,7 @@ fn setup(
     mut meshes: ResMut<Assets<Mesh>>,
     mut materials: ResMut<Assets<StandardMaterial>>,
     mut images: ResMut<Assets<Image>>,
+    asset_server: Res<AssetServer>,
 ) {
     let size = Extent3d {
         width: 512,
@@ -141,6 +142,17 @@ fn setup(
         transform: Transform::from_xyz(0.0, 0.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y),
         ..default()
     });
+
+    commands.spawn((
+        TextBundle::from_section(
+            "hello\nbevy!",
+            TextStyle {
+                font: asset_server.load("fonts/FiraSans-Bold.ttf"),
+                font_size: 200.0,
+                color: Color::RED,
+            },
+        ),
+    ));
 }

 /// Rotates the inner cube (first pass)
musjj commented 10 months ago

Hmmm, when I added UiCameraConfig { show_ui: false } to the camera looking at the rendered image, the UI simply does not get rendered.

Adding it to the camera rendering to the image using RenderTarget simply does nothing. Did anything change in 0.12?

Aunmag commented 7 months ago

Same problem. I use two cameras: one for classic game rendering, and second for rendering onto tile map (decals like blood texures, etc..). But when I spawn a TextBundle it renders to screen (which is ok) and to all my tiles (which is bad).

Here's how I spawn text:

world.spawn(
    TextBundle::from_sections([
        TextSection::new("FPS: ", style.clone()),
        TextSection::from_style(style.clone()),
        TextSection::new("\nEntities: ", style.clone()),
        TextSection::from_style(style.clone()),
        TextSection::new("\nAudio sources: ", style.clone()),
        TextSection::from_style(style.clone()),
        TextSection::new(
            "\n\
            \nSpawn weapon: [G]\
            \nSpawn human : [H] group: [+SHIFT]\
            \nSpawn zombie: [J] group: [+SHIFT]\
            ",
            style,
        ),
    ])
);

Here's how I spawn second camera (for tile map blending):

commands
    .spawn(Camera2dBundle {
        camera: Camera {
            target: RenderTarget::Image(target),
            output_mode: CameraOutputMode::Write {
                blend_state: Some(BlendState::PREMULTIPLIED_ALPHA_BLENDING),
                color_attachment_load_op: LoadOp::Load,
            },
            ..Default::default()
        },
        camera_2d: Camera2d {
            clear_color: ClearColorConfig::None,
        },
        transform,
        ..Default::default()
    })
    .insert(RenderLayers::layer(1)); // NOTE: used different render layer

Screenshot 2024-02-25 125411

But thanks to @paulkre workaround with UiCameraConfig helped!