bevy_core_pipeline/core_3d/
camera_3d.rs

1#![expect(deprecated)]
2
3use crate::{
4    core_3d::graph::Core3d,
5    tonemapping::{DebandDither, Tonemapping},
6};
7use bevy_ecs::prelude::*;
8use bevy_reflect::{std_traits::ReflectDefault, Reflect, ReflectDeserialize, ReflectSerialize};
9use bevy_render::{
10    camera::{Camera, CameraMainTextureUsages, CameraRenderGraph, Exposure, Projection},
11    extract_component::ExtractComponent,
12    primitives::Frustum,
13    render_resource::{LoadOp, TextureUsages},
14    sync_world::SyncToRenderWorld,
15    view::{ColorGrading, Msaa, VisibleEntities},
16};
17use bevy_transform::prelude::{GlobalTransform, Transform};
18use serde::{Deserialize, Serialize};
19
20/// A 3D camera component. Enables the main 3D render graph for a [`Camera`].
21///
22/// The camera coordinate space is right-handed X-right, Y-up, Z-back.
23/// This means "forward" is -Z.
24#[derive(Component, Reflect, Clone, ExtractComponent)]
25#[extract_component_filter(With<Camera>)]
26#[reflect(Component, Default)]
27#[require(
28    Camera,
29    DebandDither(|| DebandDither::Enabled),
30    CameraRenderGraph(|| CameraRenderGraph::new(Core3d)),
31    Projection,
32    Tonemapping,
33    ColorGrading,
34    Exposure
35)]
36pub struct Camera3d {
37    /// The depth clear operation to perform for the main 3d pass.
38    pub depth_load_op: Camera3dDepthLoadOp,
39    /// The texture usages for the depth texture created for the main 3d pass.
40    pub depth_texture_usages: Camera3dDepthTextureUsage,
41    /// How many individual steps should be performed in the [`Transmissive3d`](crate::core_3d::Transmissive3d) pass.
42    ///
43    /// Roughly corresponds to how many “layers of transparency” are rendered for screen space
44    /// specular transmissive objects. Each step requires making one additional
45    /// texture copy, so it's recommended to keep this number to a resonably low value. Defaults to `1`.
46    ///
47    /// ### Notes
48    ///
49    /// - No copies will be performed if there are no transmissive materials currently being rendered,
50    ///   regardless of this setting.
51    /// - Setting this to `0` disables the screen-space refraction effect entirely, and falls
52    ///   back to refracting only the environment map light's texture.
53    /// - If set to more than `0`, any opaque [`clear_color`](Camera::clear_color) will obscure the environment
54    ///   map light's texture, preventing it from being visible “through” transmissive materials. If you'd like
55    ///   to still have the environment map show up in your refractions, you can set the clear color's alpha to `0.0`.
56    ///   Keep in mind that depending on the platform and your window settings, this may cause the window to become
57    ///   transparent.
58    pub screen_space_specular_transmission_steps: usize,
59    /// The quality of the screen space specular transmission blur effect, applied to whatever's “behind” transmissive
60    /// objects when their `roughness` is greater than `0.0`.
61    ///
62    /// Higher qualities are more GPU-intensive.
63    ///
64    /// **Note:** You can get better-looking results at any quality level by enabling TAA. See: [`TemporalAntiAliasPlugin`](crate::experimental::taa::TemporalAntiAliasPlugin).
65    pub screen_space_specular_transmission_quality: ScreenSpaceTransmissionQuality,
66}
67
68impl Default for Camera3d {
69    fn default() -> Self {
70        Self {
71            depth_load_op: Default::default(),
72            depth_texture_usages: TextureUsages::RENDER_ATTACHMENT.into(),
73            screen_space_specular_transmission_steps: 1,
74            screen_space_specular_transmission_quality: Default::default(),
75        }
76    }
77}
78
79#[derive(Clone, Copy, Reflect, Serialize, Deserialize)]
80#[reflect(Serialize, Deserialize)]
81pub struct Camera3dDepthTextureUsage(pub u32);
82
83impl From<TextureUsages> for Camera3dDepthTextureUsage {
84    fn from(value: TextureUsages) -> Self {
85        Self(value.bits())
86    }
87}
88impl From<Camera3dDepthTextureUsage> for TextureUsages {
89    fn from(value: Camera3dDepthTextureUsage) -> Self {
90        Self::from_bits_truncate(value.0)
91    }
92}
93
94/// The depth clear operation to perform for the main 3d pass.
95#[derive(Reflect, Serialize, Deserialize, Clone, Debug)]
96#[reflect(Serialize, Deserialize)]
97pub enum Camera3dDepthLoadOp {
98    /// Clear with a specified value.
99    /// Note that 0.0 is the far plane due to bevy's use of reverse-z projections.
100    Clear(f32),
101    /// Load from memory.
102    Load,
103}
104
105impl Default for Camera3dDepthLoadOp {
106    fn default() -> Self {
107        Camera3dDepthLoadOp::Clear(0.0)
108    }
109}
110
111impl From<Camera3dDepthLoadOp> for LoadOp<f32> {
112    fn from(config: Camera3dDepthLoadOp) -> Self {
113        match config {
114            Camera3dDepthLoadOp::Clear(x) => LoadOp::Clear(x),
115            Camera3dDepthLoadOp::Load => LoadOp::Load,
116        }
117    }
118}
119
120/// The quality of the screen space transmission blur effect, applied to whatever's “behind” transmissive
121/// objects when their `roughness` is greater than `0.0`.
122///
123/// Higher qualities are more GPU-intensive.
124///
125/// **Note:** You can get better-looking results at any quality level by enabling TAA. See: [`TemporalAntiAliasPlugin`](crate::experimental::taa::TemporalAntiAliasPlugin).
126#[derive(Resource, Default, Clone, Copy, Reflect, PartialEq, PartialOrd, Debug)]
127#[reflect(Resource, Default, Debug, PartialEq)]
128pub enum ScreenSpaceTransmissionQuality {
129    /// Best performance at the cost of quality. Suitable for lower end GPUs. (e.g. Mobile)
130    ///
131    /// `num_taps` = 4
132    Low,
133
134    /// A balanced option between quality and performance.
135    ///
136    /// `num_taps` = 8
137    #[default]
138    Medium,
139
140    /// Better quality. Suitable for high end GPUs. (e.g. Desktop)
141    ///
142    /// `num_taps` = 16
143    High,
144
145    /// The highest quality, suitable for non-realtime rendering. (e.g. Pre-rendered cinematics and photo mode)
146    ///
147    /// `num_taps` = 32
148    Ultra,
149}
150
151/// The camera coordinate space is right-handed x-right, y-up, z-back.
152/// This means "forward" is -Z.
153#[derive(Bundle, Clone)]
154#[deprecated(
155    since = "0.15.0",
156    note = "Use the `Camera3d` component instead. Inserting it will now also insert the other components required by it automatically."
157)]
158pub struct Camera3dBundle {
159    pub camera: Camera,
160    pub camera_render_graph: CameraRenderGraph,
161    pub projection: Projection,
162    pub visible_entities: VisibleEntities,
163    pub frustum: Frustum,
164    pub transform: Transform,
165    pub global_transform: GlobalTransform,
166    pub camera_3d: Camera3d,
167    pub tonemapping: Tonemapping,
168    pub deband_dither: DebandDither,
169    pub color_grading: ColorGrading,
170    pub exposure: Exposure,
171    pub main_texture_usages: CameraMainTextureUsages,
172    pub msaa: Msaa,
173    /// Marker component that indicates that its entity needs to be synchronized to the render world
174    pub sync: SyncToRenderWorld,
175}
176
177// NOTE: ideally Perspective and Orthographic defaults can share the same impl, but sadly it breaks rust's type inference
178impl Default for Camera3dBundle {
179    fn default() -> Self {
180        Self {
181            camera_render_graph: CameraRenderGraph::new(Core3d),
182            camera: Default::default(),
183            projection: Default::default(),
184            visible_entities: Default::default(),
185            frustum: Default::default(),
186            transform: Default::default(),
187            global_transform: Default::default(),
188            camera_3d: Default::default(),
189            tonemapping: Default::default(),
190            color_grading: Default::default(),
191            exposure: Default::default(),
192            main_texture_usages: Default::default(),
193            deband_dither: DebandDither::Enabled,
194            msaa: Default::default(),
195            sync: Default::default(),
196        }
197    }
198}