
# Objective `extract_text_shadows` was still using `UiTargetCamera` and `DefaultUiCamera` for UI camera resolution, which no longer always selects the right camera. To see this modify the last lines of the `multiple_windows` example from: ```rust commands.spawn(( Text::new("First window"), node.clone(), // Since we are using multiple cameras, we need to specify which camera UI should be rendered to UiTargetCamera(first_window_camera), )); commands.spawn(( Text::new("Second window"), node, UiTargetCamera(second_window_camera), )); ``` to: ```rust commands .spawn(( node.clone(), // Since we are using multiple cameras, we need to specify which camera UI should be rendered to UiTargetCamera(first_window_camera), )) .with_child((Text::new("First window"), TextShadow::default())); commands .spawn((node, UiTargetCamera(second_window_camera))) .with_child((Text::new("Second window"), TextShadow::default())); ``` which results in the shadow that is meant to be displayed for the "Second Window" label instead being written over the first: <img width="800" alt="first_window_label" src="https://github.com/user-attachments/assets/2eebccba-5749-4064-bb1c-e4f25ff0baf7"> ## Solution Remove the `UiTargetCamera` query and the `default_camera` parameter from `extract_text_shadows` and use `UiCameraMap` with `ComputedNodeTarget` instead. ## Testing The `multiple_windows` example for this PR has been updated to add text shadow to the window labels. You should see that it displays the "Second Window" label's shadow correctly now.
69 lines
2.0 KiB
Rust
69 lines
2.0 KiB
Rust
//! Uses two windows to visualize a 3D model from different angles.
|
|
|
|
use bevy::{prelude::*, render::camera::RenderTarget, window::WindowRef};
|
|
|
|
fn main() {
|
|
App::new()
|
|
// By default, a primary window gets spawned by `WindowPlugin`, contained in `DefaultPlugins`
|
|
.add_plugins(DefaultPlugins)
|
|
.add_systems(Startup, setup_scene)
|
|
.run();
|
|
}
|
|
|
|
fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|
// add entities to the world
|
|
commands.spawn(SceneRoot(
|
|
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/torus/torus.gltf")),
|
|
));
|
|
// light
|
|
commands.spawn((
|
|
DirectionalLight::default(),
|
|
Transform::from_xyz(3.0, 3.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
|
|
));
|
|
|
|
let first_window_camera = commands
|
|
.spawn((
|
|
Camera3d::default(),
|
|
Transform::from_xyz(0.0, 0.0, 6.0).looking_at(Vec3::ZERO, Vec3::Y),
|
|
))
|
|
.id();
|
|
|
|
// Spawn a second window
|
|
let second_window = commands
|
|
.spawn(Window {
|
|
title: "Second window".to_owned(),
|
|
..default()
|
|
})
|
|
.id();
|
|
|
|
let second_window_camera = commands
|
|
.spawn((
|
|
Camera3d::default(),
|
|
Transform::from_xyz(6.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
|
|
Camera {
|
|
target: RenderTarget::Window(WindowRef::Entity(second_window)),
|
|
..default()
|
|
},
|
|
))
|
|
.id();
|
|
|
|
let node = Node {
|
|
position_type: PositionType::Absolute,
|
|
top: Val::Px(12.0),
|
|
left: Val::Px(12.0),
|
|
..default()
|
|
};
|
|
|
|
commands
|
|
.spawn((
|
|
node.clone(),
|
|
// Since we are using multiple cameras, we need to specify which camera UI should be rendered to
|
|
UiTargetCamera(first_window_camera),
|
|
))
|
|
.with_child((Text::new("First window"), TextShadow::default()));
|
|
|
|
commands
|
|
.spawn((node, UiTargetCamera(second_window_camera)))
|
|
.with_child((Text::new("Second window"), TextShadow::default()));
|
|
}
|