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

Introduce support for far culling when using PerspectiveProjection #16789

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

ptsd
Copy link

@ptsd ptsd commented Dec 12, 2024

Note

An update of #8205 for 0.15 and with review suggestions.
All credit to @NotoriousENG

Objective

Solution

  • Changes return of CameraProjection::far() and it's impls from f32 to Option<f32>
  • Adds sensible (hopefully non bc breaking) far defaults to OrthographicProjection and PerspectiveProjection
    • OrthographicProjection = Some(OrthographicProjection::DEFAULT_FAR_PLANE)
      Equivalent to existing behaviour of far clipping at 1000.0
    • PerspectiveProjection = None
      Equivalent to existing behaviour of not far clipping at all
  • Updates Frustum::from_clip_from_world_custom_far to account for far becoming optional
  • Updates bevy_render::view::visibility::check_visibility to perform far culling when appropriate
  • Updates users of the above changes as appropriate

Changelog

  • Existing instantiations of OrthographicProjection and PerspectiveProjection with an explicit far value will need to wrap the value in Some
  • Custom impls of CameraProjection will need updating to account for the changed return type of far()
  • Usages of Frustum::from_clip_from_world_custom_far in downstream code will need updating to account for the changed type of the far parameter

Copy link
Contributor

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

@@ -241,18 +241,24 @@ impl Frustum {

/// Returns a frustum derived from `clip_from_world`,
/// but with a custom far plane.
/// If `far` is `None` behavior is identical to [`Frustum::from_clip_from_world`]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like the least expectation defying change but not sure it's the best approach?

let world_from_local = transform.affine();
let model_sphere = Sphere {
center: world_from_local.transform_point3a(model_aabb.center),
radius: transform.radius_vec3a(model_aabb.half_extents),
};
// Do quick sphere-based frustum culling
if !frustum.intersects_sphere(&model_sphere, false) {
if !frustum.intersects_sphere(&model_sphere, use_far_culling) {
Copy link
Author

@ptsd ptsd Dec 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this would preserve existing behaviour when using the default projections, but maybe I'm misunderstanding as OrthographicProjection previously far culled even though we always passed false here and to intersects_obb?

let cursor_ray_len = cam_ortho.far - cam_ortho.near;
let cursor_ray_len = cam_ortho
.far
.unwrap_or(OrthographicProjection::DEFAULT_FAR_PLANE)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely wrong and I'm open to suggestions. Would also allow DEFAULT_FAR_PLANE not to be pub.

let mut projection = PerspectiveProjection::default();
projection.far = projection.far.max(size * 10.0);
projection.far = projection
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This preserves the existing intention (I think...) but feels odd as the default would be an essentialy infinite far plane anyway?

@ptsd ptsd marked this pull request as ready for review December 12, 2024 19:12
@ptsd ptsd force-pushed the feature/optional-far-culling branch from b336c59 to a555da5 Compare December 12, 2024 19:15
@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

3 participants