Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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)
.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())
.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