Skip to content

Commit 9133047

Browse files
authored
Move Transmissive3d phase to pbr/transmission (#22706)
# Objective - Further consolidate transmission to pbr ## Solution - Move phase code over ## Testing - transmission example and bistro look fine in deferred and forward etc.
1 parent 0439f55 commit 9133047

File tree

9 files changed

+151
-107
lines changed

9 files changed

+151
-107
lines changed

crates/bevy_core_pipeline/src/core_3d/mod.rs

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ impl Plugin for Core3dPlugin {
153153
render_app
154154
.init_resource::<DrawFunctions<Opaque3d>>()
155155
.init_resource::<DrawFunctions<AlphaMask3d>>()
156-
.init_resource::<DrawFunctions<Transmissive3d>>()
157156
.init_resource::<DrawFunctions<Transparent3d>>()
158157
.init_resource::<DrawFunctions<Opaque3dPrepass>>()
159158
.init_resource::<DrawFunctions<AlphaMask3dPrepass>>()
@@ -165,14 +164,12 @@ impl Plugin for Core3dPlugin {
165164
.init_resource::<ViewBinnedRenderPhases<AlphaMask3dPrepass>>()
166165
.init_resource::<ViewBinnedRenderPhases<Opaque3dDeferred>>()
167166
.init_resource::<ViewBinnedRenderPhases<AlphaMask3dDeferred>>()
168-
.init_resource::<ViewSortedRenderPhases<Transmissive3d>>()
169167
.init_resource::<ViewSortedRenderPhases<Transparent3d>>()
170168
.add_systems(ExtractSchedule, extract_core_3d_camera_phases)
171169
.add_systems(ExtractSchedule, extract_camera_prepass_phase)
172170
.add_systems(
173171
Render,
174172
(
175-
sort_phase_system::<Transmissive3d>.in_set(RenderSystems::PhaseSort),
176173
sort_phase_system::<Transparent3d>.in_set(RenderSystems::PhaseSort),
177174
configure_occlusion_culling_view_targets
178175
.after(prepare_view_targets)
@@ -448,93 +445,6 @@ impl CachedRenderPipelinePhaseItem for AlphaMask3d {
448445
}
449446
}
450447

451-
pub struct Transmissive3d {
452-
pub distance: f32,
453-
pub pipeline: CachedRenderPipelineId,
454-
pub entity: (Entity, MainEntity),
455-
pub draw_function: DrawFunctionId,
456-
pub batch_range: Range<u32>,
457-
pub extra_index: PhaseItemExtraIndex,
458-
/// Whether the mesh in question is indexed (uses an index buffer in
459-
/// addition to its vertex buffer).
460-
pub indexed: bool,
461-
}
462-
463-
impl PhaseItem for Transmissive3d {
464-
/// For now, automatic batching is disabled for transmissive items because their rendering is
465-
/// split into multiple steps depending on `ScreenSpaceTransmission::screen_space_specular_transmission_steps`,
466-
/// which the batching system doesn't currently know about.
467-
///
468-
/// Having batching enabled would cause the same item to be drawn multiple times across different
469-
/// steps, whenever the batching range crossed a step boundary.
470-
///
471-
/// Eventually, we could add support for this by having the batching system break up the batch ranges
472-
/// using the same logic as the transmissive pass, but for now it's simpler to just disable batching.
473-
const AUTOMATIC_BATCHING: bool = false;
474-
475-
#[inline]
476-
fn entity(&self) -> Entity {
477-
self.entity.0
478-
}
479-
480-
#[inline]
481-
fn main_entity(&self) -> MainEntity {
482-
self.entity.1
483-
}
484-
485-
#[inline]
486-
fn draw_function(&self) -> DrawFunctionId {
487-
self.draw_function
488-
}
489-
490-
#[inline]
491-
fn batch_range(&self) -> &Range<u32> {
492-
&self.batch_range
493-
}
494-
495-
#[inline]
496-
fn batch_range_mut(&mut self) -> &mut Range<u32> {
497-
&mut self.batch_range
498-
}
499-
500-
#[inline]
501-
fn extra_index(&self) -> PhaseItemExtraIndex {
502-
self.extra_index.clone()
503-
}
504-
505-
#[inline]
506-
fn batch_range_and_extra_index_mut(&mut self) -> (&mut Range<u32>, &mut PhaseItemExtraIndex) {
507-
(&mut self.batch_range, &mut self.extra_index)
508-
}
509-
}
510-
511-
impl SortedPhaseItem for Transmissive3d {
512-
// NOTE: Values increase towards the camera. Back-to-front ordering for transmissive means we need an ascending sort.
513-
type SortKey = FloatOrd;
514-
515-
#[inline]
516-
fn sort_key(&self) -> Self::SortKey {
517-
FloatOrd(self.distance)
518-
}
519-
520-
#[inline]
521-
fn sort(items: &mut [Self]) {
522-
radsort::sort_by_key(items, |item| item.distance);
523-
}
524-
525-
#[inline]
526-
fn indexed(&self) -> bool {
527-
self.indexed
528-
}
529-
}
530-
531-
impl CachedRenderPipelinePhaseItem for Transmissive3d {
532-
#[inline]
533-
fn cached_pipeline(&self) -> CachedRenderPipelineId {
534-
self.pipeline
535-
}
536-
}
537-
538448
pub struct Transparent3d {
539449
pub distance: f32,
540450
pub pipeline: CachedRenderPipelineId,
@@ -613,7 +523,6 @@ impl CachedRenderPipelinePhaseItem for Transparent3d {
613523
pub fn extract_core_3d_camera_phases(
614524
mut opaque_3d_phases: ResMut<ViewBinnedRenderPhases<Opaque3d>>,
615525
mut alpha_mask_3d_phases: ResMut<ViewBinnedRenderPhases<AlphaMask3d>>,
616-
mut transmissive_3d_phases: ResMut<ViewSortedRenderPhases<Transmissive3d>>,
617526
mut transparent_3d_phases: ResMut<ViewSortedRenderPhases<Transparent3d>>,
618527
cameras_3d: Extract<Query<(Entity, &Camera, Has<NoIndirectDrawing>), With<Camera3d>>>,
619528
mut live_entities: Local<HashSet<RetainedViewEntity>>,
@@ -639,15 +548,13 @@ pub fn extract_core_3d_camera_phases(
639548

640549
opaque_3d_phases.prepare_for_new_frame(retained_view_entity, gpu_preprocessing_mode);
641550
alpha_mask_3d_phases.prepare_for_new_frame(retained_view_entity, gpu_preprocessing_mode);
642-
transmissive_3d_phases.insert_or_clear(retained_view_entity);
643551
transparent_3d_phases.insert_or_clear(retained_view_entity);
644552

645553
live_entities.insert(retained_view_entity);
646554
}
647555

648556
opaque_3d_phases.retain(|view_entity, _| live_entities.contains(view_entity));
649557
alpha_mask_3d_phases.retain(|view_entity, _| live_entities.contains(view_entity));
650-
transmissive_3d_phases.retain(|view_entity, _| live_entities.contains(view_entity));
651558
transparent_3d_phases.retain(|view_entity, _| live_entities.contains(view_entity));
652559
}
653560

@@ -785,7 +692,6 @@ pub fn prepare_core_3d_depth_textures(
785692
render_device: Res<RenderDevice>,
786693
opaque_3d_phases: Res<ViewBinnedRenderPhases<Opaque3d>>,
787694
alpha_mask_3d_phases: Res<ViewBinnedRenderPhases<AlphaMask3d>>,
788-
transmissive_3d_phases: Res<ViewSortedRenderPhases<Transmissive3d>>,
789695
transparent_3d_phases: Res<ViewSortedRenderPhases<Transparent3d>>,
790696
views_3d: Query<(
791697
Entity,
@@ -800,7 +706,6 @@ pub fn prepare_core_3d_depth_textures(
800706
for (_, camera, extracted_view, depth_prepass, camera_3d, _msaa) in &views_3d {
801707
if !opaque_3d_phases.contains_key(&extracted_view.retained_view_entity)
802708
|| !alpha_mask_3d_phases.contains_key(&extracted_view.retained_view_entity)
803-
|| !transmissive_3d_phases.contains_key(&extracted_view.retained_view_entity)
804709
|| !transparent_3d_phases.contains_key(&extracted_view.retained_view_entity)
805710
{
806711
continue;

crates/bevy_pbr/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ itertools = { version = "0.14", optional = true }
7979
bitvec = { version = "1", optional = true }
8080
# direct dependency required for derive macro
8181
bytemuck = { version = "1", features = ["derive", "must_cast"] }
82+
radsort = "0.1"
8283
smallvec = { version = "1", default-features = false }
8384
nonmax = "0.5"
8485
static_assertions = "1"

crates/bevy_pbr/src/material.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ use bevy_camera::visibility::ViewVisibility;
99
use bevy_core_pipeline::deferred::{AlphaMask3dDeferred, Opaque3dDeferred};
1010
use bevy_core_pipeline::prepass::{AlphaMask3dPrepass, Opaque3dPrepass};
1111
use bevy_core_pipeline::{
12-
core_3d::{
13-
AlphaMask3d, Opaque3d, Opaque3dBatchSetKey, Opaque3dBinKey, Transmissive3d, Transparent3d,
14-
},
12+
core_3d::{AlphaMask3d, Opaque3d, Opaque3dBatchSetKey, Opaque3dBinKey, Transparent3d},
1513
prepass::{OpaqueNoLightmap3dBatchSetKey, OpaqueNoLightmap3dBinKey},
1614
tonemapping::Tonemapping,
1715
};
@@ -299,7 +297,6 @@ impl Plugin for MaterialsPlugin {
299297
.init_resource::<RenderMaterialInstances>()
300298
.init_resource::<MaterialBindGroupAllocators>()
301299
.add_render_command::<Shadow, DrawPrepass>()
302-
.add_render_command::<Transmissive3d, DrawMaterial>()
303300
.add_render_command::<Transparent3d, DrawMaterial>()
304301
.add_render_command::<Opaque3d, DrawMaterial>()
305302
.add_render_command::<AlphaMask3d, DrawMaterial>()

crates/bevy_pbr/src/render/mesh.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use bevy_camera::{
1111
Camera, Projection,
1212
};
1313
use bevy_core_pipeline::{
14-
core_3d::{AlphaMask3d, Opaque3d, Transmissive3d, Transparent3d, CORE_3D_DEPTH_FORMAT},
14+
core_3d::{AlphaMask3d, Opaque3d, Transparent3d, CORE_3D_DEPTH_FORMAT},
1515
deferred::{AlphaMask3dDeferred, Opaque3dDeferred},
1616
oit::{prepare_oit_buffers, OrderIndependentTransparencySettingsOffset},
1717
prepass::MotionVectorPrepass,

crates/bevy_pbr/src/transmission/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod node;
2+
mod phase;
23
mod texture;
34

45
use bevy_app::{App, Plugin};
@@ -9,14 +10,18 @@ use bevy_reflect::prelude::*;
910
use bevy_render::{
1011
extract_component::{ExtractComponent, ExtractComponentPlugin},
1112
render_graph::{RenderGraphExt, ViewNodeRunner},
12-
Render, RenderApp, RenderSystems,
13+
render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions, ViewSortedRenderPhases},
14+
ExtractSchedule, Render, RenderApp, RenderSystems,
1315
};
1416
use bevy_shader::load_shader_library;
1517
pub use node::MainTransmissivePass3dNode;
18+
pub use phase::Transmissive3d;
1619
pub use texture::ViewTransmissionTexture;
1720

1821
use texture::prepare_core_3d_transmission_textures;
1922

23+
use crate::DrawMaterial;
24+
2025
/// Enables screen-space transmission for cameras.
2126
pub struct ScreenSpaceTransmissionPlugin;
2227

@@ -32,6 +37,14 @@ impl Plugin for ScreenSpaceTransmissionPlugin {
3237
};
3338

3439
render_app
40+
.init_resource::<DrawFunctions<Transmissive3d>>()
41+
.init_resource::<ViewSortedRenderPhases<Transmissive3d>>()
42+
.add_render_command::<Transmissive3d, DrawMaterial>()
43+
.add_systems(
44+
Render,
45+
sort_phase_system::<Transmissive3d>.in_set(RenderSystems::PhaseSort),
46+
)
47+
.add_systems(ExtractSchedule, phase::extract_transmissive_camera_phases)
3548
.add_systems(
3649
Render,
3750
prepare_core_3d_transmission_textures.in_set(RenderSystems::PrepareResources),

crates/bevy_pbr/src/transmission/node.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use crate::{ScreenSpaceTransmission, ViewTransmissionTexture};
1+
use crate::{ScreenSpaceTransmission, Transmissive3d, ViewTransmissionTexture};
22

33
use bevy_camera::{MainPassResolutionOverride, Viewport};
4-
use bevy_core_pipeline::core_3d::Transmissive3d;
54
use bevy_ecs::{prelude::*, query::QueryItem};
65
use bevy_image::ToExtents;
76
use bevy_render::{
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
use core::ops::Range;
2+
3+
use bevy_camera::{Camera, Camera3d};
4+
use bevy_ecs::{
5+
entity::Entity,
6+
query::With,
7+
system::{Local, Query, ResMut},
8+
};
9+
use bevy_material::{descriptor::CachedRenderPipelineId, labels::DrawFunctionId};
10+
use bevy_math::FloatOrd;
11+
use bevy_platform::collections::HashSet;
12+
use bevy_render::{
13+
render_phase::{
14+
CachedRenderPipelinePhaseItem, PhaseItem, PhaseItemExtraIndex, SortedPhaseItem,
15+
ViewSortedRenderPhases,
16+
},
17+
sync_world::MainEntity,
18+
view::RetainedViewEntity,
19+
Extract,
20+
};
21+
22+
pub struct Transmissive3d {
23+
pub distance: f32,
24+
pub pipeline: CachedRenderPipelineId,
25+
pub entity: (Entity, MainEntity),
26+
pub draw_function: DrawFunctionId,
27+
pub batch_range: Range<u32>,
28+
pub extra_index: PhaseItemExtraIndex,
29+
/// Whether the mesh in question is indexed (uses an index buffer in
30+
/// addition to its vertex buffer).
31+
pub indexed: bool,
32+
}
33+
34+
impl PhaseItem for Transmissive3d {
35+
/// For now, automatic batching is disabled for transmissive items because their rendering is
36+
/// split into multiple steps depending on [`crate::ScreenSpaceTransmission::screen_space_specular_transmission_steps`],
37+
/// which the batching system doesn't currently know about.
38+
///
39+
/// Having batching enabled would cause the same item to be drawn multiple times across different
40+
/// steps, whenever the batching range crossed a step boundary.
41+
///
42+
/// Eventually, we could add support for this by having the batching system break up the batch ranges
43+
/// using the same logic as the transmissive pass, but for now it's simpler to just disable batching.
44+
const AUTOMATIC_BATCHING: bool = false;
45+
46+
#[inline]
47+
fn entity(&self) -> Entity {
48+
self.entity.0
49+
}
50+
51+
#[inline]
52+
fn main_entity(&self) -> MainEntity {
53+
self.entity.1
54+
}
55+
56+
#[inline]
57+
fn draw_function(&self) -> DrawFunctionId {
58+
self.draw_function
59+
}
60+
61+
#[inline]
62+
fn batch_range(&self) -> &Range<u32> {
63+
&self.batch_range
64+
}
65+
66+
#[inline]
67+
fn batch_range_mut(&mut self) -> &mut Range<u32> {
68+
&mut self.batch_range
69+
}
70+
71+
#[inline]
72+
fn extra_index(&self) -> PhaseItemExtraIndex {
73+
self.extra_index.clone()
74+
}
75+
76+
#[inline]
77+
fn batch_range_and_extra_index_mut(&mut self) -> (&mut Range<u32>, &mut PhaseItemExtraIndex) {
78+
(&mut self.batch_range, &mut self.extra_index)
79+
}
80+
}
81+
82+
impl SortedPhaseItem for Transmissive3d {
83+
// NOTE: Values increase towards the camera. Back-to-front ordering for transmissive means we need an ascending sort.
84+
type SortKey = FloatOrd;
85+
86+
#[inline]
87+
fn sort_key(&self) -> Self::SortKey {
88+
FloatOrd(self.distance)
89+
}
90+
91+
#[inline]
92+
fn sort(items: &mut [Self]) {
93+
radsort::sort_by_key(items, |item| item.distance);
94+
}
95+
96+
#[inline]
97+
fn indexed(&self) -> bool {
98+
self.indexed
99+
}
100+
}
101+
102+
impl CachedRenderPipelinePhaseItem for Transmissive3d {
103+
#[inline]
104+
fn cached_pipeline(&self) -> CachedRenderPipelineId {
105+
self.pipeline
106+
}
107+
}
108+
109+
pub fn extract_transmissive_camera_phases(
110+
mut transmissive_3d_phases: ResMut<ViewSortedRenderPhases<Transmissive3d>>,
111+
cameras: Extract<Query<(Entity, &Camera), With<Camera3d>>>,
112+
mut live_entities: Local<HashSet<RetainedViewEntity>>,
113+
) {
114+
live_entities.clear();
115+
116+
for (main_entity, camera) in &cameras {
117+
if !camera.is_active {
118+
continue;
119+
}
120+
121+
// This is the main camera, so use the first subview index (0).
122+
let retained_view_entity = RetainedViewEntity::new(main_entity.into(), None, 0);
123+
124+
transmissive_3d_phases.insert_or_clear(retained_view_entity);
125+
live_entities.insert(retained_view_entity);
126+
}
127+
128+
transmissive_3d_phases.retain(|view_entity, _| live_entities.contains(view_entity));
129+
}

crates/bevy_pbr/src/transmission/texture.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bevy_core_pipeline::core_3d::{AlphaMask3d, Opaque3d, Transmissive3d, Transparent3d};
1+
use bevy_core_pipeline::core_3d::{AlphaMask3d, Opaque3d, Transparent3d};
22
use bevy_ecs::{
33
component::Component,
44
entity::Entity,
@@ -18,7 +18,7 @@ use bevy_render::{
1818
view::{ExtractedView, ViewTarget},
1919
};
2020

21-
use crate::ScreenSpaceTransmission;
21+
use crate::{ScreenSpaceTransmission, Transmissive3d};
2222

2323
#[derive(Component)]
2424
pub struct ViewTransmissionTexture {

0 commit comments

Comments
 (0)