diff --git a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs b/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs index a04a3df38d..a9bc38464f 100644 --- a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs +++ b/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs @@ -1,18 +1,50 @@ use crate::clear_color::ClearColorConfig; use bevy_ecs::{prelude::*, query::QueryItem}; -use bevy_reflect::Reflect; +use bevy_reflect::{Reflect, ReflectDeserialize}; use bevy_render::{ camera::{Camera, CameraRenderGraph, Projection}, extract_component::ExtractComponent, primitives::Frustum, + render_resource::LoadOp, view::VisibleEntities, }; use bevy_transform::prelude::{GlobalTransform, Transform}; +use serde::{Deserialize, Serialize}; -#[derive(Component, Default, Reflect, Clone)] +/// Configuration for the "main 3d render graph". +#[derive(Component, Reflect, Clone, Default)] #[reflect(Component)] pub struct Camera3d { + /// The clear color operation to perform for the main 3d pass. pub clear_color: ClearColorConfig, + /// The depth clear operation to perform for the main 3d pass. + pub depth_load_op: Camera3dDepthLoadOp, +} + +/// The depth clear operation to perform for the main 3d pass. +#[derive(Reflect, Serialize, Deserialize, Clone, Debug)] +#[reflect_value(Serialize, Deserialize)] +pub enum Camera3dDepthLoadOp { + /// Clear with a specified value. + /// Note that 0.0 is the far plane due to bevy's use of reverse-z projections. + Clear(f32), + /// Load from memory. + Load, +} + +impl Default for Camera3dDepthLoadOp { + fn default() -> Self { + Camera3dDepthLoadOp::Clear(0.0) + } +} + +impl From for LoadOp { + fn from(config: Camera3dDepthLoadOp) -> Self { + match config { + Camera3dDepthLoadOp::Clear(x) => LoadOp::Clear(x), + Camera3dDepthLoadOp::Load => LoadOp::Load, + } + } } impl ExtractComponent for Camera3d { diff --git a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs index 9e1de353b7..1521e230a9 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs @@ -87,8 +87,8 @@ impl Node for MainPass3dNode { view: &depth.view, // NOTE: The opaque main pass loads the depth buffer and possibly overwrites it depth_ops: Some(Operations { - // NOTE: 0.0 is the far plane due to bevy's use of reverse-z projections - load: LoadOp::Clear(0.0), + // NOTE: 0.0 is the far plane due to bevy's use of reverse-z projections. + load: camera_3d.depth_load_op.clone().into(), store: true, }), stencil_ops: None, diff --git a/examples/3d/render_to_texture.rs b/examples/3d/render_to_texture.rs index 76a88a2935..f9179d49b9 100644 --- a/examples/3d/render_to_texture.rs +++ b/examples/3d/render_to_texture.rs @@ -95,6 +95,7 @@ fn setup( .spawn_bundle(Camera3dBundle { camera_3d: Camera3d { clear_color: ClearColorConfig::Custom(Color::WHITE), + ..default() }, camera: Camera { // render before the "main pass" camera diff --git a/examples/3d/split_screen.rs b/examples/3d/split_screen.rs index b296f170dd..1b0992c84b 100644 --- a/examples/3d/split_screen.rs +++ b/examples/3d/split_screen.rs @@ -66,6 +66,7 @@ fn setup( camera_3d: Camera3d { // dont clear on the second camera because the first camera already cleared the window clear_color: ClearColorConfig::None, + ..default() }, ..default() }) diff --git a/examples/3d/two_passes.rs b/examples/3d/two_passes.rs index 1937a55581..af83417a12 100644 --- a/examples/3d/two_passes.rs +++ b/examples/3d/two_passes.rs @@ -49,6 +49,7 @@ fn setup( transform: Transform::from_xyz(10.0, 10., -5.0).looking_at(Vec3::ZERO, Vec3::Y), camera_3d: Camera3d { clear_color: ClearColorConfig::None, + ..default() }, camera: Camera { // renders after / on top of the main camera diff --git a/examples/shader/post_processing.rs b/examples/shader/post_processing.rs index 14ec05ba77..e0e8a1608c 100644 --- a/examples/shader/post_processing.rs +++ b/examples/shader/post_processing.rs @@ -102,6 +102,7 @@ fn setup( commands.spawn_bundle(Camera3dBundle { camera_3d: Camera3d { clear_color: ClearColorConfig::Custom(Color::WHITE), + ..default() }, camera: Camera { target: RenderTarget::Image(image_handle.clone()),