mirror of
https://github.com/bevyengine/bevy
synced 2024-12-20 10:03:07 +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},
|
batching::gpu_preprocessing::{GpuPreprocessingMode, GpuPreprocessingSupport},
|
||||||
camera::SortedCameras,
|
camera::SortedCameras,
|
||||||
mesh::allocator::MeshAllocator,
|
mesh::allocator::MeshAllocator,
|
||||||
|
view::GpuCulling,
|
||||||
};
|
};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
diagnostic::RecordDiagnostics,
|
diagnostic::RecordDiagnostics,
|
||||||
|
@ -686,6 +687,7 @@ pub fn prepare_lights(
|
||||||
&ExtractedView,
|
&ExtractedView,
|
||||||
&ExtractedClusterConfig,
|
&ExtractedClusterConfig,
|
||||||
Option<&RenderLayers>,
|
Option<&RenderLayers>,
|
||||||
|
Has<GpuCulling>,
|
||||||
),
|
),
|
||||||
With<Camera3d>,
|
With<Camera3d>,
|
||||||
>,
|
>,
|
||||||
|
@ -1094,7 +1096,7 @@ pub fn prepare_lights(
|
||||||
let mut live_views = EntityHashSet::with_capacity_and_hasher(views_count, EntityHash);
|
let mut live_views = EntityHashSet::with_capacity_and_hasher(views_count, EntityHash);
|
||||||
|
|
||||||
// set up light data for each view
|
// 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
|
.0
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|sorted_camera| views.get(sorted_camera.entity).ok())
|
.filter_map(|sorted_camera| views.get(sorted_camera.entity).ok())
|
||||||
|
@ -1102,6 +1104,12 @@ pub fn prepare_lights(
|
||||||
live_views.insert(entity);
|
live_views.insert(entity);
|
||||||
let mut view_lights = Vec::new();
|
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 is_orthographic = extracted_view.clip_from_view.w_axis.w == 1.0;
|
||||||
let cluster_factors_zw = calculate_cluster_factors(
|
let cluster_factors_zw = calculate_cluster_factors(
|
||||||
clusters.near,
|
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);
|
view_lights.push(view_light_entity);
|
||||||
|
|
||||||
if first {
|
if first {
|
||||||
// Subsequent views with the same light entity will reuse the same shadow map
|
// 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_mode);
|
||||||
shadow_render_phases.insert_or_clear(
|
|
||||||
view_light_entity,
|
|
||||||
gpu_preprocessing_support.min(GpuPreprocessingMode::PreprocessingOnly),
|
|
||||||
);
|
|
||||||
live_shadow_mapping_lights.insert(view_light_entity);
|
live_shadow_mapping_lights.insert(view_light_entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1321,14 +1329,15 @@ pub fn prepare_lights(
|
||||||
LightEntity::Spot { light_entity },
|
LightEntity::Spot { light_entity },
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if matches!(gpu_preprocessing_mode, GpuPreprocessingMode::Culling) {
|
||||||
|
commands.entity(view_light_entity).insert(GpuCulling);
|
||||||
|
}
|
||||||
|
|
||||||
view_lights.push(view_light_entity);
|
view_lights.push(view_light_entity);
|
||||||
|
|
||||||
if first {
|
if first {
|
||||||
// Subsequent views with the same light entity will reuse the same shadow map
|
// Subsequent views with the same light entity will reuse the same shadow map
|
||||||
shadow_render_phases.insert_or_clear(
|
shadow_render_phases.insert_or_clear(view_light_entity, gpu_preprocessing_mode);
|
||||||
view_light_entity,
|
|
||||||
gpu_preprocessing_support.min(GpuPreprocessingMode::PreprocessingOnly),
|
|
||||||
);
|
|
||||||
live_shadow_mapping_lights.insert(view_light_entity);
|
live_shadow_mapping_lights.insert(view_light_entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1454,15 +1463,17 @@ pub fn prepare_lights(
|
||||||
cascade_index,
|
cascade_index,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if matches!(gpu_preprocessing_mode, GpuPreprocessingMode::Culling) {
|
||||||
|
commands.entity(view_light_entity).insert(GpuCulling);
|
||||||
|
}
|
||||||
|
|
||||||
view_lights.push(view_light_entity);
|
view_lights.push(view_light_entity);
|
||||||
|
|
||||||
// Subsequent views with the same light entity will **NOT** reuse the same shadow map
|
// Subsequent views with the same light entity will **NOT** reuse the same shadow map
|
||||||
// (Because the cascades are unique to each view)
|
// (Because the cascades are unique to each view)
|
||||||
// TODO: Implement GPU culling for shadow passes.
|
// TODO: Implement GPU culling for shadow passes.
|
||||||
shadow_render_phases.insert_or_clear(
|
shadow_render_phases.insert_or_clear(view_light_entity, gpu_preprocessing_mode);
|
||||||
view_light_entity,
|
|
||||||
gpu_preprocessing_support.min(GpuPreprocessingMode::PreprocessingOnly),
|
|
||||||
);
|
|
||||||
live_shadow_mapping_lights.insert(view_light_entity);
|
live_shadow_mapping_lights.insert(view_light_entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue