make cluster assign not depend on RenderAdapter/RenderDevice (#19957)
# Objective - Make bevy_light possible by making it possible to split out clusterable into bevy_camera ## Solution - Use a resource to store cluster settings instead of recalculating it every time from the render adapter/device ## Testing - 3d_scene runs
This commit is contained in:
parent
1b09c4051e
commit
d0896bf10a
@ -12,8 +12,6 @@ use bevy_math::{
|
||||
use bevy_render::{
|
||||
camera::Camera,
|
||||
primitives::{Aabb, Frustum, HalfSpace, Sphere},
|
||||
render_resource::BufferBindingType,
|
||||
renderer::{RenderAdapter, RenderDevice},
|
||||
view::{RenderLayers, ViewVisibility},
|
||||
};
|
||||
use bevy_transform::components::GlobalTransform;
|
||||
@ -21,12 +19,10 @@ use bevy_utils::prelude::default;
|
||||
use tracing::warn;
|
||||
|
||||
use crate::{
|
||||
decal::{self, clustered::ClusteredDecal},
|
||||
prelude::EnvironmentMapLight,
|
||||
ClusterConfig, ClusterFarZMode, Clusters, ExtractedPointLight, GlobalVisibleClusterableObjects,
|
||||
decal::clustered::ClusteredDecal, prelude::EnvironmentMapLight, ClusterConfig, ClusterFarZMode,
|
||||
Clusters, ExtractedPointLight, GlobalClusterSettings, GlobalVisibleClusterableObjects,
|
||||
LightProbe, PointLight, SpotLight, ViewClusterBindings, VisibleClusterableObjects,
|
||||
VolumetricLight, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
|
||||
MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS,
|
||||
VolumetricLight, MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS,
|
||||
};
|
||||
|
||||
const NDC_MIN: Vec2 = Vec2::NEG_ONE;
|
||||
@ -180,9 +176,9 @@ pub(crate) fn assign_objects_to_clusters(
|
||||
mut clusterable_objects: Local<Vec<ClusterableObjectAssignmentData>>,
|
||||
mut cluster_aabb_spheres: Local<Vec<Option<Sphere>>>,
|
||||
mut max_clusterable_objects_warning_emitted: Local<bool>,
|
||||
(render_device, render_adapter): (Option<Res<RenderDevice>>, Option<Res<RenderAdapter>>),
|
||||
global_cluster_settings: Option<Res<GlobalClusterSettings>>,
|
||||
) {
|
||||
let (Some(render_device), Some(render_adapter)) = (render_device, render_adapter) else {
|
||||
let Some(global_cluster_settings) = global_cluster_settings else {
|
||||
return;
|
||||
};
|
||||
|
||||
@ -229,20 +225,13 @@ pub(crate) fn assign_objects_to_clusters(
|
||||
),
|
||||
);
|
||||
|
||||
let clustered_forward_buffer_binding_type =
|
||||
render_device.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);
|
||||
let supports_storage_buffers = matches!(
|
||||
clustered_forward_buffer_binding_type,
|
||||
BufferBindingType::Storage { .. }
|
||||
);
|
||||
|
||||
// Gather up light probes, but only if we're clustering them.
|
||||
//
|
||||
// UBOs aren't large enough to hold indices for light probes, so we can't
|
||||
// cluster light probes on such platforms (mainly WebGL 2). Besides, those
|
||||
// platforms typically lack bindless textures, so multiple light probes
|
||||
// wouldn't be supported anyhow.
|
||||
if supports_storage_buffers {
|
||||
if global_cluster_settings.supports_storage_buffers {
|
||||
clusterable_objects.extend(light_probes_query.iter().map(
|
||||
|(entity, transform, is_reflection_probe)| ClusterableObjectAssignmentData {
|
||||
entity,
|
||||
@ -259,7 +248,7 @@ pub(crate) fn assign_objects_to_clusters(
|
||||
}
|
||||
|
||||
// Add decals if the current platform supports them.
|
||||
if decal::clustered::clustered_decals_are_usable(&render_device, &render_adapter) {
|
||||
if global_cluster_settings.clustered_decals_are_usable {
|
||||
clusterable_objects.extend(decals_query.iter().map(|(entity, transform)| {
|
||||
ClusterableObjectAssignmentData {
|
||||
entity,
|
||||
@ -272,7 +261,7 @@ pub(crate) fn assign_objects_to_clusters(
|
||||
}
|
||||
|
||||
if clusterable_objects.len() > MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS
|
||||
&& !supports_storage_buffers
|
||||
&& !global_cluster_settings.supports_storage_buffers
|
||||
{
|
||||
clusterable_objects.sort_by_cached_key(|clusterable_object| {
|
||||
(
|
||||
|
@ -21,7 +21,7 @@ use bevy_render::{
|
||||
BindingResource, BufferBindingType, ShaderSize as _, ShaderType, StorageBuffer,
|
||||
UniformBuffer,
|
||||
},
|
||||
renderer::{RenderDevice, RenderQueue},
|
||||
renderer::{RenderAdapter, RenderDevice, RenderQueue},
|
||||
sync_world::RenderEntity,
|
||||
Extract,
|
||||
};
|
||||
@ -63,6 +63,27 @@ const CLUSTER_COUNT_MASK: u32 = (1 << CLUSTER_COUNT_SIZE) - 1;
|
||||
// The z-slicing method mentioned in the aortiz article is originally from Tiago Sousa's Siggraph 2016 talk about Doom 2016:
|
||||
// http://advances.realtimerendering.com/s2016/Siggraph2016_idTech6.pdf
|
||||
|
||||
#[derive(Resource)]
|
||||
pub struct GlobalClusterSettings {
|
||||
pub supports_storage_buffers: bool,
|
||||
pub clustered_decals_are_usable: bool,
|
||||
}
|
||||
|
||||
pub(crate) fn make_global_cluster_settings(world: &World) -> GlobalClusterSettings {
|
||||
let device = world.resource::<RenderDevice>();
|
||||
let adapter = world.resource::<RenderAdapter>();
|
||||
let clustered_decals_are_usable =
|
||||
crate::decal::clustered::clustered_decals_are_usable(device, adapter);
|
||||
let supports_storage_buffers = matches!(
|
||||
device.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT),
|
||||
BufferBindingType::Storage { .. }
|
||||
);
|
||||
GlobalClusterSettings {
|
||||
supports_storage_buffers,
|
||||
clustered_decals_are_usable,
|
||||
}
|
||||
}
|
||||
|
||||
/// Configure the far z-plane mode used for the furthest depth slice for clustered forward
|
||||
/// rendering
|
||||
#[derive(Debug, Copy, Clone, Reflect)]
|
||||
|
@ -396,6 +396,9 @@ impl Plugin for PbrPlugin {
|
||||
.init_resource::<ShadowSamplers>()
|
||||
.init_resource::<GlobalClusterableObjectMeta>()
|
||||
.init_resource::<FallbackBindlessResources>();
|
||||
|
||||
let global_cluster_settings = make_global_cluster_settings(render_app.world());
|
||||
app.insert_resource(global_cluster_settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user