mirror of
https://github.com/bevyengine/bevy
synced 2024-11-29 08:00:20 +00:00
add Visibility for lights (#3958)
# Objective Add Visibility for lights ## Solution - add Visibility to PointLightBundle and DirectionLightBundle - filter lights used by Visibility.is_visible note: includes changes from #3916 due to overlap, will be cleaner after that is merged
This commit is contained in:
parent
72bb38cad5
commit
575ea81d7b
3 changed files with 37 additions and 15 deletions
|
@ -71,6 +71,8 @@ pub struct PointLightBundle {
|
||||||
pub cubemap_frusta: CubemapFrusta,
|
pub cubemap_frusta: CubemapFrusta,
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
pub global_transform: GlobalTransform,
|
pub global_transform: GlobalTransform,
|
||||||
|
/// Enables or disables the light
|
||||||
|
pub visibility: Visibility,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A component bundle for [`DirectionalLight`] entities.
|
/// A component bundle for [`DirectionalLight`] entities.
|
||||||
|
@ -81,4 +83,6 @@ pub struct DirectionalLightBundle {
|
||||||
pub visible_entities: VisibleEntities,
|
pub visible_entities: VisibleEntities,
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
pub global_transform: GlobalTransform,
|
pub global_transform: GlobalTransform,
|
||||||
|
/// Enables or disables the light
|
||||||
|
pub visibility: Visibility,
|
||||||
}
|
}
|
||||||
|
|
|
@ -480,7 +480,7 @@ fn ndc_position_to_cluster(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort point lights with shadows enabled first, then by a stable key so that the index
|
// Sort point lights with shadows enabled first, then by a stable key so that the index
|
||||||
// can be used to render at most `MAX_POINT_LIGHT_SHADOW_MAPS` point light shadows, and
|
// can be used to render at most `MAX_POINT_LIGHT_SHADOW_MAPS` point light shadows and
|
||||||
// we keep a stable set of lights visible
|
// we keep a stable set of lights visible
|
||||||
pub(crate) fn point_light_order(
|
pub(crate) fn point_light_order(
|
||||||
(entity_1, shadows_enabled_1): (&Entity, &bool),
|
(entity_1, shadows_enabled_1): (&Entity, &bool),
|
||||||
|
@ -506,7 +506,7 @@ pub(crate) fn assign_lights_to_clusters(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut global_lights: ResMut<VisiblePointLights>,
|
mut global_lights: ResMut<VisiblePointLights>,
|
||||||
mut views: Query<(Entity, &GlobalTransform, &Camera, &Frustum, &mut Clusters)>,
|
mut views: Query<(Entity, &GlobalTransform, &Camera, &Frustum, &mut Clusters)>,
|
||||||
lights_query: Query<(Entity, &GlobalTransform, &PointLight)>,
|
lights_query: Query<(Entity, &GlobalTransform, &PointLight, &Visibility)>,
|
||||||
mut lights: Local<Vec<PointLightAssignmentData>>,
|
mut lights: Local<Vec<PointLightAssignmentData>>,
|
||||||
mut max_point_lights_warning_emitted: Local<bool>,
|
mut max_point_lights_warning_emitted: Local<bool>,
|
||||||
) {
|
) {
|
||||||
|
@ -514,12 +514,15 @@ pub(crate) fn assign_lights_to_clusters(
|
||||||
lights.extend(
|
lights.extend(
|
||||||
lights_query
|
lights_query
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(entity, transform, light)| PointLightAssignmentData {
|
.filter(|(.., visibility)| visibility.is_visible)
|
||||||
entity,
|
.map(
|
||||||
translation: transform.translation,
|
|(entity, transform, light, _visibility)| PointLightAssignmentData {
|
||||||
shadows_enabled: light.shadows_enabled,
|
entity,
|
||||||
range: light.range,
|
translation: transform.translation,
|
||||||
}),
|
shadows_enabled: light.shadows_enabled,
|
||||||
|
range: light.range,
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if lights.len() > MAX_POINT_LIGHTS {
|
if lights.len() > MAX_POINT_LIGHTS {
|
||||||
|
@ -699,13 +702,18 @@ pub(crate) fn assign_lights_to_clusters(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_directional_light_frusta(
|
pub fn update_directional_light_frusta(
|
||||||
mut views: Query<(&GlobalTransform, &DirectionalLight, &mut Frustum)>,
|
mut views: Query<(
|
||||||
|
&GlobalTransform,
|
||||||
|
&DirectionalLight,
|
||||||
|
&mut Frustum,
|
||||||
|
&Visibility,
|
||||||
|
)>,
|
||||||
) {
|
) {
|
||||||
for (transform, directional_light, mut frustum) in views.iter_mut() {
|
for (transform, directional_light, mut frustum, visibility) in views.iter_mut() {
|
||||||
// The frustum is used for culling meshes to the light for shadow mapping
|
// 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
|
// so if shadow mapping is disabled for this light, then the frustum is
|
||||||
// not needed.
|
// not needed.
|
||||||
if !directional_light.shadows_enabled {
|
if !directional_light.shadows_enabled || !visibility.is_visible {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,6 +789,7 @@ pub fn check_light_mesh_visibility(
|
||||||
&Frustum,
|
&Frustum,
|
||||||
&mut VisibleEntities,
|
&mut VisibleEntities,
|
||||||
Option<&RenderLayers>,
|
Option<&RenderLayers>,
|
||||||
|
&Visibility,
|
||||||
)>,
|
)>,
|
||||||
mut visible_entity_query: Query<
|
mut visible_entity_query: Query<
|
||||||
(
|
(
|
||||||
|
@ -795,13 +804,13 @@ pub fn check_light_mesh_visibility(
|
||||||
>,
|
>,
|
||||||
) {
|
) {
|
||||||
// Directonal lights
|
// Directonal lights
|
||||||
for (directional_light, frustum, mut visible_entities, maybe_view_mask) in
|
for (directional_light, frustum, mut visible_entities, maybe_view_mask, visibility) in
|
||||||
directional_lights.iter_mut()
|
directional_lights.iter_mut()
|
||||||
{
|
{
|
||||||
visible_entities.entities.clear();
|
visible_entities.entities.clear();
|
||||||
|
|
||||||
// NOTE: If shadow mapping is disabled for the light then it must have no visible entities
|
// NOTE: If shadow mapping is disabled for the light then it must have no visible entities
|
||||||
if !directional_light.shadows_enabled {
|
if !directional_light.shadows_enabled || !visibility.is_visible {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,9 @@ use bevy_render::{
|
||||||
render_resource::{std140::AsStd140, *},
|
render_resource::{std140::AsStd140, *},
|
||||||
renderer::{RenderContext, RenderDevice, RenderQueue},
|
renderer::{RenderContext, RenderDevice, RenderQueue},
|
||||||
texture::*,
|
texture::*,
|
||||||
view::{ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms, VisibleEntities},
|
view::{
|
||||||
|
ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms, Visibility, VisibleEntities,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use bevy_transform::components::GlobalTransform;
|
use bevy_transform::components::GlobalTransform;
|
||||||
use bevy_utils::{
|
use bevy_utils::{
|
||||||
|
@ -337,6 +339,7 @@ pub fn extract_lights(
|
||||||
&DirectionalLight,
|
&DirectionalLight,
|
||||||
&mut VisibleEntities,
|
&mut VisibleEntities,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
|
&Visibility,
|
||||||
)>,
|
)>,
|
||||||
) {
|
) {
|
||||||
commands.insert_resource(ExtractedAmbientLight {
|
commands.insert_resource(ExtractedAmbientLight {
|
||||||
|
@ -383,7 +386,13 @@ pub fn extract_lights(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (entity, directional_light, visible_entities, transform) in directional_lights.iter_mut() {
|
for (entity, directional_light, visible_entities, transform, visibility) in
|
||||||
|
directional_lights.iter_mut()
|
||||||
|
{
|
||||||
|
if !visibility.is_visible {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Calulate the directional light shadow map texel size using the largest x,y dimension of
|
// Calulate the directional light shadow map texel size using the largest x,y dimension of
|
||||||
// the orthographic projection divided by the shadow map resolution
|
// the orthographic projection divided by the shadow map resolution
|
||||||
// NOTE: When using various PCF kernel sizes, this will need to be adjusted, according to:
|
// NOTE: When using various PCF kernel sizes, this will need to be adjusted, according to:
|
||||||
|
|
Loading…
Reference in a new issue