Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Visibilty Inheritance, universal ComputedVisibility and RenderLayers support #5310

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/bevy_pbr/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ pub struct PointLightBundle {
pub global_transform: GlobalTransform,
/// Enables or disables the light
pub visibility: Visibility,
/// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering
pub computed_visibility: ComputedVisibility,
}

/// A component bundle for spot light entities
Expand All @@ -85,6 +87,8 @@ pub struct SpotLightBundle {
pub global_transform: GlobalTransform,
/// Enables or disables the light
pub visibility: Visibility,
/// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering
pub computed_visibility: ComputedVisibility,
}

/// A component bundle for [`DirectionalLight`] entities.
Expand All @@ -97,4 +101,6 @@ pub struct DirectionalLightBundle {
pub global_transform: GlobalTransform,
/// Enables or disables the light
pub visibility: Visibility,
/// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering
pub computed_visibility: ComputedVisibility,
}
3 changes: 3 additions & 0 deletions crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,16 @@ impl Plugin for PbrPlugin {
assign_lights_to_clusters
.label(SimulationLightSystems::AssignLightsToClusters)
.after(TransformSystem::TransformPropagate)
.after(VisibilitySystems::CheckVisibility)
.after(CameraUpdateSystem)
.after(ModifiesWindows),
)
.add_system_to_stage(
CoreStage::PostUpdate,
update_directional_light_frusta
.label(SimulationLightSystems::UpdateLightFrusta)
// This must run after CheckVisibility because it relies on ComputedVisibility::is_visible()
.after(VisibilitySystems::CheckVisibility)
cart marked this conversation as resolved.
Show resolved Hide resolved
.after(TransformSystem::TransformPropagate),
)
.add_system_to_stage(
Expand Down
60 changes: 28 additions & 32 deletions crates/bevy_pbr/src/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use bevy_render::{
primitives::{Aabb, CubemapFrusta, Frustum, Plane, Sphere},
render_resource::BufferBindingType,
renderer::RenderDevice,
view::{ComputedVisibility, RenderLayers, Visibility, VisibleEntities},
view::{ComputedVisibility, RenderLayers, VisibleEntities},
};
use bevy_transform::components::GlobalTransform;
use bevy_utils::tracing::warn;
Expand Down Expand Up @@ -793,8 +793,8 @@ pub(crate) fn assign_lights_to_clusters(
&mut Clusters,
Option<&mut VisiblePointLights>,
)>,
point_lights_query: Query<(Entity, &GlobalTransform, &PointLight, &Visibility)>,
spot_lights_query: Query<(Entity, &GlobalTransform, &SpotLight, &Visibility)>,
point_lights_query: Query<(Entity, &GlobalTransform, &PointLight, &ComputedVisibility)>,
spot_lights_query: Query<(Entity, &GlobalTransform, &SpotLight, &ComputedVisibility)>,
mut lights: Local<Vec<PointLightAssignmentData>>,
mut cluster_aabb_spheres: Local<Vec<Option<Sphere>>>,
mut max_point_lights_warning_emitted: Local<bool>,
Expand All @@ -811,7 +811,7 @@ pub(crate) fn assign_lights_to_clusters(
lights.extend(
point_lights_query
.iter()
.filter(|(.., visibility)| visibility.is_visible)
.filter(|(.., visibility)| visibility.is_visible())
.map(
|(entity, transform, point_light, _visibility)| PointLightAssignmentData {
entity,
Expand All @@ -826,7 +826,7 @@ pub(crate) fn assign_lights_to_clusters(
lights.extend(
spot_lights_query
.iter()
.filter(|(.., visibility)| visibility.is_visible)
.filter(|(.., visibility)| visibility.is_visible())
cart marked this conversation as resolved.
Show resolved Hide resolved
.map(
|(entity, transform, spot_light, _visibility)| PointLightAssignmentData {
entity,
Expand Down Expand Up @@ -1415,7 +1415,7 @@ pub fn update_directional_light_frusta(
&GlobalTransform,
&DirectionalLight,
&mut Frustum,
&Visibility,
&ComputedVisibility,
),
Or<(Changed<GlobalTransform>, Changed<DirectionalLight>)>,
>,
Expand All @@ -1424,7 +1424,7 @@ pub fn update_directional_light_frusta(
// The frustum is used for culling meshes to the light for shadow mapping
// so if shadow mapping is disabled for this light, then the frustum is
// not needed.
if !directional_light.shadows_enabled || !visibility.is_visible {
if !directional_light.shadows_enabled || !visibility.is_visible() {
continue;
}

Expand Down Expand Up @@ -1541,45 +1541,43 @@ pub fn check_light_mesh_visibility(
&Frustum,
&mut VisibleEntities,
Option<&RenderLayers>,
&Visibility,
&ComputedVisibility,
),
Without<SpotLight>,
>,
mut visible_entity_query: Query<
(
Entity,
&Visibility,
&mut ComputedVisibility,
Option<&RenderLayers>,
Option<&Aabb>,
Option<&GlobalTransform>,
),
Without<NotShadowCaster>,
(Without<NotShadowCaster>, Without<DirectionalLight>),
>,
) {
// Directonal lights
for (directional_light, frustum, mut visible_entities, maybe_view_mask, visibility) in
&mut directional_lights
// Directional lights
for (
directional_light,
frustum,
mut visible_entities,
maybe_view_mask,
light_computed_visibility,
) in &mut directional_lights
{
visible_entities.entities.clear();

// NOTE: If shadow mapping is disabled for the light then it must have no visible entities
if !directional_light.shadows_enabled || !visibility.is_visible {
if !directional_light.shadows_enabled || !light_computed_visibility.is_visible() {
continue;
}

let view_mask = maybe_view_mask.copied().unwrap_or_default();

for (
entity,
visibility,
mut computed_visibility,
maybe_entity_mask,
maybe_aabb,
maybe_transform,
) in &mut visible_entity_query
for (entity, mut computed_visibility, maybe_entity_mask, maybe_aabb, maybe_transform) in
&mut visible_entity_query
{
if !visibility.is_visible {
if !computed_visibility.is_visible_in_hierarchy() {
continue;
}

Expand All @@ -1595,7 +1593,7 @@ pub fn check_light_mesh_visibility(
}
}

computed_visibility.is_visible = true;
computed_visibility.set_visible_in_view();
visible_entities.entities.push(entity);
}

Expand Down Expand Up @@ -1631,14 +1629,13 @@ pub fn check_light_mesh_visibility(

for (
entity,
visibility,
mut computed_visibility,
maybe_entity_mask,
maybe_aabb,
maybe_transform,
) in &mut visible_entity_query
{
if !visibility.is_visible {
if !computed_visibility.is_visible_in_hierarchy() {
continue;
}

Expand All @@ -1660,12 +1657,12 @@ pub fn check_light_mesh_visibility(
.zip(cubemap_visible_entities.iter_mut())
{
if frustum.intersects_obb(aabb, &model_to_world, true) {
computed_visibility.is_visible = true;
computed_visibility.set_visible_in_view();
visible_entities.entities.push(entity);
}
}
} else {
computed_visibility.is_visible = true;
computed_visibility.set_visible_in_view();
for visible_entities in cubemap_visible_entities.iter_mut() {
visible_entities.entities.push(entity);
}
Expand Down Expand Up @@ -1695,14 +1692,13 @@ pub fn check_light_mesh_visibility(

for (
entity,
visibility,
mut computed_visibility,
maybe_entity_mask,
maybe_aabb,
maybe_transform,
) in visible_entity_query.iter_mut()
{
if !visibility.is_visible {
if !computed_visibility.is_visible_in_hierarchy() {
continue;
}

Expand All @@ -1720,11 +1716,11 @@ pub fn check_light_mesh_visibility(
}

if frustum.intersects_obb(aabb, &model_to_world, true) {
computed_visibility.is_visible = true;
computed_visibility.set_visible_in_view();
visible_entities.entities.push(entity);
}
} else {
computed_visibility.is_visible = true;
computed_visibility.set_visible_in_view();
visible_entities.entities.push(entity);
}
}
Expand Down
37 changes: 30 additions & 7 deletions crates/bevy_pbr/src/render/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ use bevy_render::{
renderer::{RenderContext, RenderDevice, RenderQueue},
texture::*,
view::{
ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms, Visibility, VisibleEntities,
ComputedVisibility, ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms,
VisibleEntities,
},
Extract,
};
Expand Down Expand Up @@ -411,16 +412,30 @@ pub fn extract_lights(
point_light_shadow_map: Extract<Res<PointLightShadowMap>>,
directional_light_shadow_map: Extract<Res<DirectionalLightShadowMap>>,
global_point_lights: Extract<Res<GlobalVisiblePointLights>>,
point_lights: Extract<Query<(&PointLight, &CubemapVisibleEntities, &GlobalTransform)>>,
spot_lights: Extract<Query<(&SpotLight, &VisibleEntities, &GlobalTransform)>>,
point_lights: Extract<
Query<(
&PointLight,
&CubemapVisibleEntities,
&GlobalTransform,
&ComputedVisibility,
)>,
>,
spot_lights: Extract<
Query<(
&SpotLight,
&VisibleEntities,
&GlobalTransform,
&ComputedVisibility,
)>,
>,
directional_lights: Extract<
Query<
(
Entity,
&DirectionalLight,
&VisibleEntities,
&GlobalTransform,
&Visibility,
&ComputedVisibility,
),
Without<SpotLight>,
>,
Expand All @@ -447,7 +462,12 @@ pub fn extract_lights(

let mut point_lights_values = Vec::with_capacity(*previous_point_lights_len);
for entity in global_point_lights.iter().copied() {
if let Ok((point_light, cubemap_visible_entities, transform)) = point_lights.get(entity) {
if let Ok((point_light, cubemap_visible_entities, transform, visibility)) =
point_lights.get(entity)
{
if !visibility.is_visible() {
continue;
}
// TODO: This is very much not ideal. We should be able to re-use the vector memory.
// However, since exclusive access to the main world in extract is ill-advised, we just clone here.
let render_cubemap_visible_entities = cubemap_visible_entities.clone();
Expand Down Expand Up @@ -481,7 +501,10 @@ pub fn extract_lights(

let mut spot_lights_values = Vec::with_capacity(*previous_spot_lights_len);
for entity in global_point_lights.iter().copied() {
if let Ok((spot_light, visible_entities, transform)) = spot_lights.get(entity) {
if let Ok((spot_light, visible_entities, transform, visibility)) = spot_lights.get(entity) {
if !visibility.is_visible() {
continue;
}
// TODO: This is very much not ideal. We should be able to re-use the vector memory.
// However, since exclusive access to the main world in extract is ill-advised, we just clone here.
let render_visible_entities = visible_entities.clone();
Expand Down Expand Up @@ -522,7 +545,7 @@ pub fn extract_lights(
for (entity, directional_light, visible_entities, transform, visibility) in
directional_lights.iter()
{
if !visibility.is_visible {
if !visibility.is_visible() {
continue;
}

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub fn extract_meshes(
) {
let mut caster_commands = Vec::with_capacity(*prev_caster_commands_len);
let mut not_caster_commands = Vec::with_capacity(*prev_not_caster_commands_len);
let visible_meshes = meshes_query.iter().filter(|(_, vis, ..)| vis.is_visible);
let visible_meshes = meshes_query.iter().filter(|(_, vis, ..)| vis.is_visible());

for (entity, _, transform, handle, not_receiver, not_caster) in visible_meshes {
let transform = transform.compute_matrix();
Expand Down Expand Up @@ -216,7 +216,7 @@ pub fn extract_skinned_meshes(
let mut last_start = 0;

for (entity, computed_visibility, skin) in query.iter() {
if !computed_visibility.is_visible {
if !computed_visibility.is_visible() {
continue;
}
// PERF: This can be expensive, can we move this to prepare?
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ bevy_core = { path = "../bevy_core", version = "0.8.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.8.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.8.0-dev" }
bevy_encase_derive = { path = "../bevy_encase_derive", version = "0.8.0-dev" }
bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.8.0-dev" }
bevy_log = { path = "../bevy_log", version = "0.8.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.8.0-dev" }
bevy_mikktspace = { path = "../bevy_mikktspace", version = "0.8.0-dev" }
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/src/extract_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ fn extract_visible_components<C: ExtractComponent>(
) {
let mut values = Vec::with_capacity(*previous_len);
for (entity, computed_visibility, query_item) in query.iter_mut() {
if computed_visibility.is_visible {
if computed_visibility.is_visible() {
values.push((entity, (C::extract_component(query_item),)));
}
}
Expand Down
Loading