Skip to content

Commit f28b921

Browse files
committed
Add "depth_load_op" configuration to 3d Cameras (#4904)
# Objective Users should be able to configure depth load operations on cameras. Currently every camera clears depth when it is rendered. But sometimes later passes need to rely on depth from previous passes. ## Solution This adds the `Camera3d::depth_load_op` field with a new `Camera3dDepthLoadOp` value. This is a custom type because Camera3d uses "reverse-z depth" and this helps us record and document that in a discoverable way. It also gives us more control over reflection + other trait impls, whereas `LoadOp` is owned by the `wgpu` crate. ```rust commands.spawn_bundle(Camera3dBundle { camera_3d: Camera3d { depth_load_op: Camera3dDepthLoadOp::Load, ..default() }, ..default() }); ``` ### two_passes example with the "second pass" camera configured to the default (clear depth to 0.0) ![image](https://user-images.githubusercontent.com/2694663/171743172-46d4fdd5-5090-46ea-abe4-1fbc519f6ee8.png) ### two_passes example with the "second pass" camera configured to "load" the depth ![image](https://user-images.githubusercontent.com/2694663/171743323-74dd9a1d-9c25-4883-98dd-38ca0bed8c17.png) --- ## Changelog ### Added * `Camera3d` now has a `depth_load_op` field, which can configure the Camera's main 3d pass depth loading behavior.
1 parent cbf0324 commit f28b921

File tree

6 files changed

+40
-4
lines changed

6 files changed

+40
-4
lines changed

crates/bevy_core_pipeline/src/core_3d/camera_3d.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,50 @@
11
use crate::clear_color::ClearColorConfig;
22
use bevy_ecs::{prelude::*, query::QueryItem};
3-
use bevy_reflect::Reflect;
3+
use bevy_reflect::{Reflect, ReflectDeserialize};
44
use bevy_render::{
55
camera::{Camera, CameraRenderGraph, Projection},
66
extract_component::ExtractComponent,
77
primitives::Frustum,
8+
render_resource::LoadOp,
89
view::VisibleEntities,
910
};
1011
use bevy_transform::prelude::{GlobalTransform, Transform};
12+
use serde::{Deserialize, Serialize};
1113

12-
#[derive(Component, Default, Reflect, Clone)]
14+
/// Configuration for the "main 3d render graph".
15+
#[derive(Component, Reflect, Clone, Default)]
1316
#[reflect(Component)]
1417
pub struct Camera3d {
18+
/// The clear color operation to perform for the main 3d pass.
1519
pub clear_color: ClearColorConfig,
20+
/// The depth clear operation to perform for the main 3d pass.
21+
pub depth_load_op: Camera3dDepthLoadOp,
22+
}
23+
24+
/// The depth clear operation to perform for the main 3d pass.
25+
#[derive(Reflect, Serialize, Deserialize, Clone, Debug)]
26+
#[reflect_value(Serialize, Deserialize)]
27+
pub enum Camera3dDepthLoadOp {
28+
/// Clear with a specified value.
29+
/// Note that 0.0 is the far plane due to bevy's use of reverse-z projections.
30+
Clear(f32),
31+
/// Load from memory.
32+
Load,
33+
}
34+
35+
impl Default for Camera3dDepthLoadOp {
36+
fn default() -> Self {
37+
Camera3dDepthLoadOp::Clear(0.0)
38+
}
39+
}
40+
41+
impl From<Camera3dDepthLoadOp> for LoadOp<f32> {
42+
fn from(config: Camera3dDepthLoadOp) -> Self {
43+
match config {
44+
Camera3dDepthLoadOp::Clear(x) => LoadOp::Clear(x),
45+
Camera3dDepthLoadOp::Load => LoadOp::Load,
46+
}
47+
}
1648
}
1749

1850
impl ExtractComponent for Camera3d {

crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ impl Node for MainPass3dNode {
8787
view: &depth.view,
8888
// NOTE: The opaque main pass loads the depth buffer and possibly overwrites it
8989
depth_ops: Some(Operations {
90-
// NOTE: 0.0 is the far plane due to bevy's use of reverse-z projections
91-
load: LoadOp::Clear(0.0),
90+
// NOTE: 0.0 is the far plane due to bevy's use of reverse-z projections.
91+
load: camera_3d.depth_load_op.clone().into(),
9292
store: true,
9393
}),
9494
stencil_ops: None,

examples/3d/render_to_texture.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ fn setup(
9595
.spawn_bundle(Camera3dBundle {
9696
camera_3d: Camera3d {
9797
clear_color: ClearColorConfig::Custom(Color::WHITE),
98+
..default()
9899
},
99100
camera: Camera {
100101
// render before the "main pass" camera

examples/3d/split_screen.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ fn setup(
6666
camera_3d: Camera3d {
6767
// dont clear on the second camera because the first camera already cleared the window
6868
clear_color: ClearColorConfig::None,
69+
..default()
6970
},
7071
..default()
7172
})

examples/3d/two_passes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ fn setup(
4949
transform: Transform::from_xyz(10.0, 10., -5.0).looking_at(Vec3::ZERO, Vec3::Y),
5050
camera_3d: Camera3d {
5151
clear_color: ClearColorConfig::None,
52+
..default()
5253
},
5354
camera: Camera {
5455
// renders after / on top of the main camera

examples/shader/post_processing.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ fn setup(
102102
commands.spawn_bundle(Camera3dBundle {
103103
camera_3d: Camera3d {
104104
clear_color: ClearColorConfig::Custom(Color::WHITE),
105+
..default()
105106
},
106107
camera: Camera {
107108
target: RenderTarget::Image(image_handle.clone()),

0 commit comments

Comments
 (0)