Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_post_process/src/auto_exposure/buffers.rs
6596 views
1
use bevy_ecs::prelude::*;
2
use bevy_platform::collections::{hash_map::Entry, HashMap};
3
use bevy_render::{
4
render_resource::{StorageBuffer, UniformBuffer},
5
renderer::{RenderDevice, RenderQueue},
6
sync_world::RenderEntity,
7
Extract,
8
};
9
10
use super::{pipeline::AutoExposureUniform, AutoExposure};
11
12
#[derive(Resource, Default)]
13
pub(super) struct AutoExposureBuffers {
14
pub(super) buffers: HashMap<Entity, AutoExposureBuffer>,
15
}
16
17
pub(super) struct AutoExposureBuffer {
18
pub(super) state: StorageBuffer<f32>,
19
pub(super) settings: UniformBuffer<AutoExposureUniform>,
20
}
21
22
#[derive(Resource)]
23
pub(super) struct ExtractedStateBuffers {
24
changed: Vec<(Entity, AutoExposure)>,
25
removed: Vec<Entity>,
26
}
27
28
pub(super) fn extract_buffers(
29
mut commands: Commands,
30
changed: Extract<Query<(RenderEntity, &AutoExposure), Changed<AutoExposure>>>,
31
mut removed: Extract<RemovedComponents<AutoExposure>>,
32
) {
33
commands.insert_resource(ExtractedStateBuffers {
34
changed: changed
35
.iter()
36
.map(|(entity, settings)| (entity, settings.clone()))
37
.collect(),
38
removed: removed.read().collect(),
39
});
40
}
41
42
pub(super) fn prepare_buffers(
43
device: Res<RenderDevice>,
44
queue: Res<RenderQueue>,
45
mut extracted: ResMut<ExtractedStateBuffers>,
46
mut buffers: ResMut<AutoExposureBuffers>,
47
) {
48
for (entity, settings) in extracted.changed.drain(..) {
49
let (min_log_lum, max_log_lum) = settings.range.into_inner();
50
let (low_percent, high_percent) = settings.filter.into_inner();
51
let initial_state = 0.0f32.clamp(min_log_lum, max_log_lum);
52
53
let settings = AutoExposureUniform {
54
min_log_lum,
55
inv_log_lum_range: 1.0 / (max_log_lum - min_log_lum),
56
log_lum_range: max_log_lum - min_log_lum,
57
low_percent,
58
high_percent,
59
speed_up: settings.speed_brighten,
60
speed_down: settings.speed_darken,
61
exponential_transition_distance: settings.exponential_transition_distance,
62
};
63
64
match buffers.buffers.entry(entity) {
65
Entry::Occupied(mut entry) => {
66
// Update the settings buffer, but skip updating the state buffer.
67
// The state buffer is skipped so that the animation stays continuous.
68
let value = entry.get_mut();
69
value.settings.set(settings);
70
value.settings.write_buffer(&device, &queue);
71
}
72
Entry::Vacant(entry) => {
73
let value = entry.insert(AutoExposureBuffer {
74
state: StorageBuffer::from(initial_state),
75
settings: UniformBuffer::from(settings),
76
});
77
78
value.state.write_buffer(&device, &queue);
79
value.settings.write_buffer(&device, &queue);
80
}
81
}
82
}
83
84
for entity in extracted.removed.drain(..) {
85
buffers.buffers.remove(&entity);
86
}
87
}
88
89