Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_pbr/src/atmosphere/node.rs
9395 views
1
use bevy_camera::{MainPassResolutionOverride, Viewport};
2
use bevy_ecs::system::Res;
3
use bevy_math::{UVec2, Vec3Swizzles};
4
use bevy_render::{
5
camera::ExtractedCamera,
6
extract_component::DynamicUniformIndex,
7
render_resource::{ComputePass, ComputePassDescriptor, PipelineCache, RenderPassDescriptor},
8
renderer::{RenderContext, ViewQuery},
9
view::{ViewTarget, ViewUniformOffset},
10
};
11
12
use crate::{resources::GpuAtmosphere, ViewLightsUniformOffset};
13
14
use super::{
15
resources::{
16
AtmosphereBindGroups, AtmosphereLutPipelines, AtmosphereTransformsOffset,
17
RenderSkyPipelineId,
18
},
19
GpuAtmosphereSettings,
20
};
21
22
pub fn atmosphere_luts(
23
view: ViewQuery<(
24
&GpuAtmosphereSettings,
25
&AtmosphereBindGroups,
26
&DynamicUniformIndex<GpuAtmosphere>,
27
&DynamicUniformIndex<GpuAtmosphereSettings>,
28
&AtmosphereTransformsOffset,
29
&ViewUniformOffset,
30
&ViewLightsUniformOffset,
31
)>,
32
pipelines: Res<AtmosphereLutPipelines>,
33
pipeline_cache: Res<PipelineCache>,
34
mut ctx: RenderContext,
35
) {
36
let (
37
settings,
38
bind_groups,
39
atmosphere_uniforms_offset,
40
settings_uniforms_offset,
41
atmosphere_transforms_offset,
42
view_uniforms_offset,
43
lights_uniforms_offset,
44
) = view.into_inner();
45
46
let (
47
Some(transmittance_lut_pipeline),
48
Some(multiscattering_lut_pipeline),
49
Some(sky_view_lut_pipeline),
50
Some(aerial_view_lut_pipeline),
51
) = (
52
pipeline_cache.get_compute_pipeline(pipelines.transmittance_lut),
53
pipeline_cache.get_compute_pipeline(pipelines.multiscattering_lut),
54
pipeline_cache.get_compute_pipeline(pipelines.sky_view_lut),
55
pipeline_cache.get_compute_pipeline(pipelines.aerial_view_lut),
56
)
57
else {
58
return;
59
};
60
61
let command_encoder = ctx.command_encoder();
62
63
let mut luts_pass = command_encoder.begin_compute_pass(&ComputePassDescriptor {
64
label: Some("atmosphere_luts"),
65
timestamp_writes: None,
66
});
67
68
fn dispatch_2d(compute_pass: &mut ComputePass, size: UVec2) {
69
const WORKGROUP_SIZE: u32 = 16;
70
let workgroups_x = size.x.div_ceil(WORKGROUP_SIZE);
71
let workgroups_y = size.y.div_ceil(WORKGROUP_SIZE);
72
compute_pass.dispatch_workgroups(workgroups_x, workgroups_y, 1);
73
}
74
75
// Transmittance LUT
76
77
luts_pass.set_pipeline(transmittance_lut_pipeline);
78
luts_pass.set_bind_group(
79
0,
80
&bind_groups.transmittance_lut,
81
&[
82
atmosphere_uniforms_offset.index(),
83
settings_uniforms_offset.index(),
84
],
85
);
86
87
dispatch_2d(&mut luts_pass, settings.transmittance_lut_size);
88
89
// Multiscattering LUT
90
91
luts_pass.set_pipeline(multiscattering_lut_pipeline);
92
luts_pass.set_bind_group(
93
0,
94
&bind_groups.multiscattering_lut,
95
&[
96
atmosphere_uniforms_offset.index(),
97
settings_uniforms_offset.index(),
98
],
99
);
100
101
luts_pass.dispatch_workgroups(
102
settings.multiscattering_lut_size.x,
103
settings.multiscattering_lut_size.y,
104
1,
105
);
106
107
// Sky View LUT
108
109
luts_pass.set_pipeline(sky_view_lut_pipeline);
110
luts_pass.set_bind_group(
111
0,
112
&bind_groups.sky_view_lut,
113
&[
114
atmosphere_uniforms_offset.index(),
115
settings_uniforms_offset.index(),
116
atmosphere_transforms_offset.index(),
117
view_uniforms_offset.offset,
118
lights_uniforms_offset.offset,
119
],
120
);
121
122
dispatch_2d(&mut luts_pass, settings.sky_view_lut_size);
123
124
// Aerial View LUT
125
126
luts_pass.set_pipeline(aerial_view_lut_pipeline);
127
luts_pass.set_bind_group(
128
0,
129
&bind_groups.aerial_view_lut,
130
&[
131
atmosphere_uniforms_offset.index(),
132
settings_uniforms_offset.index(),
133
view_uniforms_offset.offset,
134
lights_uniforms_offset.offset,
135
],
136
);
137
138
dispatch_2d(&mut luts_pass, settings.aerial_view_lut_size.xy());
139
}
140
141
pub fn render_sky(
142
view: ViewQuery<(
143
&ExtractedCamera,
144
&AtmosphereBindGroups,
145
&ViewTarget,
146
&DynamicUniformIndex<GpuAtmosphere>,
147
&DynamicUniformIndex<GpuAtmosphereSettings>,
148
&AtmosphereTransformsOffset,
149
&ViewUniformOffset,
150
&ViewLightsUniformOffset,
151
&RenderSkyPipelineId,
152
Option<&MainPassResolutionOverride>,
153
)>,
154
pipeline_cache: Res<PipelineCache>,
155
mut ctx: RenderContext,
156
) {
157
let (
158
camera,
159
atmosphere_bind_groups,
160
view_target,
161
atmosphere_uniforms_offset,
162
settings_uniforms_offset,
163
atmosphere_transforms_offset,
164
view_uniforms_offset,
165
lights_uniforms_offset,
166
render_sky_pipeline_id,
167
resolution_override,
168
) = view.into_inner();
169
170
let Some(render_sky_pipeline) = pipeline_cache.get_render_pipeline(render_sky_pipeline_id.0)
171
else {
172
return;
173
}; //TODO: warning
174
175
let command_encoder = ctx.command_encoder();
176
177
let mut render_sky_pass = command_encoder.begin_render_pass(&RenderPassDescriptor {
178
label: Some("render_sky"),
179
color_attachments: &[Some(view_target.get_color_attachment())],
180
depth_stencil_attachment: None,
181
timestamp_writes: None,
182
occlusion_query_set: None,
183
multiview_mask: None,
184
});
185
186
if let Some(viewport) =
187
Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override)
188
{
189
render_sky_pass.set_viewport(
190
viewport.physical_position.x as f32,
191
viewport.physical_position.y as f32,
192
viewport.physical_size.x as f32,
193
viewport.physical_size.y as f32,
194
viewport.depth.start,
195
viewport.depth.end,
196
);
197
}
198
199
render_sky_pass.set_pipeline(render_sky_pipeline);
200
render_sky_pass.set_bind_group(
201
0,
202
&atmosphere_bind_groups.render_sky,
203
&[
204
atmosphere_uniforms_offset.index(),
205
settings_uniforms_offset.index(),
206
atmosphere_transforms_offset.index(),
207
view_uniforms_offset.offset,
208
lights_uniforms_offset.offset,
209
],
210
);
211
render_sky_pass.draw(0..3, 0..1);
212
}
213
214