mirror of
https://github.com/bevyengine/bevy
synced 2024-12-20 01:53:12 +00:00
Use multidraw for shadows when GPU culling is in use. (#16692)
This patch makes shadows use multidraw when the camera they'll be drawn to has the `GpuCulling` component. This results in a significant reduction in drawcalls; Bistro Exterior drops to 3 drawcalls for each shadow cascade. Note that PR #16670 will remove the `GpuCulling` component, making shadows automatically use multidraw. Beware of that when testing this patch; before #16670 lands, you'll need to manually add `GpuCulling` to your camera in order to see any performance benefits.
This commit is contained in:
parent
bb090e6176
commit
7236070573
1 changed files with 25 additions and 14 deletions
|
@ -15,6 +15,7 @@ use bevy_render::{
|
|||
batching::gpu_preprocessing::{GpuPreprocessingMode, GpuPreprocessingSupport},
|
||||
camera::SortedCameras,
|
||||
mesh::allocator::MeshAllocator,
|
||||
view::GpuCulling,
|
||||
};
|
||||
use bevy_render::{
|
||||
diagnostic::RecordDiagnostics,
|
||||
|
@ -686,6 +687,7 @@ pub fn prepare_lights(
|
|||
&ExtractedView,
|
||||
&ExtractedClusterConfig,
|
||||
Option<&RenderLayers>,
|
||||
Has<GpuCulling>,
|
||||
),
|
||||
With<Camera3d>,
|
||||
>,
|
||||
|
@ -1094,7 +1096,7 @@ pub fn prepare_lights(
|
|||
let mut live_views = EntityHashSet::with_capacity_and_hasher(views_count, EntityHash);
|
||||
|
||||
// set up light data for each view
|
||||
for (entity, extracted_view, clusters, maybe_layers) in sorted_cameras
|
||||
for (entity, extracted_view, clusters, maybe_layers, has_gpu_culling) in sorted_cameras
|
||||
.0
|
||||
.iter()
|
||||
.filter_map(|sorted_camera| views.get(sorted_camera.entity).ok())
|
||||
|
@ -1102,6 +1104,12 @@ pub fn prepare_lights(
|
|||
live_views.insert(entity);
|
||||
let mut view_lights = Vec::new();
|
||||
|
||||
let gpu_preprocessing_mode = gpu_preprocessing_support.min(if has_gpu_culling {
|
||||
GpuPreprocessingMode::Culling
|
||||
} else {
|
||||
GpuPreprocessingMode::PreprocessingOnly
|
||||
});
|
||||
|
||||
let is_orthographic = extracted_view.clip_from_view.w_axis.w == 1.0;
|
||||
let cluster_factors_zw = calculate_cluster_factors(
|
||||
clusters.near,
|
||||
|
@ -1229,15 +1237,15 @@ pub fn prepare_lights(
|
|||
},
|
||||
));
|
||||
|
||||
if matches!(gpu_preprocessing_mode, GpuPreprocessingMode::Culling) {
|
||||
commands.entity(view_light_entity).insert(GpuCulling);
|
||||
}
|
||||
|
||||
view_lights.push(view_light_entity);
|
||||
|
||||
if first {
|
||||
// Subsequent views with the same light entity will reuse the same shadow map
|
||||
// TODO: Implement GPU culling for shadow passes.
|
||||
shadow_render_phases.insert_or_clear(
|
||||
view_light_entity,
|
||||
gpu_preprocessing_support.min(GpuPreprocessingMode::PreprocessingOnly),
|
||||
);
|
||||
shadow_render_phases.insert_or_clear(view_light_entity, gpu_preprocessing_mode);
|
||||
live_shadow_mapping_lights.insert(view_light_entity);
|
||||
}
|
||||
}
|
||||
|
@ -1321,14 +1329,15 @@ pub fn prepare_lights(
|
|||
LightEntity::Spot { light_entity },
|
||||
));
|
||||
|
||||
if matches!(gpu_preprocessing_mode, GpuPreprocessingMode::Culling) {
|
||||
commands.entity(view_light_entity).insert(GpuCulling);
|
||||
}
|
||||
|
||||
view_lights.push(view_light_entity);
|
||||
|
||||
if first {
|
||||
// Subsequent views with the same light entity will reuse the same shadow map
|
||||
shadow_render_phases.insert_or_clear(
|
||||
view_light_entity,
|
||||
gpu_preprocessing_support.min(GpuPreprocessingMode::PreprocessingOnly),
|
||||
);
|
||||
shadow_render_phases.insert_or_clear(view_light_entity, gpu_preprocessing_mode);
|
||||
live_shadow_mapping_lights.insert(view_light_entity);
|
||||
}
|
||||
}
|
||||
|
@ -1454,15 +1463,17 @@ pub fn prepare_lights(
|
|||
cascade_index,
|
||||
},
|
||||
));
|
||||
|
||||
if matches!(gpu_preprocessing_mode, GpuPreprocessingMode::Culling) {
|
||||
commands.entity(view_light_entity).insert(GpuCulling);
|
||||
}
|
||||
|
||||
view_lights.push(view_light_entity);
|
||||
|
||||
// Subsequent views with the same light entity will **NOT** reuse the same shadow map
|
||||
// (Because the cascades are unique to each view)
|
||||
// TODO: Implement GPU culling for shadow passes.
|
||||
shadow_render_phases.insert_or_clear(
|
||||
view_light_entity,
|
||||
gpu_preprocessing_support.min(GpuPreprocessingMode::PreprocessingOnly),
|
||||
);
|
||||
shadow_render_phases.insert_or_clear(view_light_entity, gpu_preprocessing_mode);
|
||||
live_shadow_mapping_lights.insert(view_light_entity);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue