bevy_core_pipeline/core_3d/
camera_3d.rs

1use crate::{
2    core_3d::graph::Core3d,
3    tonemapping::{DebandDither, Tonemapping},
4};
5use bevy_ecs::prelude::*;
6use bevy_reflect::{std_traits::ReflectDefault, Reflect, ReflectDeserialize, ReflectSerialize};
7use bevy_render::{
8    camera::{Camera, CameraRenderGraph, Exposure, Projection},
9    extract_component::ExtractComponent,
10    render_resource::{LoadOp, TextureUsages},
11    view::ColorGrading,
12};
13use serde::{Deserialize, Serialize};
14
15/// A 3D camera component. Enables the main 3D render graph for a [`Camera`].
16///
17/// The camera coordinate space is right-handed X-right, Y-up, Z-back.
18/// This means "forward" is -Z.
19#[derive(Component, Reflect, Clone, ExtractComponent)]
20#[extract_component_filter(With<Camera>)]
21#[reflect(Component, Default, Clone)]
22#[require(
23    Camera,
24    DebandDither::Enabled,
25    CameraRenderGraph::new(Core3d),
26    Projection,
27    Tonemapping,
28    ColorGrading,
29    Exposure
30)]
31pub struct Camera3d {
32    /// The depth clear operation to perform for the main 3d pass.
33    pub depth_load_op: Camera3dDepthLoadOp,
34    /// The texture usages for the depth texture created for the main 3d pass.
35    pub depth_texture_usages: Camera3dDepthTextureUsage,
36    /// How many individual steps should be performed in the [`Transmissive3d`](crate::core_3d::Transmissive3d) pass.
37    ///
38    /// Roughly corresponds to how many “layers of transparency” are rendered for screen space
39    /// specular transmissive objects. Each step requires making one additional
40    /// texture copy, so it's recommended to keep this number to a reasonably low value. Defaults to `1`.
41    ///
42    /// ### Notes
43    ///
44    /// - No copies will be performed if there are no transmissive materials currently being rendered,
45    ///   regardless of this setting.
46    /// - Setting this to `0` disables the screen-space refraction effect entirely, and falls
47    ///   back to refracting only the environment map light's texture.
48    /// - If set to more than `0`, any opaque [`clear_color`](Camera::clear_color) will obscure the environment
49    ///   map light's texture, preventing it from being visible “through” transmissive materials. If you'd like
50    ///   to still have the environment map show up in your refractions, you can set the clear color's alpha to `0.0`.
51    ///   Keep in mind that depending on the platform and your window settings, this may cause the window to become
52    ///   transparent.
53    pub screen_space_specular_transmission_steps: usize,
54    /// The quality of the screen space specular transmission blur effect, applied to whatever's “behind” transmissive
55    /// objects when their `roughness` is greater than `0.0`.
56    ///
57    /// Higher qualities are more GPU-intensive.
58    ///
59    /// **Note:** You can get better-looking results at any quality level by enabling TAA. See: [`TemporalAntiAliasPlugin`](crate::experimental::taa::TemporalAntiAliasPlugin).
60    pub screen_space_specular_transmission_quality: ScreenSpaceTransmissionQuality,
61}
62
63impl Default for Camera3d {
64    fn default() -> Self {
65        Self {
66            depth_load_op: Default::default(),
67            depth_texture_usages: TextureUsages::RENDER_ATTACHMENT.into(),
68            screen_space_specular_transmission_steps: 1,
69            screen_space_specular_transmission_quality: Default::default(),
70        }
71    }
72}
73
74#[derive(Clone, Copy, Reflect, Serialize, Deserialize)]
75#[reflect(Serialize, Deserialize, Clone)]
76pub struct Camera3dDepthTextureUsage(pub u32);
77
78impl From<TextureUsages> for Camera3dDepthTextureUsage {
79    fn from(value: TextureUsages) -> Self {
80        Self(value.bits())
81    }
82}
83impl From<Camera3dDepthTextureUsage> for TextureUsages {
84    fn from(value: Camera3dDepthTextureUsage) -> Self {
85        Self::from_bits_truncate(value.0)
86    }
87}
88
89/// The depth clear operation to perform for the main 3d pass.
90#[derive(Reflect, Serialize, Deserialize, Clone, Debug)]
91#[reflect(Serialize, Deserialize, Clone, Default)]
92pub enum Camera3dDepthLoadOp {
93    /// Clear with a specified value.
94    /// Note that 0.0 is the far plane due to bevy's use of reverse-z projections.
95    Clear(f32),
96    /// Load from memory.
97    Load,
98}
99
100impl Default for Camera3dDepthLoadOp {
101    fn default() -> Self {
102        Camera3dDepthLoadOp::Clear(0.0)
103    }
104}
105
106impl From<Camera3dDepthLoadOp> for LoadOp<f32> {
107    fn from(config: Camera3dDepthLoadOp) -> Self {
108        match config {
109            Camera3dDepthLoadOp::Clear(x) => LoadOp::Clear(x),
110            Camera3dDepthLoadOp::Load => LoadOp::Load,
111        }
112    }
113}
114
115/// The quality of the screen space transmission blur effect, applied to whatever's “behind” transmissive
116/// objects when their `roughness` is greater than `0.0`.
117///
118/// Higher qualities are more GPU-intensive.
119///
120/// **Note:** You can get better-looking results at any quality level by enabling TAA. See: [`TemporalAntiAliasPlugin`](crate::experimental::taa::TemporalAntiAliasPlugin).
121#[derive(Resource, Default, Clone, Copy, Reflect, PartialEq, PartialOrd, Debug)]
122#[reflect(Resource, Default, Clone, Debug, PartialEq)]
123pub enum ScreenSpaceTransmissionQuality {
124    /// Best performance at the cost of quality. Suitable for lower end GPUs. (e.g. Mobile)
125    ///
126    /// `num_taps` = 4
127    Low,
128
129    /// A balanced option between quality and performance.
130    ///
131    /// `num_taps` = 8
132    #[default]
133    Medium,
134
135    /// Better quality. Suitable for high end GPUs. (e.g. Desktop)
136    ///
137    /// `num_taps` = 16
138    High,
139
140    /// The highest quality, suitable for non-realtime rendering. (e.g. Pre-rendered cinematics and photo mode)
141    ///
142    /// `num_taps` = 32
143    Ultra,
144}