Skip to content

Commit

Permalink
run frustum cumming with parallel iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
aevyrie committed Apr 15, 2022
1 parent 83c6ffb commit 3c49aab
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 65 deletions.
1 change: 1 addition & 0 deletions crates/bevy_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ bevy_derive = { path = "../bevy_derive", version = "0.7.0" }
bevy_ecs = { path = "../bevy_ecs", version = "0.7.0" }
bevy_math = { path = "../bevy_math", version = "0.7.0" }
bevy_reflect = { path = "../bevy_reflect", version = "0.7.0", features = ["bevy"] }
bevy_tasks = { path = "../bevy_tasks", version = "0.7.0" }
bevy_transform = { path = "../bevy_transform", version = "0.7.0" }
bevy_window = { path = "../bevy_window", version = "0.7.0" }
bevy_utils = { path = "../bevy_utils", version = "0.7.0" }
Expand Down
13 changes: 7 additions & 6 deletions crates/bevy_render/src/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,13 @@ impl RenderTarget {
RenderTarget::Window(window_id) => windows
.get(*window_id)
.map(|window| UVec2::new(window.physical_width(), window.physical_height())),
RenderTarget::Image(image_handle) => images.get(image_handle).map(|image| {
let Extent3d { width, height, .. } = image.texture_descriptor.size;
UVec2::new(width, height)
}),
}
.filter(|size| size.x > 0 && size.y > 0)
RenderTarget::Image(image_handle) => images
.get(image_handle)
.map(|image| {
let Extent3d { width, height, .. } = image.texture_descriptor.size;
UVec2::new(width, height)
}),
}.filter(|dim| dim.x > 0 && dim.y > 0)
}
pub fn get_logical_size(&self, windows: &Windows, images: &Assets<Image>) -> Option<Vec2> {
match self {
Expand Down
119 changes: 60 additions & 59 deletions crates/bevy_render/src/view/visibility/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
mod render_layers;

use std::sync::Arc;

use bevy_math::Vec3A;
use parking_lot::RwLock;
pub use render_layers::*;

use bevy_app::{CoreStage, Plugin};
Expand Down Expand Up @@ -139,72 +142,70 @@ pub fn update_frusta<T: Component + CameraProjection + Send + Sync + 'static>(
}

pub fn check_visibility(
pool: Res<bevy_tasks::prelude::ComputeTaskPool>,
mut view_query: Query<(&mut VisibleEntities, &Frustum, Option<&RenderLayers>), With<Camera>>,
mut visible_entity_query: ParamSet<(
Query<&mut ComputedVisibility>,
Query<(
Entity,
&Visibility,
&mut ComputedVisibility,
Option<&RenderLayers>,
Option<&Aabb>,
Option<&NoFrustumCulling>,
Option<&GlobalTransform>,
)>,
mut visible_entity_query: Query<(
Entity,
&Visibility,
&mut ComputedVisibility,
Option<&RenderLayers>,
Option<&Aabb>,
Option<&NoFrustumCulling>,
Option<&GlobalTransform>,
)>,
) {
// Reset the computed visibility to false
for mut computed_visibility in visible_entity_query.p0().iter_mut() {
computed_visibility.is_visible = false;
}

for (mut visible_entities, frustum, maybe_view_mask) in view_query.iter_mut() {
visible_entities.entities.clear();
let view_mask = maybe_view_mask.copied().unwrap_or_default();

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

let entity_mask = maybe_entity_mask.copied().unwrap_or_default();
if !view_mask.intersects(&entity_mask) {
continue;
}

// If we have an aabb and transform, do frustum culling
if let (Some(model_aabb), None, Some(transform)) =
(maybe_aabb, maybe_no_frustum_culling, maybe_transform)
{
let model = transform.compute_matrix();
let model_sphere = Sphere {
center: model.transform_point3a(model_aabb.center),
radius: (Vec3A::from(transform.scale) * model_aabb.half_extents).length(),
};
// Do quick sphere-based frustum culling
if !frustum.intersects_sphere(&model_sphere, false) {
continue;
let viz = Arc::new(RwLock::new(Vec::new()));

visible_entity_query.par_for_each_mut(
&pool,
32,
move |(
entity,
visibility,
mut computed_visibility,
maybe_entity_mask,
maybe_aabb,
maybe_no_frustum_culling,
maybe_transform,
)| {
computed_visibility.is_visible = false;
if visibility.is_visible {
let entity_mask = maybe_entity_mask.copied().unwrap_or_default();
if view_mask.intersects(&entity_mask) {
let mut skip = false;
// If we have an aabb and transform, do frustum culling
if let (Some(model_aabb), None, Some(transform)) =
(maybe_aabb, maybe_no_frustum_culling, maybe_transform)
{
let model = transform.compute_matrix();
let model_sphere = Sphere {
center: model.transform_point3a(model_aabb.center),
radius: (Vec3A::from(transform.scale) * model_aabb.half_extents)
.length(),
};
// Do quick sphere-based frustum culling
if !frustum.intersects_sphere(&model_sphere, false) {
skip = true;
}
// If we have an aabb, do aabb-based frustum culling
if !frustum.intersects_obb(model_aabb, &model, false) {
skip = true;
}
}

if !skip {
computed_visibility.is_visible = true;
viz.write().push(entity);
}
}
// TODO: check for big changes in visible entities len() vs capacity() (ex: 2x) and resize
// to prevent holding unneeded memory
}
// If we have an aabb, do aabb-based frustum culling
if !frustum.intersects_obb(model_aabb, &model, false) {
continue;
}
}

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

// TODO: check for big changes in visible entities len() vs capacity() (ex: 2x) and resize
// to prevent holding unneeded memory
},
);
}
}

0 comments on commit 3c49aab

Please sign in to comment.