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::{
|
use bevy_render::{
|
||||||
camera::Camera,
|
camera::Camera,
|
||||||
primitives::{Aabb, Frustum, HalfSpace, Sphere},
|
primitives::{Aabb, Frustum, HalfSpace, Sphere},
|
||||||
render_resource::BufferBindingType,
|
|
||||||
renderer::{RenderAdapter, RenderDevice},
|
|
||||||
view::{RenderLayers, ViewVisibility},
|
view::{RenderLayers, ViewVisibility},
|
||||||
};
|
};
|
||||||
use bevy_transform::components::GlobalTransform;
|
use bevy_transform::components::GlobalTransform;
|
||||||
@ -21,12 +19,10 @@ use bevy_utils::prelude::default;
|
|||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
decal::{self, clustered::ClusteredDecal},
|
decal::clustered::ClusteredDecal, prelude::EnvironmentMapLight, ClusterConfig, ClusterFarZMode,
|
||||||
prelude::EnvironmentMapLight,
|
Clusters, ExtractedPointLight, GlobalClusterSettings, GlobalVisibleClusterableObjects,
|
||||||
ClusterConfig, ClusterFarZMode, Clusters, ExtractedPointLight, GlobalVisibleClusterableObjects,
|
|
||||||
LightProbe, PointLight, SpotLight, ViewClusterBindings, VisibleClusterableObjects,
|
LightProbe, PointLight, SpotLight, ViewClusterBindings, VisibleClusterableObjects,
|
||||||
VolumetricLight, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
|
VolumetricLight, MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS,
|
||||||
MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const NDC_MIN: Vec2 = Vec2::NEG_ONE;
|
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 clusterable_objects: Local<Vec<ClusterableObjectAssignmentData>>,
|
||||||
mut cluster_aabb_spheres: Local<Vec<Option<Sphere>>>,
|
mut cluster_aabb_spheres: Local<Vec<Option<Sphere>>>,
|
||||||
mut max_clusterable_objects_warning_emitted: Local<bool>,
|
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;
|
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.
|
// 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
|
// 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
|
// cluster light probes on such platforms (mainly WebGL 2). Besides, those
|
||||||
// platforms typically lack bindless textures, so multiple light probes
|
// platforms typically lack bindless textures, so multiple light probes
|
||||||
// wouldn't be supported anyhow.
|
// wouldn't be supported anyhow.
|
||||||
if supports_storage_buffers {
|
if global_cluster_settings.supports_storage_buffers {
|
||||||
clusterable_objects.extend(light_probes_query.iter().map(
|
clusterable_objects.extend(light_probes_query.iter().map(
|
||||||
|(entity, transform, is_reflection_probe)| ClusterableObjectAssignmentData {
|
|(entity, transform, is_reflection_probe)| ClusterableObjectAssignmentData {
|
||||||
entity,
|
entity,
|
||||||
@ -259,7 +248,7 @@ pub(crate) fn assign_objects_to_clusters(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add decals if the current platform supports them.
|
// 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)| {
|
clusterable_objects.extend(decals_query.iter().map(|(entity, transform)| {
|
||||||
ClusterableObjectAssignmentData {
|
ClusterableObjectAssignmentData {
|
||||||
entity,
|
entity,
|
||||||
@ -272,7 +261,7 @@ pub(crate) fn assign_objects_to_clusters(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if clusterable_objects.len() > MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS
|
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| {
|
clusterable_objects.sort_by_cached_key(|clusterable_object| {
|
||||||
(
|
(
|
||||||
|
@ -21,7 +21,7 @@ use bevy_render::{
|
|||||||
BindingResource, BufferBindingType, ShaderSize as _, ShaderType, StorageBuffer,
|
BindingResource, BufferBindingType, ShaderSize as _, ShaderType, StorageBuffer,
|
||||||
UniformBuffer,
|
UniformBuffer,
|
||||||
},
|
},
|
||||||
renderer::{RenderDevice, RenderQueue},
|
renderer::{RenderAdapter, RenderDevice, RenderQueue},
|
||||||
sync_world::RenderEntity,
|
sync_world::RenderEntity,
|
||||||
Extract,
|
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:
|
// 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
|
// 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
|
/// Configure the far z-plane mode used for the furthest depth slice for clustered forward
|
||||||
/// rendering
|
/// rendering
|
||||||
#[derive(Debug, Copy, Clone, Reflect)]
|
#[derive(Debug, Copy, Clone, Reflect)]
|
||||||
|
@ -396,6 +396,9 @@ impl Plugin for PbrPlugin {
|
|||||||
.init_resource::<ShadowSamplers>()
|
.init_resource::<ShadowSamplers>()
|
||||||
.init_resource::<GlobalClusterableObjectMeta>()
|
.init_resource::<GlobalClusterableObjectMeta>()
|
||||||
.init_resource::<FallbackBindlessResources>();
|
.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