Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_pbr/src/atmosphere/resources.rs
6604 views
1
use crate::{GpuLights, LightMeta};
2
use bevy_asset::{load_embedded_asset, Handle};
3
use bevy_camera::{Camera, Camera3d};
4
use bevy_core_pipeline::FullscreenShader;
5
use bevy_ecs::{
6
component::Component,
7
entity::Entity,
8
query::With,
9
resource::Resource,
10
system::{Commands, Query, Res, ResMut},
11
world::{FromWorld, World},
12
};
13
use bevy_image::ToExtents;
14
use bevy_math::{Affine3A, Mat4, Vec3A};
15
use bevy_render::{
16
extract_component::ComponentUniforms,
17
render_resource::{binding_types::*, *},
18
renderer::{RenderDevice, RenderQueue},
19
texture::{CachedTexture, TextureCache},
20
view::{ExtractedView, Msaa, ViewDepthTexture, ViewUniform, ViewUniforms},
21
};
22
use bevy_shader::Shader;
23
use bevy_utils::default;
24
25
use super::{Atmosphere, GpuAtmosphereSettings};
26
27
#[derive(Resource)]
28
pub(crate) struct AtmosphereBindGroupLayouts {
29
pub transmittance_lut: BindGroupLayout,
30
pub multiscattering_lut: BindGroupLayout,
31
pub sky_view_lut: BindGroupLayout,
32
pub aerial_view_lut: BindGroupLayout,
33
}
34
35
#[derive(Resource)]
36
pub(crate) struct RenderSkyBindGroupLayouts {
37
pub render_sky: BindGroupLayout,
38
pub render_sky_msaa: BindGroupLayout,
39
pub fullscreen_shader: FullscreenShader,
40
pub fragment_shader: Handle<Shader>,
41
}
42
43
impl FromWorld for AtmosphereBindGroupLayouts {
44
fn from_world(world: &mut World) -> Self {
45
let render_device = world.resource::<RenderDevice>();
46
let transmittance_lut = render_device.create_bind_group_layout(
47
"transmittance_lut_bind_group_layout",
48
&BindGroupLayoutEntries::with_indices(
49
ShaderStages::COMPUTE,
50
(
51
(0, uniform_buffer::<Atmosphere>(true)),
52
(1, uniform_buffer::<GpuAtmosphereSettings>(true)),
53
(
54
// transmittance lut storage texture
55
13,
56
texture_storage_2d(
57
TextureFormat::Rgba16Float,
58
StorageTextureAccess::WriteOnly,
59
),
60
),
61
),
62
),
63
);
64
65
let multiscattering_lut = render_device.create_bind_group_layout(
66
"multiscattering_lut_bind_group_layout",
67
&BindGroupLayoutEntries::with_indices(
68
ShaderStages::COMPUTE,
69
(
70
(0, uniform_buffer::<Atmosphere>(true)),
71
(1, uniform_buffer::<GpuAtmosphereSettings>(true)),
72
(5, texture_2d(TextureSampleType::Float { filterable: true })), //transmittance lut and sampler
73
(6, sampler(SamplerBindingType::Filtering)),
74
(
75
//multiscattering lut storage texture
76
13,
77
texture_storage_2d(
78
TextureFormat::Rgba16Float,
79
StorageTextureAccess::WriteOnly,
80
),
81
),
82
),
83
),
84
);
85
86
let sky_view_lut = render_device.create_bind_group_layout(
87
"sky_view_lut_bind_group_layout",
88
&BindGroupLayoutEntries::with_indices(
89
ShaderStages::COMPUTE,
90
(
91
(0, uniform_buffer::<Atmosphere>(true)),
92
(1, uniform_buffer::<GpuAtmosphereSettings>(true)),
93
(2, uniform_buffer::<AtmosphereTransform>(true)),
94
(3, uniform_buffer::<ViewUniform>(true)),
95
(4, uniform_buffer::<GpuLights>(true)),
96
(5, texture_2d(TextureSampleType::Float { filterable: true })), //transmittance lut and sampler
97
(6, sampler(SamplerBindingType::Filtering)),
98
(7, texture_2d(TextureSampleType::Float { filterable: true })), //multiscattering lut and sampler
99
(8, sampler(SamplerBindingType::Filtering)),
100
(
101
13,
102
texture_storage_2d(
103
TextureFormat::Rgba16Float,
104
StorageTextureAccess::WriteOnly,
105
),
106
),
107
),
108
),
109
);
110
111
let aerial_view_lut = render_device.create_bind_group_layout(
112
"aerial_view_lut_bind_group_layout",
113
&BindGroupLayoutEntries::with_indices(
114
ShaderStages::COMPUTE,
115
(
116
(0, uniform_buffer::<Atmosphere>(true)),
117
(1, uniform_buffer::<GpuAtmosphereSettings>(true)),
118
(3, uniform_buffer::<ViewUniform>(true)),
119
(4, uniform_buffer::<GpuLights>(true)),
120
(5, texture_2d(TextureSampleType::Float { filterable: true })), //transmittance lut and sampler
121
(6, sampler(SamplerBindingType::Filtering)),
122
(7, texture_2d(TextureSampleType::Float { filterable: true })), //multiscattering lut and sampler
123
(8, sampler(SamplerBindingType::Filtering)),
124
(
125
//Aerial view lut storage texture
126
13,
127
texture_storage_3d(
128
TextureFormat::Rgba16Float,
129
StorageTextureAccess::WriteOnly,
130
),
131
),
132
),
133
),
134
);
135
136
Self {
137
transmittance_lut,
138
multiscattering_lut,
139
sky_view_lut,
140
aerial_view_lut,
141
}
142
}
143
}
144
145
impl FromWorld for RenderSkyBindGroupLayouts {
146
fn from_world(world: &mut World) -> Self {
147
let render_device = world.resource::<RenderDevice>();
148
let render_sky = render_device.create_bind_group_layout(
149
"render_sky_bind_group_layout",
150
&BindGroupLayoutEntries::with_indices(
151
ShaderStages::FRAGMENT,
152
(
153
(0, uniform_buffer::<Atmosphere>(true)),
154
(1, uniform_buffer::<GpuAtmosphereSettings>(true)),
155
(2, uniform_buffer::<AtmosphereTransform>(true)),
156
(3, uniform_buffer::<ViewUniform>(true)),
157
(4, uniform_buffer::<GpuLights>(true)),
158
(5, texture_2d(TextureSampleType::Float { filterable: true })), //transmittance lut and sampler
159
(6, sampler(SamplerBindingType::Filtering)),
160
(7, texture_2d(TextureSampleType::Float { filterable: true })), //multiscattering lut and sampler
161
(8, sampler(SamplerBindingType::Filtering)),
162
(9, texture_2d(TextureSampleType::Float { filterable: true })), //sky view lut and sampler
163
(10, sampler(SamplerBindingType::Filtering)),
164
(
165
// aerial view lut and sampler
166
11,
167
texture_3d(TextureSampleType::Float { filterable: true }),
168
),
169
(12, sampler(SamplerBindingType::Filtering)),
170
(
171
//view depth texture
172
13,
173
texture_2d(TextureSampleType::Depth),
174
),
175
),
176
),
177
);
178
179
let render_sky_msaa = render_device.create_bind_group_layout(
180
"render_sky_msaa_bind_group_layout",
181
&BindGroupLayoutEntries::with_indices(
182
ShaderStages::FRAGMENT,
183
(
184
(0, uniform_buffer::<Atmosphere>(true)),
185
(1, uniform_buffer::<GpuAtmosphereSettings>(true)),
186
(2, uniform_buffer::<AtmosphereTransform>(true)),
187
(3, uniform_buffer::<ViewUniform>(true)),
188
(4, uniform_buffer::<GpuLights>(true)),
189
(5, texture_2d(TextureSampleType::Float { filterable: true })), //transmittance lut and sampler
190
(6, sampler(SamplerBindingType::Filtering)),
191
(7, texture_2d(TextureSampleType::Float { filterable: true })), //multiscattering lut and sampler
192
(8, sampler(SamplerBindingType::Filtering)),
193
(9, texture_2d(TextureSampleType::Float { filterable: true })), //sky view lut and sampler
194
(10, sampler(SamplerBindingType::Filtering)),
195
(
196
// aerial view lut and sampler
197
11,
198
texture_3d(TextureSampleType::Float { filterable: true }),
199
),
200
(12, sampler(SamplerBindingType::Filtering)),
201
(
202
//view depth texture
203
13,
204
texture_2d_multisampled(TextureSampleType::Depth),
205
),
206
),
207
),
208
);
209
210
Self {
211
render_sky,
212
render_sky_msaa,
213
fullscreen_shader: world.resource::<FullscreenShader>().clone(),
214
fragment_shader: load_embedded_asset!(world, "render_sky.wgsl"),
215
}
216
}
217
}
218
219
#[derive(Resource)]
220
pub struct AtmosphereSamplers {
221
pub transmittance_lut: Sampler,
222
pub multiscattering_lut: Sampler,
223
pub sky_view_lut: Sampler,
224
pub aerial_view_lut: Sampler,
225
}
226
227
impl FromWorld for AtmosphereSamplers {
228
fn from_world(world: &mut World) -> Self {
229
let render_device = world.resource::<RenderDevice>();
230
231
let base_sampler = SamplerDescriptor {
232
mag_filter: FilterMode::Linear,
233
min_filter: FilterMode::Linear,
234
mipmap_filter: FilterMode::Nearest,
235
..Default::default()
236
};
237
238
let transmittance_lut = render_device.create_sampler(&SamplerDescriptor {
239
label: Some("transmittance_lut_sampler"),
240
..base_sampler
241
});
242
243
let multiscattering_lut = render_device.create_sampler(&SamplerDescriptor {
244
label: Some("multiscattering_lut_sampler"),
245
..base_sampler
246
});
247
248
let sky_view_lut = render_device.create_sampler(&SamplerDescriptor {
249
label: Some("sky_view_lut_sampler"),
250
address_mode_u: AddressMode::Repeat,
251
..base_sampler
252
});
253
254
let aerial_view_lut = render_device.create_sampler(&SamplerDescriptor {
255
label: Some("aerial_view_lut_sampler"),
256
..base_sampler
257
});
258
259
Self {
260
transmittance_lut,
261
multiscattering_lut,
262
sky_view_lut,
263
aerial_view_lut,
264
}
265
}
266
}
267
268
#[derive(Resource)]
269
pub(crate) struct AtmosphereLutPipelines {
270
pub transmittance_lut: CachedComputePipelineId,
271
pub multiscattering_lut: CachedComputePipelineId,
272
pub sky_view_lut: CachedComputePipelineId,
273
pub aerial_view_lut: CachedComputePipelineId,
274
}
275
276
impl FromWorld for AtmosphereLutPipelines {
277
fn from_world(world: &mut World) -> Self {
278
let pipeline_cache = world.resource::<PipelineCache>();
279
let layouts = world.resource::<AtmosphereBindGroupLayouts>();
280
281
let transmittance_lut = pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
282
label: Some("transmittance_lut_pipeline".into()),
283
layout: vec![layouts.transmittance_lut.clone()],
284
shader: load_embedded_asset!(world, "transmittance_lut.wgsl"),
285
..default()
286
});
287
288
let multiscattering_lut =
289
pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
290
label: Some("multi_scattering_lut_pipeline".into()),
291
layout: vec![layouts.multiscattering_lut.clone()],
292
shader: load_embedded_asset!(world, "multiscattering_lut.wgsl"),
293
..default()
294
});
295
296
let sky_view_lut = pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
297
label: Some("sky_view_lut_pipeline".into()),
298
layout: vec![layouts.sky_view_lut.clone()],
299
shader: load_embedded_asset!(world, "sky_view_lut.wgsl"),
300
..default()
301
});
302
303
let aerial_view_lut = pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
304
label: Some("aerial_view_lut_pipeline".into()),
305
layout: vec![layouts.aerial_view_lut.clone()],
306
shader: load_embedded_asset!(world, "aerial_view_lut.wgsl"),
307
..default()
308
});
309
310
Self {
311
transmittance_lut,
312
multiscattering_lut,
313
sky_view_lut,
314
aerial_view_lut,
315
}
316
}
317
}
318
319
#[derive(Component)]
320
pub(crate) struct RenderSkyPipelineId(pub CachedRenderPipelineId);
321
322
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
323
pub(crate) struct RenderSkyPipelineKey {
324
pub msaa_samples: u32,
325
pub dual_source_blending: bool,
326
}
327
328
impl SpecializedRenderPipeline for RenderSkyBindGroupLayouts {
329
type Key = RenderSkyPipelineKey;
330
331
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
332
let mut shader_defs = Vec::new();
333
334
if key.msaa_samples > 1 {
335
shader_defs.push("MULTISAMPLED".into());
336
}
337
if key.dual_source_blending {
338
shader_defs.push("DUAL_SOURCE_BLENDING".into());
339
}
340
341
let dst_factor = if key.dual_source_blending {
342
BlendFactor::Src1
343
} else {
344
BlendFactor::SrcAlpha
345
};
346
347
RenderPipelineDescriptor {
348
label: Some(format!("render_sky_pipeline_{}", key.msaa_samples).into()),
349
layout: vec![if key.msaa_samples == 1 {
350
self.render_sky.clone()
351
} else {
352
self.render_sky_msaa.clone()
353
}],
354
vertex: self.fullscreen_shader.to_vertex_state(),
355
fragment: Some(FragmentState {
356
shader: self.fragment_shader.clone(),
357
shader_defs,
358
targets: vec![Some(ColorTargetState {
359
format: TextureFormat::Rgba16Float,
360
blend: Some(BlendState {
361
color: BlendComponent {
362
src_factor: BlendFactor::One,
363
dst_factor,
364
operation: BlendOperation::Add,
365
},
366
alpha: BlendComponent {
367
src_factor: BlendFactor::Zero,
368
dst_factor: BlendFactor::One,
369
operation: BlendOperation::Add,
370
},
371
}),
372
write_mask: ColorWrites::ALL,
373
})],
374
..default()
375
}),
376
multisample: MultisampleState {
377
count: key.msaa_samples,
378
..default()
379
},
380
..default()
381
}
382
}
383
}
384
385
pub(super) fn queue_render_sky_pipelines(
386
views: Query<(Entity, &Msaa), (With<Camera>, With<Atmosphere>)>,
387
pipeline_cache: Res<PipelineCache>,
388
layouts: Res<RenderSkyBindGroupLayouts>,
389
mut specializer: ResMut<SpecializedRenderPipelines<RenderSkyBindGroupLayouts>>,
390
render_device: Res<RenderDevice>,
391
mut commands: Commands,
392
) {
393
for (entity, msaa) in &views {
394
let id = specializer.specialize(
395
&pipeline_cache,
396
&layouts,
397
RenderSkyPipelineKey {
398
msaa_samples: msaa.samples(),
399
dual_source_blending: render_device
400
.features()
401
.contains(WgpuFeatures::DUAL_SOURCE_BLENDING),
402
},
403
);
404
commands.entity(entity).insert(RenderSkyPipelineId(id));
405
}
406
}
407
408
#[derive(Component)]
409
pub struct AtmosphereTextures {
410
pub transmittance_lut: CachedTexture,
411
pub multiscattering_lut: CachedTexture,
412
pub sky_view_lut: CachedTexture,
413
pub aerial_view_lut: CachedTexture,
414
}
415
416
pub(super) fn prepare_atmosphere_textures(
417
views: Query<(Entity, &GpuAtmosphereSettings), With<Atmosphere>>,
418
render_device: Res<RenderDevice>,
419
mut texture_cache: ResMut<TextureCache>,
420
mut commands: Commands,
421
) {
422
for (entity, lut_settings) in &views {
423
let transmittance_lut = texture_cache.get(
424
&render_device,
425
TextureDescriptor {
426
label: Some("transmittance_lut"),
427
size: lut_settings.transmittance_lut_size.to_extents(),
428
mip_level_count: 1,
429
sample_count: 1,
430
dimension: TextureDimension::D2,
431
format: TextureFormat::Rgba16Float,
432
usage: TextureUsages::STORAGE_BINDING | TextureUsages::TEXTURE_BINDING,
433
view_formats: &[],
434
},
435
);
436
437
let multiscattering_lut = texture_cache.get(
438
&render_device,
439
TextureDescriptor {
440
label: Some("multiscattering_lut"),
441
size: lut_settings.multiscattering_lut_size.to_extents(),
442
mip_level_count: 1,
443
sample_count: 1,
444
dimension: TextureDimension::D2,
445
format: TextureFormat::Rgba16Float,
446
usage: TextureUsages::STORAGE_BINDING | TextureUsages::TEXTURE_BINDING,
447
view_formats: &[],
448
},
449
);
450
451
let sky_view_lut = texture_cache.get(
452
&render_device,
453
TextureDescriptor {
454
label: Some("sky_view_lut"),
455
size: lut_settings.sky_view_lut_size.to_extents(),
456
mip_level_count: 1,
457
sample_count: 1,
458
dimension: TextureDimension::D2,
459
format: TextureFormat::Rgba16Float,
460
usage: TextureUsages::STORAGE_BINDING | TextureUsages::TEXTURE_BINDING,
461
view_formats: &[],
462
},
463
);
464
465
let aerial_view_lut = texture_cache.get(
466
&render_device,
467
TextureDescriptor {
468
label: Some("aerial_view_lut"),
469
size: lut_settings.aerial_view_lut_size.to_extents(),
470
mip_level_count: 1,
471
sample_count: 1,
472
dimension: TextureDimension::D3,
473
format: TextureFormat::Rgba16Float,
474
usage: TextureUsages::STORAGE_BINDING | TextureUsages::TEXTURE_BINDING,
475
view_formats: &[],
476
},
477
);
478
479
commands.entity(entity).insert({
480
AtmosphereTextures {
481
transmittance_lut,
482
multiscattering_lut,
483
sky_view_lut,
484
aerial_view_lut,
485
}
486
});
487
}
488
}
489
490
#[derive(Resource, Default)]
491
pub struct AtmosphereTransforms {
492
uniforms: DynamicUniformBuffer<AtmosphereTransform>,
493
}
494
495
impl AtmosphereTransforms {
496
#[inline]
497
pub fn uniforms(&self) -> &DynamicUniformBuffer<AtmosphereTransform> {
498
&self.uniforms
499
}
500
}
501
502
#[derive(ShaderType)]
503
pub struct AtmosphereTransform {
504
world_from_atmosphere: Mat4,
505
}
506
507
#[derive(Component)]
508
pub struct AtmosphereTransformsOffset {
509
index: u32,
510
}
511
512
impl AtmosphereTransformsOffset {
513
#[inline]
514
pub fn index(&self) -> u32 {
515
self.index
516
}
517
}
518
519
pub(super) fn prepare_atmosphere_transforms(
520
views: Query<(Entity, &ExtractedView), (With<Atmosphere>, With<Camera3d>)>,
521
render_device: Res<RenderDevice>,
522
render_queue: Res<RenderQueue>,
523
mut atmo_uniforms: ResMut<AtmosphereTransforms>,
524
mut commands: Commands,
525
) {
526
let atmo_count = views.iter().len();
527
let Some(mut writer) =
528
atmo_uniforms
529
.uniforms
530
.get_writer(atmo_count, &render_device, &render_queue)
531
else {
532
return;
533
};
534
535
for (entity, view) in &views {
536
let world_from_view = view.world_from_view.affine();
537
let camera_z = world_from_view.matrix3.z_axis;
538
let camera_y = world_from_view.matrix3.y_axis;
539
let atmo_z = camera_z
540
.with_y(0.0)
541
.try_normalize()
542
.unwrap_or_else(|| camera_y.with_y(0.0).normalize());
543
let atmo_y = Vec3A::Y;
544
let atmo_x = atmo_y.cross(atmo_z).normalize();
545
let world_from_atmosphere =
546
Affine3A::from_cols(atmo_x, atmo_y, atmo_z, world_from_view.translation);
547
548
let world_from_atmosphere = Mat4::from(world_from_atmosphere);
549
550
commands.entity(entity).insert(AtmosphereTransformsOffset {
551
index: writer.write(&AtmosphereTransform {
552
world_from_atmosphere,
553
}),
554
});
555
}
556
}
557
558
#[derive(Component)]
559
pub(crate) struct AtmosphereBindGroups {
560
pub transmittance_lut: BindGroup,
561
pub multiscattering_lut: BindGroup,
562
pub sky_view_lut: BindGroup,
563
pub aerial_view_lut: BindGroup,
564
pub render_sky: BindGroup,
565
}
566
567
pub(super) fn prepare_atmosphere_bind_groups(
568
views: Query<
569
(Entity, &AtmosphereTextures, &ViewDepthTexture, &Msaa),
570
(With<Camera3d>, With<Atmosphere>),
571
>,
572
render_device: Res<RenderDevice>,
573
layouts: Res<AtmosphereBindGroupLayouts>,
574
render_sky_layouts: Res<RenderSkyBindGroupLayouts>,
575
samplers: Res<AtmosphereSamplers>,
576
view_uniforms: Res<ViewUniforms>,
577
lights_uniforms: Res<LightMeta>,
578
atmosphere_transforms: Res<AtmosphereTransforms>,
579
atmosphere_uniforms: Res<ComponentUniforms<Atmosphere>>,
580
settings_uniforms: Res<ComponentUniforms<GpuAtmosphereSettings>>,
581
582
mut commands: Commands,
583
) {
584
if views.iter().len() == 0 {
585
return;
586
}
587
588
let atmosphere_binding = atmosphere_uniforms
589
.binding()
590
.expect("Failed to prepare atmosphere bind groups. Atmosphere uniform buffer missing");
591
592
let transforms_binding = atmosphere_transforms
593
.uniforms()
594
.binding()
595
.expect("Failed to prepare atmosphere bind groups. Atmosphere transforms buffer missing");
596
597
let settings_binding = settings_uniforms.binding().expect(
598
"Failed to prepare atmosphere bind groups. AtmosphereSettings uniform buffer missing",
599
);
600
601
let view_binding = view_uniforms
602
.uniforms
603
.binding()
604
.expect("Failed to prepare atmosphere bind groups. View uniform buffer missing");
605
606
let lights_binding = lights_uniforms
607
.view_gpu_lights
608
.binding()
609
.expect("Failed to prepare atmosphere bind groups. Lights uniform buffer missing");
610
611
for (entity, textures, view_depth_texture, msaa) in &views {
612
let transmittance_lut = render_device.create_bind_group(
613
"transmittance_lut_bind_group",
614
&layouts.transmittance_lut,
615
&BindGroupEntries::with_indices((
616
(0, atmosphere_binding.clone()),
617
(1, settings_binding.clone()),
618
(13, &textures.transmittance_lut.default_view),
619
)),
620
);
621
622
let multiscattering_lut = render_device.create_bind_group(
623
"multiscattering_lut_bind_group",
624
&layouts.multiscattering_lut,
625
&BindGroupEntries::with_indices((
626
(0, atmosphere_binding.clone()),
627
(1, settings_binding.clone()),
628
(5, &textures.transmittance_lut.default_view),
629
(6, &samplers.transmittance_lut),
630
(13, &textures.multiscattering_lut.default_view),
631
)),
632
);
633
634
let sky_view_lut = render_device.create_bind_group(
635
"sky_view_lut_bind_group",
636
&layouts.sky_view_lut,
637
&BindGroupEntries::with_indices((
638
(0, atmosphere_binding.clone()),
639
(1, settings_binding.clone()),
640
(2, transforms_binding.clone()),
641
(3, view_binding.clone()),
642
(4, lights_binding.clone()),
643
(5, &textures.transmittance_lut.default_view),
644
(6, &samplers.transmittance_lut),
645
(7, &textures.multiscattering_lut.default_view),
646
(8, &samplers.multiscattering_lut),
647
(13, &textures.sky_view_lut.default_view),
648
)),
649
);
650
651
let aerial_view_lut = render_device.create_bind_group(
652
"sky_view_lut_bind_group",
653
&layouts.aerial_view_lut,
654
&BindGroupEntries::with_indices((
655
(0, atmosphere_binding.clone()),
656
(1, settings_binding.clone()),
657
(3, view_binding.clone()),
658
(4, lights_binding.clone()),
659
(5, &textures.transmittance_lut.default_view),
660
(6, &samplers.transmittance_lut),
661
(7, &textures.multiscattering_lut.default_view),
662
(8, &samplers.multiscattering_lut),
663
(13, &textures.aerial_view_lut.default_view),
664
)),
665
);
666
667
let render_sky = render_device.create_bind_group(
668
"render_sky_bind_group",
669
if *msaa == Msaa::Off {
670
&render_sky_layouts.render_sky
671
} else {
672
&render_sky_layouts.render_sky_msaa
673
},
674
&BindGroupEntries::with_indices((
675
(0, atmosphere_binding.clone()),
676
(1, settings_binding.clone()),
677
(2, transforms_binding.clone()),
678
(3, view_binding.clone()),
679
(4, lights_binding.clone()),
680
(5, &textures.transmittance_lut.default_view),
681
(6, &samplers.transmittance_lut),
682
(7, &textures.multiscattering_lut.default_view),
683
(8, &samplers.multiscattering_lut),
684
(9, &textures.sky_view_lut.default_view),
685
(10, &samplers.sky_view_lut),
686
(11, &textures.aerial_view_lut.default_view),
687
(12, &samplers.aerial_view_lut),
688
(13, view_depth_texture.view()),
689
)),
690
);
691
692
commands.entity(entity).insert(AtmosphereBindGroups {
693
transmittance_lut,
694
multiscattering_lut,
695
sky_view_lut,
696
aerial_view_lut,
697
render_sky,
698
});
699
}
700
}
701
702