Skip to main content

bevy_post_process/auto_exposure/
settings.rs

1use core::ops::RangeInclusive;
2
3use super::compensation_curve::AutoExposureCompensationCurve;
4use bevy_asset::Handle;
5use bevy_camera::Hdr;
6use bevy_ecs::{prelude::Component, reflect::ReflectComponent};
7use bevy_image::Image;
8use bevy_reflect::{std_traits::ReflectDefault, Reflect};
9use bevy_render::{extract_component::ExtractComponent, RenderApp};
10use bevy_utils::default;
11
12/// Component that enables auto exposure for an HDR-enabled 2d or 3d camera.
13///
14/// Auto exposure adjusts the exposure of the camera automatically to
15/// simulate the human eye's ability to adapt to different lighting conditions.
16///
17/// Bevy's implementation builds a 64 bin histogram of the scene's luminance,
18/// and then adjusts the exposure so that the average brightness of the final
19/// render will be middle gray. Because it's using a histogram, some details can
20/// be selectively ignored or emphasized. Outliers like shadows and specular
21/// highlights can be ignored, and certain areas can be given more (or less)
22/// weight based on a mask.
23///
24/// # Usage Notes
25///
26/// **Auto Exposure requires compute shaders and is not compatible with WebGL2.**
27#[derive(Component, Clone, Reflect, ExtractComponent)]
28#[reflect(Component, Default, Clone)]
29#[require(Hdr)]
30#[extract_app(RenderApp)]
31pub struct AutoExposure {
32    /// The range of exposure values for the histogram.
33    ///
34    /// Pixel values below this range will be ignored, and pixel values above this range will be
35    /// clamped in the sense that they will count towards the highest bin in the histogram.
36    /// The default value is `-8.0..=8.0`.
37    pub range: RangeInclusive<f32>,
38
39    /// The portion of the histogram to consider when metering.
40    ///
41    /// By default, the darkest 10% and the brightest 10% of samples are ignored,
42    /// so the default value is `0.10..=0.90`.
43    pub filter: RangeInclusive<f32>,
44
45    /// The speed at which the exposure adapts from dark to bright scenes, in F-stops per second.
46    pub speed_brighten: f32,
47
48    /// The speed at which the exposure adapts from bright to dark scenes, in F-stops per second.
49    pub speed_darken: f32,
50
51    /// The distance in F-stops from the target exposure from where to transition from animating
52    /// in linear fashion to animating exponentially. This helps against jittering when the
53    /// target exposure keeps on changing slightly from frame to frame, while still maintaining
54    /// a relatively slow animation for big changes in scene brightness.
55    ///
56    /// ```text
57    /// ev
58    ///                       ➔●┐
59    /// |              ⬈         ├ exponential section
60    /// │        ⬈               ┘
61    /// │    ⬈                   ┐
62    /// │  ⬈                     ├ linear section
63    /// │⬈                       ┘
64    /// ●───────────────────────── time
65    /// ```
66    ///
67    /// The default value is 1.5.
68    pub exponential_transition_distance: f32,
69
70    /// The mask to apply when metering. The mask will cover the entire screen, where:
71    /// * `(0.0, 0.0)` is the top-left corner,
72    /// * `(1.0, 1.0)` is the bottom-right corner.
73    ///
74    /// Only the red channel of the texture is used.
75    /// The sample at the current screen position will be used to weight the contribution
76    /// of each pixel to the histogram:
77    /// * 0.0 means the pixel will not contribute to the histogram,
78    /// * 1.0 means the pixel will contribute fully to the histogram.
79    ///
80    /// The default value is a white image, so all pixels contribute equally.
81    ///
82    /// # Usage Notes
83    ///
84    /// The mask is quantized to 16 discrete levels because of limitations in the compute shader
85    /// implementation.
86    pub metering_mask: Handle<Image>,
87
88    /// Exposure compensation curve to apply after metering.
89    /// The default value is a flat line at 0.0.
90    /// For more information, see [`AutoExposureCompensationCurve`].
91    pub compensation_curve: Handle<AutoExposureCompensationCurve>,
92}
93
94impl Default for AutoExposure {
95    fn default() -> Self {
96        Self {
97            range: -8.0..=8.0,
98            filter: 0.10..=0.90,
99            speed_brighten: 3.0,
100            speed_darken: 1.0,
101            exponential_transition_distance: 1.5,
102            metering_mask: default(),
103            compensation_curve: default(),
104        }
105    }
106}