Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_post_process/src/auto_exposure/mod.rs
6596 views
1
use bevy_app::prelude::*;
2
use bevy_asset::{embedded_asset, AssetApp, Assets, Handle};
3
use bevy_ecs::prelude::*;
4
use bevy_render::{
5
extract_component::ExtractComponentPlugin,
6
render_asset::RenderAssetPlugin,
7
render_graph::RenderGraphExt,
8
render_resource::{
9
Buffer, BufferDescriptor, BufferUsages, PipelineCache, SpecializedComputePipelines,
10
},
11
renderer::RenderDevice,
12
ExtractSchedule, Render, RenderApp, RenderStartup, RenderSystems,
13
};
14
15
mod buffers;
16
mod compensation_curve;
17
mod node;
18
mod pipeline;
19
mod settings;
20
21
use buffers::{extract_buffers, prepare_buffers, AutoExposureBuffers};
22
pub use compensation_curve::{AutoExposureCompensationCurve, AutoExposureCompensationCurveError};
23
use node::AutoExposureNode;
24
use pipeline::{AutoExposurePass, AutoExposurePipeline, ViewAutoExposurePipeline};
25
pub use settings::AutoExposure;
26
27
use crate::auto_exposure::{
28
compensation_curve::GpuAutoExposureCompensationCurve, pipeline::init_auto_exposure_pipeline,
29
};
30
use bevy_core_pipeline::core_3d::graph::{Core3d, Node3d};
31
32
/// Plugin for the auto exposure feature.
33
///
34
/// See [`AutoExposure`] for more details.
35
pub struct AutoExposurePlugin;
36
37
#[derive(Resource)]
38
struct AutoExposureResources {
39
histogram: Buffer,
40
}
41
42
impl Plugin for AutoExposurePlugin {
43
fn build(&self, app: &mut App) {
44
embedded_asset!(app, "auto_exposure.wgsl");
45
46
app.add_plugins(RenderAssetPlugin::<GpuAutoExposureCompensationCurve>::default())
47
.init_asset::<AutoExposureCompensationCurve>()
48
.register_asset_reflect::<AutoExposureCompensationCurve>();
49
app.world_mut()
50
.resource_mut::<Assets<AutoExposureCompensationCurve>>()
51
.insert(&Handle::default(), AutoExposureCompensationCurve::default())
52
.unwrap();
53
54
app.add_plugins(ExtractComponentPlugin::<AutoExposure>::default());
55
56
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
57
return;
58
};
59
60
render_app
61
.init_resource::<SpecializedComputePipelines<AutoExposurePipeline>>()
62
.init_resource::<AutoExposureBuffers>()
63
.add_systems(
64
RenderStartup,
65
(init_auto_exposure_pipeline, init_auto_exposure_resources),
66
)
67
.add_systems(ExtractSchedule, extract_buffers)
68
.add_systems(
69
Render,
70
(
71
prepare_buffers.in_set(RenderSystems::Prepare),
72
queue_view_auto_exposure_pipelines.in_set(RenderSystems::Queue),
73
),
74
)
75
.add_render_graph_node::<AutoExposureNode>(Core3d, node::AutoExposure)
76
.add_render_graph_edges(
77
Core3d,
78
(Node3d::EndMainPass, node::AutoExposure, Node3d::Tonemapping),
79
);
80
}
81
}
82
83
pub fn init_auto_exposure_resources(mut commands: Commands, render_device: Res<RenderDevice>) {
84
commands.insert_resource(AutoExposureResources {
85
histogram: render_device.create_buffer(&BufferDescriptor {
86
label: Some("histogram buffer"),
87
size: pipeline::HISTOGRAM_BIN_COUNT * 4,
88
usage: BufferUsages::STORAGE,
89
mapped_at_creation: false,
90
}),
91
});
92
}
93
94
fn queue_view_auto_exposure_pipelines(
95
mut commands: Commands,
96
pipeline_cache: Res<PipelineCache>,
97
mut compute_pipelines: ResMut<SpecializedComputePipelines<AutoExposurePipeline>>,
98
pipeline: Res<AutoExposurePipeline>,
99
view_targets: Query<(Entity, &AutoExposure)>,
100
) {
101
for (entity, auto_exposure) in view_targets.iter() {
102
let histogram_pipeline =
103
compute_pipelines.specialize(&pipeline_cache, &pipeline, AutoExposurePass::Histogram);
104
let average_pipeline =
105
compute_pipelines.specialize(&pipeline_cache, &pipeline, AutoExposurePass::Average);
106
107
commands.entity(entity).insert(ViewAutoExposurePipeline {
108
histogram_pipeline,
109
mean_luminance_pipeline: average_pipeline,
110
compensation_curve: auto_exposure.compensation_curve.clone(),
111
metering_mask: auto_exposure.metering_mask.clone(),
112
});
113
}
114
}
115
116