Skip to content

Make indirect drawing opt-out instead of opt-in, enabling multidraw by default.#16757

Merged
alice-i-cecile merged 8 commits intobevyengine:mainfrom
pcwalton:opt-out-gpu-culling
Dec 13, 2024
Merged

Make indirect drawing opt-out instead of opt-in, enabling multidraw by default.#16757
alice-i-cecile merged 8 commits intobevyengine:mainfrom
pcwalton:opt-out-gpu-culling

Conversation

@pcwalton
Copy link
Contributor

This patch replaces the undocumented NoGpuCulling component with a new component, NoIndirectDrawing, effectively turning indirect drawing on by default. Indirect mode is needed for the recently-landed multidraw feature (#16427). Since multidraw is such a win for performance, when that feature is supported the small performance tax that indirect mode incurs is virtually always worth paying.

To ensure that custom drawing code such as that in the custom_shader_instancing example continues to function, this commit additionally makes GPU culling take the NoFrustumCulling component into account.

This PR is an alternative to #16670 that doesn't break the custom_shader_instancing example. PR #16755 should land first in order to avoid breaking deferred rendering, as multidraw currently breaks it.

Migration Guide

  • Indirect drawing (GPU culling) is now enabled by default, so the GpuCulling component is no longer available. To disable indirect mode, which may be useful with custom render nodes, add the new NoIndirectDrawing component to your camera.

default.

This patch replaces the undocumented `NoGpuCulling` component with a new
component, `NoIndirectDrawing`, effectively turning indirect drawing on
by default. Indirect mode is needed for the recently-landed multidraw
feature (bevyengine#16427). Since multidraw is such a win for performance, when
that feature is supported the small performance tax that indirect mode
incurs is virtually always worth paying.

To ensure that custom drawing code such as that in the
`custom_shader_instancing` example continues to function, this commit
additionally makes GPU culling take the `NoFrustumCulling` component
into account.

This PR is an alternative to bevyengine#16670 that doesn't break the
`custom_shader_instancing` example. **PR bevyengine#16755 should land first in
order to avoid breaking deferred rendering, as multidraw currently
breaks it**.
@pcwalton pcwalton added C-Bug An unexpected or incorrect behavior A-Rendering Drawing game state to the screen S-Needs-Review Needs reviewer attention (from anyone!) to move forward M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide C-Performance A change motivated by improving speed, memory usage or compile times labels Dec 10, 2024
@alice-i-cecile alice-i-cecile added the S-Blocked This cannot move forward until something else changes label Dec 11, 2024
@JMS55
Copy link
Contributor

JMS55 commented Dec 11, 2024

Did you mean to add the new component to custom_shader_instancing?

@pcwalton
Copy link
Contributor Author

@JMS55 Good catch, fixed.

Copy link
Contributor

@bushrat011899 bushrat011899 left a comment

Choose a reason for hiding this comment

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

Code looks good, and it works on my i5-1240P iGPU with Windows 10 and DX12.

@pcwalton pcwalton removed S-Blocked This cannot move forward until something else changes C-Bug An unexpected or incorrect behavior labels Dec 12, 2024
@pcwalton pcwalton requested a review from Elabajaba December 12, 2024 04:51
@pcwalton
Copy link
Contributor Author

Looks like the tests all passed except for some timeouts on Android that look like test flakiness rather than actual failures.

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 13, 2024
@alice-i-cecile alice-i-cecile removed the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Dec 13, 2024
@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Dec 13, 2024
Merged via the queue into bevyengine:main with commit 00722b8 Dec 13, 2024
ecoskey pushed a commit to ecoskey/bevy that referenced this pull request Jan 6, 2025
…y default. (bevyengine#16757)

This patch replaces the undocumented `NoGpuCulling` component with a new
component, `NoIndirectDrawing`, effectively turning indirect drawing on
by default. Indirect mode is needed for the recently-landed multidraw
feature (bevyengine#16427). Since multidraw is such a win for performance, when
that feature is supported the small performance tax that indirect mode
incurs is virtually always worth paying.

To ensure that custom drawing code such as that in the
`custom_shader_instancing` example continues to function, this commit
additionally makes GPU culling take the `NoFrustumCulling` component
into account.

This PR is an alternative to bevyengine#16670 that doesn't break the
`custom_shader_instancing` example. **PR bevyengine#16755 should land first in
order to avoid breaking deferred rendering, as multidraw currently
breaks it**.

## Migration Guide

* Indirect drawing (GPU culling) is now enabled by default, so the
`GpuCulling` component is no longer available. To disable indirect mode,
which may be useful with custom render nodes, add the new
`NoIndirectDrawing` component to your camera.
github-merge-queue bot pushed a commit that referenced this pull request Feb 20, 2025
# 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):

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

and as recent as this commit:

```
c818c92 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:
https://github.com/bevyengine/bevy/blob/c818c92143e56ef3b51836af423319a5a61b15ad/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"
/>
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-Performance A change motivated by improving speed, memory usage or compile times M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants