bevy/crates
Máté Homolya 9e11e96a59
Fix false positive GPU frustum culling (#17939)
# Objective

Fix incorrect mesh culling where objects (particularly directional
shadows) were being incorrectly culled during the early preprocessing
phase. The issue manifested specifically on Apple M1 GPUs but not on
newer devices like the M4. The bug was in the
`view_frustum_intersects_obb` function, where including the w component
(plane distance) in the dot product calculations led to false positive
culling results. This caused objects to be incorrectly culled before
shadow casting could begin.

## Issue Details
The problem of missing shadows is reproducible on Apple M1 GPUs as of
this commit (bisected):

```
00722b8d0 Make indirect drawing opt-out instead of opt-in, enabling multidraw by default. (#16757)
```

and as recent as this commit:

```
c818c9214 Add option to animate materials in many_cubes (#17927)
```

- The frustum culling calculation incorrectly included the w component
(plane distance) when transforming basis vectors
- The relative radius calculation should only consider directional
transformation (xyz), not positional information (w)
- This caused false positive culling specifically on M1 devices likely
due to different device-specific floating-point behavior
- When objects were incorrectly culled, `early_instance_count` never
incremented, leading to missing geometry in the shadow pass

## Testing

- Tested on M1 and M4 devices to verify the fix
- Verified shadows and geometry render correctly on both platforms
- Confirmed the solution matches the existing Rust implementation's
behavior for calculating the relative radius:
c818c92143/crates/bevy_render/src/primitives/mod.rs (L77-L87)
- The fix resolves a mathematical error in the frustum culling
calculation while maintaining correct culling behavior across all
platforms.

---

## Showcase

`c818c9214`
<img width="1284" alt="c818c9214"
src="https://github.com/user-attachments/assets/fe1c7ea9-b13d-422e-b12d-f1cd74475213"
/>

`mate-h/frustum-cull-fix`
<img width="1283" alt="frustum-cull-fix"
src="https://github.com/user-attachments/assets/8a9ccb2a-64b6-4d5e-a17d-ac4798da5b51"
/>
2025-02-20 05:35:21 +00:00
..
bevy_a11y Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_animation Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_app feat(ecs): configurable error handling for fallible systems (#17753) 2025-02-11 18:36:08 +00:00
bevy_asset Fill out some missing docs for bevy_assets (#17829) 2025-02-13 21:08:09 +00:00
bevy_audio Support decibels in bevy_audio::Volume (#17605) 2025-02-10 21:26:43 +00:00
bevy_color Upgrade to wgpu v24 (#17542) 2025-02-09 19:40:53 +00:00
bevy_core_pipeline Remove prepasses from the render world when they're removed from the main world. (#17565) 2025-02-14 06:43:35 +00:00
bevy_derive Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_dev_tools Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_diagnostic Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_dylib Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_ecs Improve the docs for ChildOf and Children (#17886) 2025-02-17 01:46:11 +00:00
bevy_encase_derive Harden proc macro path resolution and add integration tests. (#17330) 2025-02-09 19:45:45 +00:00
bevy_gilrs Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_gizmos Harden proc macro path resolution and add integration tests. (#17330) 2025-02-09 19:45:45 +00:00
bevy_gltf Fixed bevy_image and bevy_gltf failing to compile with some features. (#17887) 2025-02-17 05:10:13 +00:00
bevy_image Fixed bevy_image and bevy_gltf failing to compile with some features. (#17887) 2025-02-17 05:10:13 +00:00
bevy_input Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_input_focus Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_internal Fix dds feature enabling bevy_gltf (#17888) 2025-02-17 03:33:17 +00:00
bevy_log Bump Rust tracy client version (#17867) 2025-02-15 21:07:40 +00:00
bevy_macro_utils Fix failing proc macros when depending on bevy through dev and normal dependencies. (#17795) 2025-02-11 18:28:15 +00:00
bevy_math Add ways to configure EasingFunction::Steps via new StepConfig (#17752) 2025-02-11 22:19:01 +00:00
bevy_mesh Retain skins from frame to frame. (#17818) 2025-02-18 00:56:04 +00:00
bevy_mikktspace Update typos to 1.29.6 (#17850) 2025-02-13 19:44:47 +00:00
bevy_pbr Fix false positive GPU frustum culling (#17939) 2025-02-20 05:35:21 +00:00
bevy_picking Update picking docs to include position space (#17859) 2025-02-15 19:08:12 +00:00
bevy_platform_support Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_ptr Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_reflect Add TypeRegistry::register_by_val (#17817) 2025-02-15 19:07:01 +00:00
bevy_remote Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_render Shader validation enum (#17824) 2025-02-20 04:06:46 +00:00
bevy_scene Allow users to register their own disabling components / default query filters (#17768) 2025-02-11 18:25:32 +00:00
bevy_sprite Make the specialized pipeline cache two-level. (#17915) 2025-02-18 07:23:33 +00:00
bevy_state Harden proc macro path resolution and add integration tests. (#17330) 2025-02-09 19:45:45 +00:00
bevy_tasks Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_text Allowed creating uninitialized images (for use as storage textures) (#17760) 2025-02-10 22:22:07 +00:00
bevy_time Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_transform Add EntityDoesNotExistError, replace cases of Entity as an error, do some easy Resultification (#17855) 2025-02-16 21:59:46 +00:00
bevy_ui Update picking docs to include position space (#17859) 2025-02-15 19:08:12 +00:00
bevy_utils Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_window Cleanup publish process (#17728) 2025-02-09 17:46:19 +00:00
bevy_winit Allowed creating uninitialized images (for use as storage textures) (#17760) 2025-02-10 22:22:07 +00:00