Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_solari/src/realtime/prepare.rs
9419 views
1
use super::SolariLighting;
2
#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]
3
use bevy_anti_alias::dlss::{
4
Dlss, DlssRayReconstructionFeature, ViewDlssRayReconstructionTextures,
5
};
6
use bevy_camera::MainPassResolutionOverride;
7
#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]
8
use bevy_ecs::query::Has;
9
use bevy_ecs::{
10
component::Component,
11
entity::Entity,
12
query::With,
13
system::{Commands, Query, Res},
14
};
15
use bevy_image::ToExtents;
16
use bevy_math::UVec2;
17
#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]
18
use bevy_render::texture::CachedTexture;
19
use bevy_render::{
20
camera::ExtractedCamera,
21
render_resource::{
22
Buffer, BufferDescriptor, BufferUsages, TextureDescriptor, TextureDimension, TextureFormat,
23
TextureUsages, TextureView, TextureViewDescriptor,
24
},
25
renderer::RenderDevice,
26
};
27
28
/// Size of the `LightSample` shader struct in bytes.
29
const LIGHT_SAMPLE_STRUCT_SIZE: u64 = 8;
30
31
/// Size of the `ResolvedLightSamplePacked` shader struct in bytes.
32
const RESOLVED_LIGHT_SAMPLE_STRUCT_SIZE: u64 = 24;
33
34
/// Size of the GI `Reservoir` shader struct in bytes.
35
const GI_RESERVOIR_STRUCT_SIZE: u64 = 48;
36
37
pub const LIGHT_TILE_BLOCKS: u64 = 128;
38
pub const LIGHT_TILE_SAMPLES_PER_BLOCK: u64 = 1024;
39
40
/// Amount of entries in the world cache (must be a power of 2, and >= 2^10)
41
pub const WORLD_CACHE_SIZE: u64 = 2u64.pow(20);
42
43
/// Internal rendering resources used for Solari lighting.
44
#[derive(Component)]
45
pub struct SolariLightingResources {
46
pub light_tile_samples: Buffer,
47
pub light_tile_resolved_samples: Buffer,
48
pub di_reservoirs_a: TextureView,
49
pub di_reservoirs_b: TextureView,
50
pub gi_reservoirs_a: Buffer,
51
pub gi_reservoirs_b: Buffer,
52
pub world_cache_checksums: Buffer,
53
pub world_cache_life: Buffer,
54
pub world_cache_radiance: Buffer,
55
pub world_cache_geometry_data: Buffer,
56
pub world_cache_luminance_deltas: Buffer,
57
pub world_cache_active_cells_new_radiance: Buffer,
58
pub world_cache_a: Buffer,
59
pub world_cache_b: Buffer,
60
pub world_cache_active_cell_indices: Buffer,
61
pub world_cache_active_cells_count: Buffer,
62
pub world_cache_active_cells_dispatch: Buffer,
63
pub view_size: UVec2,
64
}
65
66
pub fn prepare_solari_lighting_resources(
67
#[cfg(any(not(feature = "dlss"), feature = "force_disable_dlss"))] query: Query<
68
(
69
Entity,
70
&ExtractedCamera,
71
Option<&SolariLightingResources>,
72
Option<&MainPassResolutionOverride>,
73
),
74
With<SolariLighting>,
75
>,
76
#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] query: Query<
77
(
78
Entity,
79
&ExtractedCamera,
80
Option<&SolariLightingResources>,
81
Option<&MainPassResolutionOverride>,
82
Has<Dlss<DlssRayReconstructionFeature>>,
83
),
84
With<SolariLighting>,
85
>,
86
render_device: Res<RenderDevice>,
87
mut commands: Commands,
88
) {
89
for query_item in &query {
90
#[cfg(any(not(feature = "dlss"), feature = "force_disable_dlss"))]
91
let (entity, camera, solari_lighting_resources, resolution_override) = query_item;
92
#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]
93
let (entity, camera, solari_lighting_resources, resolution_override, has_dlss_rr) =
94
query_item;
95
96
let Some(mut view_size) = camera.physical_viewport_size else {
97
continue;
98
};
99
if let Some(MainPassResolutionOverride(resolution_override)) = resolution_override {
100
view_size = *resolution_override;
101
}
102
103
if solari_lighting_resources.map(|r| r.view_size) == Some(view_size) {
104
continue;
105
}
106
107
let light_tile_samples = render_device.create_buffer(&BufferDescriptor {
108
label: Some("solari_lighting_light_tile_samples"),
109
size: LIGHT_TILE_BLOCKS * LIGHT_TILE_SAMPLES_PER_BLOCK * LIGHT_SAMPLE_STRUCT_SIZE,
110
usage: BufferUsages::STORAGE,
111
mapped_at_creation: false,
112
});
113
114
let light_tile_resolved_samples = render_device.create_buffer(&BufferDescriptor {
115
label: Some("solari_lighting_light_tile_resolved_samples"),
116
size: LIGHT_TILE_BLOCKS
117
* LIGHT_TILE_SAMPLES_PER_BLOCK
118
* RESOLVED_LIGHT_SAMPLE_STRUCT_SIZE,
119
usage: BufferUsages::STORAGE,
120
mapped_at_creation: false,
121
});
122
123
let di_reservoirs = |name| {
124
render_device
125
.create_texture(&TextureDescriptor {
126
label: Some(name),
127
size: view_size.to_extents(),
128
mip_level_count: 1,
129
sample_count: 1,
130
dimension: TextureDimension::D2,
131
format: TextureFormat::Rgba32Uint,
132
usage: TextureUsages::STORAGE_BINDING,
133
view_formats: &[],
134
})
135
.create_view(&TextureViewDescriptor::default())
136
};
137
let di_reservoirs_a = di_reservoirs("solari_lighting_di_reservoirs_a");
138
let di_reservoirs_b = di_reservoirs("solari_lighting_di_reservoirs_b");
139
140
let gi_reservoirs = |name| {
141
render_device.create_buffer(&BufferDescriptor {
142
label: Some(name),
143
size: (view_size.x * view_size.y) as u64 * GI_RESERVOIR_STRUCT_SIZE,
144
usage: BufferUsages::STORAGE,
145
mapped_at_creation: false,
146
})
147
};
148
let gi_reservoirs_a = gi_reservoirs("solari_lighting_gi_reservoirs_a");
149
let gi_reservoirs_b = gi_reservoirs("solari_lighting_gi_reservoirs_b");
150
151
let world_cache_checksums = render_device.create_buffer(&BufferDescriptor {
152
label: Some("solari_lighting_world_cache_checksums"),
153
size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,
154
usage: BufferUsages::STORAGE,
155
mapped_at_creation: false,
156
});
157
158
let world_cache_life = render_device.create_buffer(&BufferDescriptor {
159
label: Some("solari_lighting_world_cache_life"),
160
size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,
161
usage: BufferUsages::STORAGE,
162
mapped_at_creation: false,
163
});
164
165
let world_cache_radiance = render_device.create_buffer(&BufferDescriptor {
166
label: Some("solari_lighting_world_cache_radiance"),
167
size: WORLD_CACHE_SIZE * size_of::<[f32; 4]>() as u64,
168
usage: BufferUsages::STORAGE,
169
mapped_at_creation: false,
170
});
171
172
let world_cache_geometry_data = render_device.create_buffer(&BufferDescriptor {
173
label: Some("solari_lighting_world_cache_geometry_data"),
174
size: WORLD_CACHE_SIZE * size_of::<[f32; 8]>() as u64,
175
usage: BufferUsages::STORAGE,
176
mapped_at_creation: false,
177
});
178
179
let world_cache_luminance_deltas = render_device.create_buffer(&BufferDescriptor {
180
label: Some("solari_lighting_world_cache_luminance_deltas"),
181
size: WORLD_CACHE_SIZE * size_of::<f32>() as u64,
182
usage: BufferUsages::STORAGE,
183
mapped_at_creation: false,
184
});
185
186
let world_cache_active_cells_new_radiance =
187
render_device.create_buffer(&BufferDescriptor {
188
label: Some("solari_lighting_world_cache_active_cells_new_radiance"),
189
size: WORLD_CACHE_SIZE * size_of::<[f32; 4]>() as u64,
190
usage: BufferUsages::STORAGE,
191
mapped_at_creation: false,
192
});
193
194
let world_cache_a = render_device.create_buffer(&BufferDescriptor {
195
label: Some("solari_lighting_world_cache_a"),
196
size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,
197
usage: BufferUsages::STORAGE,
198
mapped_at_creation: false,
199
});
200
let world_cache_b = render_device.create_buffer(&BufferDescriptor {
201
label: Some("solari_lighting_world_cache_b"),
202
size: 1024 * size_of::<u32>() as u64,
203
usage: BufferUsages::STORAGE,
204
mapped_at_creation: false,
205
});
206
207
let world_cache_active_cell_indices = render_device.create_buffer(&BufferDescriptor {
208
label: Some("solari_lighting_world_cache_active_cell_indices"),
209
size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,
210
usage: BufferUsages::STORAGE,
211
mapped_at_creation: false,
212
});
213
214
let world_cache_active_cells_count = render_device.create_buffer(&BufferDescriptor {
215
label: Some("solari_lighting_world_cache_active_cells_count"),
216
size: size_of::<u32>() as u64,
217
usage: BufferUsages::STORAGE | BufferUsages::COPY_SRC,
218
mapped_at_creation: false,
219
});
220
221
let world_cache_active_cells_dispatch = render_device.create_buffer(&BufferDescriptor {
222
label: Some("solari_lighting_world_cache_active_cells_dispatch"),
223
size: size_of::<[u32; 3]>() as u64,
224
usage: BufferUsages::INDIRECT | BufferUsages::STORAGE,
225
mapped_at_creation: false,
226
});
227
228
commands.entity(entity).insert(SolariLightingResources {
229
light_tile_samples,
230
light_tile_resolved_samples,
231
di_reservoirs_a,
232
di_reservoirs_b,
233
gi_reservoirs_a,
234
gi_reservoirs_b,
235
world_cache_checksums,
236
world_cache_life,
237
world_cache_radiance,
238
world_cache_geometry_data,
239
world_cache_luminance_deltas,
240
world_cache_active_cells_new_radiance,
241
world_cache_a,
242
world_cache_b,
243
world_cache_active_cell_indices,
244
world_cache_active_cells_count,
245
world_cache_active_cells_dispatch,
246
view_size,
247
});
248
249
#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]
250
if has_dlss_rr {
251
let diffuse_albedo = render_device.create_texture(&TextureDescriptor {
252
label: Some("solari_lighting_diffuse_albedo"),
253
size: view_size.to_extents(),
254
mip_level_count: 1,
255
sample_count: 1,
256
dimension: TextureDimension::D2,
257
format: TextureFormat::Rgba8Unorm,
258
usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,
259
view_formats: &[],
260
});
261
let diffuse_albedo_view = diffuse_albedo.create_view(&TextureViewDescriptor::default());
262
263
let specular_albedo = render_device.create_texture(&TextureDescriptor {
264
label: Some("solari_lighting_specular_albedo"),
265
size: view_size.to_extents(),
266
mip_level_count: 1,
267
sample_count: 1,
268
dimension: TextureDimension::D2,
269
format: TextureFormat::Rgba8Unorm,
270
usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,
271
view_formats: &[],
272
});
273
let specular_albedo_view =
274
specular_albedo.create_view(&TextureViewDescriptor::default());
275
276
let normal_roughness = render_device.create_texture(&TextureDescriptor {
277
label: Some("solari_lighting_normal_roughness"),
278
size: view_size.to_extents(),
279
mip_level_count: 1,
280
sample_count: 1,
281
dimension: TextureDimension::D2,
282
format: TextureFormat::Rgba16Float,
283
usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,
284
view_formats: &[],
285
});
286
let normal_roughness_view =
287
normal_roughness.create_view(&TextureViewDescriptor::default());
288
289
let specular_motion_vectors = render_device.create_texture(&TextureDescriptor {
290
label: Some("solari_lighting_specular_motion_vectors"),
291
size: view_size.to_extents(),
292
mip_level_count: 1,
293
sample_count: 1,
294
dimension: TextureDimension::D2,
295
format: TextureFormat::Rg16Float,
296
usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,
297
view_formats: &[],
298
});
299
let specular_motion_vectors_view =
300
specular_motion_vectors.create_view(&TextureViewDescriptor::default());
301
302
commands
303
.entity(entity)
304
.insert(ViewDlssRayReconstructionTextures {
305
diffuse_albedo: CachedTexture {
306
texture: diffuse_albedo,
307
default_view: diffuse_albedo_view,
308
},
309
specular_albedo: CachedTexture {
310
texture: specular_albedo,
311
default_view: specular_albedo_view,
312
},
313
normal_roughness: CachedTexture {
314
texture: normal_roughness,
315
default_view: normal_roughness_view,
316
},
317
specular_motion_vectors: CachedTexture {
318
texture: specular_motion_vectors,
319
default_view: specular_motion_vectors_view,
320
},
321
});
322
}
323
}
324
}
325
326