Skip to content

Commit daf8e8c

Browse files
committed
Make UiNode render pass respect render layers.
1 parent e931225 commit daf8e8c

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

crates/bevy_render/src/camera/camera.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
prelude::Image,
44
render_asset::RenderAssets,
55
render_resource::TextureView,
6-
view::{ColorGrading, ExtractedView, ExtractedWindows, VisibleEntities},
6+
view::{ColorGrading, ExtractedView, ExtractedWindows, VisibleEntities, RenderLayers},
77
Extract,
88
};
99
use bevy_asset::{AssetEvent, Assets, Handle};
@@ -582,6 +582,7 @@ pub fn extract_cameras(
582582
&VisibleEntities,
583583
Option<&ColorGrading>,
584584
Option<&TemporalJitter>,
585+
Option<&RenderLayers>,
585586
)>,
586587
>,
587588
primary_window: Extract<Query<Entity, With<PrimaryWindow>>>,
@@ -595,6 +596,7 @@ pub fn extract_cameras(
595596
visible_entities,
596597
color_grading,
597598
temporal_jitter,
599+
render_layers,
598600
) in query.iter()
599601
{
600602
let color_grading = *color_grading.unwrap_or(&ColorGrading::default());
@@ -643,6 +645,10 @@ pub fn extract_cameras(
643645
visible_entities.clone(),
644646
));
645647

648+
if let Some(render_layers) = render_layers {
649+
commands.insert(*render_layers);
650+
}
651+
646652
if let Some(temporal_jitter) = temporal_jitter {
647653
commands.insert(temporal_jitter.clone());
648654
}

crates/bevy_ui/src/render/mod.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use bevy_render::{
2424
render_resource::*,
2525
renderer::{RenderDevice, RenderQueue},
2626
texture::Image,
27-
view::{ComputedVisibility, ExtractedView, ViewUniforms},
27+
view::{ComputedVisibility, ExtractedView, ViewUniforms, RenderLayers},
2828
Extract, RenderApp, RenderSet,
2929
};
3030
use bevy_sprite::SpriteAssetEvents;
@@ -155,6 +155,7 @@ pub struct ExtractedUiNode {
155155
pub clip: Option<Rect>,
156156
pub flip_x: bool,
157157
pub flip_y: bool,
158+
pub render_layers: Option<RenderLayers>,
158159
}
159160

160161
#[derive(Resource, Default)]
@@ -174,12 +175,13 @@ pub fn extract_uinodes(
174175
Option<&UiImage>,
175176
&ComputedVisibility,
176177
Option<&CalculatedClip>,
178+
Option<&RenderLayers>,
177179
)>,
178180
>,
179181
) {
180182
extracted_uinodes.uinodes.clear();
181183
for (stack_index, entity) in ui_stack.uinodes.iter().enumerate() {
182-
if let Ok((uinode, transform, color, maybe_image, visibility, clip)) =
184+
if let Ok((uinode, transform, color, maybe_image, visibility, clip, render_layers)) =
183185
uinode_query.get(*entity)
184186
{
185187
// Skip invisible and completely transparent nodes
@@ -210,6 +212,7 @@ pub fn extract_uinodes(
210212
clip: clip.map(|clip| clip.clip),
211213
flip_x,
212214
flip_y,
215+
render_layers: render_layers.cloned(),
213216
});
214217
}
215218
}
@@ -231,9 +234,9 @@ pub struct DefaultCameraView(pub Entity);
231234

232235
pub fn extract_default_ui_camera_view<T: Component>(
233236
mut commands: Commands,
234-
query: Extract<Query<(Entity, &Camera, Option<&UiCameraConfig>), With<T>>>,
237+
query: Extract<Query<(Entity, &Camera, Option<&UiCameraConfig>, Option<&RenderLayers>), With<T>>>,
235238
) {
236-
for (entity, camera, camera_ui) in &query {
239+
for (entity, camera, camera_ui, render_layers) in &query {
237240
// ignore cameras with disabled ui
238241
if matches!(camera_ui, Some(&UiCameraConfig { show_ui: false, .. })) {
239242
continue;
@@ -265,6 +268,9 @@ pub fn extract_default_ui_camera_view<T: Component>(
265268
color_grading: Default::default(),
266269
})
267270
.id();
271+
if let Some(render_layers) = render_layers {
272+
commands.entity(default_camera_view).insert(*render_layers);
273+
}
268274
commands.get_or_spawn(entity).insert((
269275
DefaultCameraView(default_camera_view),
270276
RenderPhase::<TransparentUi>::default(),
@@ -287,6 +293,7 @@ pub fn extract_text_uinodes(
287293
&TextLayoutInfo,
288294
&ComputedVisibility,
289295
Option<&CalculatedClip>,
296+
Option<&RenderLayers>
290297
)>,
291298
>,
292299
) {
@@ -299,7 +306,7 @@ pub fn extract_text_uinodes(
299306
let inverse_scale_factor = scale_factor.recip();
300307

301308
for (stack_index, entity) in ui_stack.uinodes.iter().enumerate() {
302-
if let Ok((uinode, global_transform, text, text_layout_info, visibility, clip)) =
309+
if let Ok((uinode, global_transform, text, text_layout_info, visibility, clip, render_layers)) =
303310
uinode_query.get(*entity)
304311
{
305312
// Skip if not visible or if size is set to zero (e.g. when a parent is set to `Display::None`)
@@ -338,6 +345,7 @@ pub fn extract_text_uinodes(
338345
clip: clip.map(|clip| clip.clip),
339346
flip_x: false,
340347
flip_y: false,
348+
render_layers: render_layers.cloned(),
341349
});
342350
}
343351
}
@@ -381,6 +389,7 @@ pub struct UiBatch {
381389
pub range: Range<u32>,
382390
pub image: Handle<Image>,
383391
pub z: f32,
392+
pub render_layers: Option<RenderLayers>,
384393
}
385394

386395
pub fn prepare_uinodes(
@@ -401,17 +410,22 @@ pub fn prepare_uinodes(
401410
let mut end = 0;
402411
let mut current_batch_handle = Default::default();
403412
let mut last_z = 0.0;
413+
let mut current_render_layers: Option<RenderLayers> = None;
404414
for extracted_uinode in &extracted_uinodes.uinodes {
405-
if current_batch_handle != extracted_uinode.image {
415+
if current_batch_handle != extracted_uinode.image ||
416+
current_render_layers != extracted_uinode.render_layers
417+
{
406418
if start != end {
407419
commands.spawn(UiBatch {
408420
range: start..end,
409421
image: current_batch_handle,
410422
z: last_z,
423+
render_layers: current_render_layers,
411424
});
412425
start = end;
413426
}
414427
current_batch_handle = extracted_uinode.image.clone_weak();
428+
current_render_layers = extracted_uinode.render_layers;
415429
}
416430

417431
let uinode_rect = extracted_uinode.rect;
@@ -521,6 +535,7 @@ pub fn prepare_uinodes(
521535
range: start..end,
522536
image: current_batch_handle,
523537
z: last_z,
538+
render_layers: current_render_layers,
524539
});
525540
}
526541

@@ -544,7 +559,7 @@ pub fn queue_uinodes(
544559
mut image_bind_groups: ResMut<UiImageBindGroups>,
545560
gpu_images: Res<RenderAssets<Image>>,
546561
ui_batches: Query<(Entity, &UiBatch)>,
547-
mut views: Query<(&ExtractedView, &mut RenderPhase<TransparentUi>)>,
562+
mut views: Query<(&ExtractedView, &mut RenderPhase<TransparentUi>, Option<&RenderLayers>)>,
548563
events: Res<SpriteAssetEvents>,
549564
) {
550565
// If an image has changed, the GpuImage has (probably) changed
@@ -567,13 +582,18 @@ pub fn queue_uinodes(
567582
layout: &ui_pipeline.view_layout,
568583
}));
569584
let draw_ui_function = draw_functions.read().id::<DrawUi>();
570-
for (view, mut transparent_phase) in &mut views {
585+
for (view, mut transparent_phase, render_layers) in &mut views {
586+
let view_layers = render_layers.cloned().unwrap_or_default();
571587
let pipeline = pipelines.specialize(
572588
&pipeline_cache,
573589
&ui_pipeline,
574590
UiPipelineKey { hdr: view.hdr },
575591
);
576592
for (entity, batch) in &ui_batches {
593+
let batch_layers = batch.render_layers.unwrap_or_default();
594+
if !view_layers.intersects(&batch_layers) {
595+
continue;
596+
}
577597
image_bind_groups
578598
.values
579599
.entry(batch.image.clone_weak())

0 commit comments

Comments
 (0)