mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
honour NoFrustumCulling for shadows (#15117)
# Objective `NoFrustumCulling` prevents meshes from being considered out of view based on AABBs (sometimes useful for skinned meshes which don't recalculate AABBs currently). it currently only applies for primary view rendering, not for shadow rendering which can result in missing shadows. ## Solution Add checks for `NoFrustumCulling` to `check_dir_light_mesh_visibility` and `check_point_light_mesh_visibility` so that `NoFrustumCulling` entities are rendered to all shadow views as well as all primary views.
This commit is contained in:
parent
ccb8854ec1
commit
4e6471ed23
1 changed files with 22 additions and 6 deletions
|
@ -11,7 +11,8 @@ use bevy_render::{
|
|||
mesh::Mesh,
|
||||
primitives::{Aabb, CascadesFrusta, CubemapFrusta, Frustum, Sphere},
|
||||
view::{
|
||||
InheritedVisibility, RenderLayers, ViewVisibility, VisibilityRange, VisibleEntityRanges,
|
||||
InheritedVisibility, NoFrustumCulling, RenderLayers, ViewVisibility, VisibilityRange,
|
||||
VisibleEntityRanges,
|
||||
},
|
||||
};
|
||||
use bevy_transform::components::{GlobalTransform, Transform};
|
||||
|
@ -683,6 +684,7 @@ pub fn check_dir_light_mesh_visibility(
|
|||
Option<&Aabb>,
|
||||
Option<&GlobalTransform>,
|
||||
Has<VisibilityRange>,
|
||||
Has<NoFrustumCulling>,
|
||||
),
|
||||
(
|
||||
Without<NotShadowCaster>,
|
||||
|
@ -742,6 +744,7 @@ pub fn check_dir_light_mesh_visibility(
|
|||
maybe_aabb,
|
||||
maybe_transform,
|
||||
has_visibility_range,
|
||||
has_no_frustum_culling,
|
||||
)| {
|
||||
if !inherited_visibility.get() {
|
||||
return;
|
||||
|
@ -768,7 +771,9 @@ pub fn check_dir_light_mesh_visibility(
|
|||
.zip(view_visible_entities_local_queue.iter_mut())
|
||||
{
|
||||
// Disable near-plane culling, as a shadow caster could lie before the near plane.
|
||||
if !frustum.intersects_obb(aabb, &transform.affine(), false, true) {
|
||||
if !has_no_frustum_culling
|
||||
&& !frustum.intersects_obb(aabb, &transform.affine(), false, true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
visible = true;
|
||||
|
@ -848,6 +853,7 @@ pub fn check_point_light_mesh_visibility(
|
|||
Option<&Aabb>,
|
||||
Option<&GlobalTransform>,
|
||||
Has<VisibilityRange>,
|
||||
Has<NoFrustumCulling>,
|
||||
),
|
||||
(
|
||||
Without<NotShadowCaster>,
|
||||
|
@ -897,6 +903,7 @@ pub fn check_point_light_mesh_visibility(
|
|||
maybe_aabb,
|
||||
maybe_transform,
|
||||
has_visibility_range,
|
||||
has_no_frustum_culling,
|
||||
)| {
|
||||
if !inherited_visibility.get() {
|
||||
return;
|
||||
|
@ -917,7 +924,9 @@ pub fn check_point_light_mesh_visibility(
|
|||
if let (Some(aabb), Some(transform)) = (maybe_aabb, maybe_transform) {
|
||||
let model_to_world = transform.affine();
|
||||
// Do a cheap sphere vs obb test to prune out most meshes outside the sphere of the light
|
||||
if !light_sphere.intersects_obb(aabb, &model_to_world) {
|
||||
if !has_no_frustum_culling
|
||||
&& !light_sphere.intersects_obb(aabb, &model_to_world)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -925,7 +934,9 @@ pub fn check_point_light_mesh_visibility(
|
|||
.iter()
|
||||
.zip(cubemap_visible_entities_local_queue.iter_mut())
|
||||
{
|
||||
if frustum.intersects_obb(aabb, &model_to_world, true, true) {
|
||||
if has_no_frustum_culling
|
||||
|| frustum.intersects_obb(aabb, &model_to_world, true, true)
|
||||
{
|
||||
view_visibility.set();
|
||||
visible_entities.push(entity);
|
||||
}
|
||||
|
@ -980,6 +991,7 @@ pub fn check_point_light_mesh_visibility(
|
|||
maybe_aabb,
|
||||
maybe_transform,
|
||||
has_visibility_range,
|
||||
has_no_frustum_culling,
|
||||
)| {
|
||||
if !inherited_visibility.get() {
|
||||
return;
|
||||
|
@ -1001,11 +1013,15 @@ pub fn check_point_light_mesh_visibility(
|
|||
if let (Some(aabb), Some(transform)) = (maybe_aabb, maybe_transform) {
|
||||
let model_to_world = transform.affine();
|
||||
// Do a cheap sphere vs obb test to prune out most meshes outside the sphere of the light
|
||||
if !light_sphere.intersects_obb(aabb, &model_to_world) {
|
||||
if !has_no_frustum_culling
|
||||
&& !light_sphere.intersects_obb(aabb, &model_to_world)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if frustum.intersects_obb(aabb, &model_to_world, true, true) {
|
||||
if has_no_frustum_culling
|
||||
|| frustum.intersects_obb(aabb, &model_to_world, true, true)
|
||||
{
|
||||
view_visibility.set();
|
||||
spot_visible_entities_local_queue.push(entity);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue