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