Skip to content

Commit 048885c

Browse files
committed
bevy_pbr: Use storage buffers for point lights if supported
1 parent 086f476 commit 048885c

File tree

8 files changed

+382
-106
lines changed

8 files changed

+382
-106
lines changed

crates/bevy_pbr/src/lib.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use bevy_render::{
4141
render_graph::RenderGraph,
4242
render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions},
4343
render_resource::{Shader, SpecializedMeshPipelines},
44+
renderer::RenderDevice,
4445
view::VisibilitySystems,
4546
RenderApp, RenderStage,
4647
};
@@ -126,6 +127,15 @@ impl Plugin for PbrPlugin {
126127
},
127128
);
128129

130+
// NOTE: 3 storage buffer bindings are needed for clustered-forward rendering so check
131+
// that at least that many are supported
132+
let use_storage_buffers = app
133+
.world
134+
.resource::<RenderDevice>()
135+
.limits()
136+
.max_storage_buffers_per_shader_stage
137+
>= 3;
138+
129139
let render_app = match app.get_sub_app_mut(RenderApp) {
130140
Ok(render_app) => render_app,
131141
Err(_) => return,
@@ -164,7 +174,7 @@ impl Plugin for PbrPlugin {
164174
.init_resource::<ShadowPipeline>()
165175
.init_resource::<DrawFunctions<Shadow>>()
166176
.init_resource::<LightMeta>()
167-
.init_resource::<GlobalLightMeta>()
177+
.insert_resource(GlobalLightMeta::new(use_storage_buffers))
168178
.init_resource::<SpecializedMeshPipelines<ShadowPipeline>>();
169179

170180
let shadow_pass_node = ShadowPassNode::new(&mut render_app.world);

crates/bevy_pbr/src/light.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use bevy_render::{
99
color::Color,
1010
prelude::Image,
1111
primitives::{Aabb, CubemapFrusta, Frustum, Sphere},
12+
renderer::RenderDevice,
1213
view::{ComputedVisibility, RenderLayers, Visibility, VisibleEntities},
1314
};
1415
use bevy_transform::components::GlobalTransform;
@@ -709,6 +710,7 @@ pub(crate) fn assign_lights_to_clusters(
709710
lights_query: Query<(Entity, &GlobalTransform, &PointLight, &Visibility)>,
710711
mut lights: Local<Vec<PointLightAssignmentData>>,
711712
mut max_point_lights_warning_emitted: Local<bool>,
713+
render_device: Res<RenderDevice>,
712714
) {
713715
global_lights.entities.clear();
714716
lights.clear();
@@ -727,7 +729,10 @@ pub(crate) fn assign_lights_to_clusters(
727729
),
728730
);
729731

730-
if lights.len() > MAX_POINT_LIGHTS {
732+
// NOTE: Clustered-forward rendering requires 3 buffer bindings so only use storage buffers
733+
// if at least 3 are supported
734+
let use_storage_buffers = render_device.limits().max_storage_buffers_per_shader_stage >= 3;
735+
if !use_storage_buffers && lights.len() > MAX_POINT_LIGHTS {
731736
lights.sort_by(|light_1, light_2| {
732737
point_light_order(
733738
(&light_1.entity, &light_1.shadows_enabled),

crates/bevy_pbr/src/pbr_material.rs

+12
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ impl RenderAsset for StandardMaterial {
357357
pub struct StandardMaterialKey {
358358
normal_map: bool,
359359
cull_mode: Option<Face>,
360+
use_storage_buffers: bool,
360361
}
361362

362363
impl SpecializedMaterial for StandardMaterial {
@@ -369,6 +370,9 @@ impl SpecializedMaterial for StandardMaterial {
369370
StandardMaterialKey {
370371
normal_map: render_asset.has_normal_map,
371372
cull_mode: render_asset.cull_mode,
373+
// NOTE: Clustered-forward rendering requires 3 storage buffer bindings so check that
374+
// at least that many are supported.
375+
use_storage_buffers: render_device.limits().max_storage_buffers_per_shader_stage >= 3,
372376
}
373377
}
374378

@@ -386,6 +390,14 @@ impl SpecializedMaterial for StandardMaterial {
386390
.push(String::from("STANDARDMATERIAL_NORMAL_MAP"));
387391
}
388392
descriptor.primitive.cull_mode = key.cull_mode;
393+
if !key.use_storage_buffers {
394+
descriptor
395+
.fragment
396+
.as_mut()
397+
.unwrap()
398+
.shader_defs
399+
.push(String::from("NO_STORAGE_BUFFERS_SUPPORT"));
400+
}
389401
if let Some(label) = &mut descriptor.label {
390402
*label = format!("pbr_{}", *label).into();
391403
}

0 commit comments

Comments
 (0)