SIGN IN SIGN UP
bevyengine / bevy UNCLAIMED

A refreshingly simple data-driven game engine built in Rust

0 0 59 Rust

Respect disabled batching in GPU sorted phase preprocessing (#24365)

# Objective

On current `main`, the GPU preprocessing path disregards the
`AUTOMATIC_BATCHING` flag for sorted render phase items. This means
sorted phases cannot reliably opt out of batching when GPU preprocessing
is used.

For example, `Transmissive3d` uses items with `AUTOMATIC_BATCHING =
false` because screen-space transmission needs to render them in ordered
chunks. The number of chunks is controlled by
`ScreenSpaceTransmission.steps`. If batching is still performed, some or
all items can be grouped into a single batch range regardless of the
number of steps, producing an incorrect result as illustrated below.
[This
comment](https://github.com/bevyengine/bevy/blob/a0baf1a2c869ec03949d0e3e33922c3433eaeae6/crates/bevy_pbr/src/transmission/phase.rs#L42)
also documents other problematic configurations.

The CPU path handles this correctly because it uses the common
[`batch_and_prepare_sorted_render_phase`](https://github.com/bevyengine/bevy/blob/a0baf1a2c869ec03949d0e3e33922c3433eaeae6/crates/bevy_render/src/batching/mod.rs#L227-L230)
helper, which already checks `I::AUTOMATIC_BATCHING`.

Disabling automatic batching manually by adding `NoAutomaticBatching` to
every transmissive mesh also works, but this is an inconvenient and
hard-to-discover workaround.

## Solution

Make the GPU preprocessing path avoid batching sorted phase items when
`PhaseItem::AUTOMATIC_BATCHING = false`.

## Testing

Manual repro used four overlapping `StandardMaterial` transmissive
planes with `ScreenSpaceTransmission.steps=4`

Before this change, RenderDoc showed all four planes being drawn in the
first `main_transmissive_pass_3d` pass.

<img width="1276" height="715" alt="image"
src="https://github.com/user-attachments/assets/f365c76b-53f6-49f1-979c-5f459a4e0047"
/>

After this change, the transmissive phase items are no longer
automatically batched by the GPU preprocessing path, so the step
splitting can render separate items in separate passes as intended.

<img width="1280" height="717" alt="image"
src="https://github.com/user-attachments/assets/66e1253e-5e40-4f34-8b76-57e3a81365bd"
/>

I also checked the repro with three batching configurations:

- **No batching -> works**
- Adding `NoAutomaticBatching` to the four transmissive plane entities
avoids the issue.

- **CPU batching -> works**
- Hacked by forcing the WebGL2 feature set in `RenderPlugin` setup,
which makes Bevy use the `no_gpu_preprocessing` path.

- **GPU batching -> breaks before this PR**

Co-authored-by: Dahmen issam <issam.dahmen@fittingbox.com>
I
issam3105 committed
8c8fe5c36abbe5d332c39c478e18ad44467e21de
Parent: 1d6243e
Committed by GitHub <noreply@github.com> on 5/21/2026, 10:22:42 AM