Skip to content

Commit 73e8a27

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

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
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, RenderLayers, VisibleEntities},
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: 50 additions & 9 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, RenderLayers, ViewUniforms},
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,19 @@ 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<
238+
Query<
239+
(
240+
Entity,
241+
&Camera,
242+
Option<&UiCameraConfig>,
243+
Option<&RenderLayers>,
244+
),
245+
With<T>,
246+
>,
247+
>,
235248
) {
236-
for (entity, camera, camera_ui) in &query {
249+
for (entity, camera, camera_ui, render_layers) in &query {
237250
// ignore cameras with disabled ui
238251
if matches!(camera_ui, Some(&UiCameraConfig { show_ui: false, .. })) {
239252
continue;
@@ -265,6 +278,9 @@ pub fn extract_default_ui_camera_view<T: Component>(
265278
color_grading: Default::default(),
266279
})
267280
.id();
281+
if let Some(render_layers) = render_layers {
282+
commands.entity(default_camera_view).insert(*render_layers);
283+
}
268284
commands.get_or_spawn(entity).insert((
269285
DefaultCameraView(default_camera_view),
270286
RenderPhase::<TransparentUi>::default(),
@@ -287,6 +303,7 @@ pub fn extract_text_uinodes(
287303
&TextLayoutInfo,
288304
&ComputedVisibility,
289305
Option<&CalculatedClip>,
306+
Option<&RenderLayers>,
290307
)>,
291308
>,
292309
) {
@@ -299,8 +316,15 @@ pub fn extract_text_uinodes(
299316
let inverse_scale_factor = scale_factor.recip();
300317

301318
for (stack_index, entity) in ui_stack.uinodes.iter().enumerate() {
302-
if let Ok((uinode, global_transform, text, text_layout_info, visibility, clip)) =
303-
uinode_query.get(*entity)
319+
if let Ok((
320+
uinode,
321+
global_transform,
322+
text,
323+
text_layout_info,
324+
visibility,
325+
clip,
326+
render_layers,
327+
)) = uinode_query.get(*entity)
304328
{
305329
// Skip if not visible or if size is set to zero (e.g. when a parent is set to `Display::None`)
306330
if !visibility.is_visible() || uinode.size().x == 0. || uinode.size().y == 0. {
@@ -338,6 +362,7 @@ pub fn extract_text_uinodes(
338362
clip: clip.map(|clip| clip.clip),
339363
flip_x: false,
340364
flip_y: false,
365+
render_layers: render_layers.cloned(),
341366
});
342367
}
343368
}
@@ -381,6 +406,7 @@ pub struct UiBatch {
381406
pub range: Range<u32>,
382407
pub image: Handle<Image>,
383408
pub z: f32,
409+
pub render_layers: Option<RenderLayers>,
384410
}
385411

386412
pub fn prepare_uinodes(
@@ -401,17 +427,22 @@ pub fn prepare_uinodes(
401427
let mut end = 0;
402428
let mut current_batch_handle = Default::default();
403429
let mut last_z = 0.0;
430+
let mut current_render_layers: Option<RenderLayers> = None;
404431
for extracted_uinode in &extracted_uinodes.uinodes {
405-
if current_batch_handle != extracted_uinode.image {
432+
if current_batch_handle != extracted_uinode.image
433+
|| current_render_layers != extracted_uinode.render_layers
434+
{
406435
if start != end {
407436
commands.spawn(UiBatch {
408437
range: start..end,
409438
image: current_batch_handle,
410439
z: last_z,
440+
render_layers: current_render_layers,
411441
});
412442
start = end;
413443
}
414444
current_batch_handle = extracted_uinode.image.clone_weak();
445+
current_render_layers = extracted_uinode.render_layers;
415446
}
416447

417448
let uinode_rect = extracted_uinode.rect;
@@ -521,6 +552,7 @@ pub fn prepare_uinodes(
521552
range: start..end,
522553
image: current_batch_handle,
523554
z: last_z,
555+
render_layers: current_render_layers,
524556
});
525557
}
526558

@@ -544,7 +576,11 @@ pub fn queue_uinodes(
544576
mut image_bind_groups: ResMut<UiImageBindGroups>,
545577
gpu_images: Res<RenderAssets<Image>>,
546578
ui_batches: Query<(Entity, &UiBatch)>,
547-
mut views: Query<(&ExtractedView, &mut RenderPhase<TransparentUi>)>,
579+
mut views: Query<(
580+
&ExtractedView,
581+
&mut RenderPhase<TransparentUi>,
582+
Option<&RenderLayers>,
583+
)>,
548584
events: Res<SpriteAssetEvents>,
549585
) {
550586
// If an image has changed, the GpuImage has (probably) changed
@@ -567,13 +603,18 @@ pub fn queue_uinodes(
567603
layout: &ui_pipeline.view_layout,
568604
}));
569605
let draw_ui_function = draw_functions.read().id::<DrawUi>();
570-
for (view, mut transparent_phase) in &mut views {
606+
for (view, mut transparent_phase, render_layers) in &mut views {
607+
let view_layers = render_layers.cloned().unwrap_or_default();
571608
let pipeline = pipelines.specialize(
572609
&pipeline_cache,
573610
&ui_pipeline,
574611
UiPipelineKey { hdr: view.hdr },
575612
);
576613
for (entity, batch) in &ui_batches {
614+
let batch_layers = batch.render_layers.unwrap_or_default();
615+
if !view_layers.intersects(&batch_layers) {
616+
continue;
617+
}
577618
image_bind_groups
578619
.values
579620
.entry(batch.image.clone_weak())

0 commit comments

Comments
 (0)