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

Update the prepass shaders and fix the batching logic for bindless and multidraw. #16755

Merged

Conversation

pcwalton
Copy link
Contributor

This commit resolves most of the failures seen in #16670. It contains two major fixes:

  1. The prepass shaders weren't updated for bindless mode, so they were accessing material as a single element instead of as an array. I added the needed BINDLESS check.

  2. If the mesh didn't support batch set keys (i.e. get_batch_set_key() returns None), and multidraw was enabled, the batching logic would try to multidraw all the meshes in a bin together instead of disabling multidraw. This is because we checked whether the Option<BatchSetKey> for the previous batch was equal to the Option<BatchSetKey> for the next batch to determine whether objects could be multidrawn together, which would return true if batch set keys were absent, causing an entire bin to be multidrawn together. This patch fixes the logic so that multidraw is only enabled if the batch set keys match and are Some.

Additionally, this commit adds batch key support for bins that use Opaque3dNoLightmapBinKey, which in practice means prepasses. Consequently, this patch enables multidraw for the prepass when GPU culling is enabled.

When testing this patch, try adding GpuCulling to the camera in the deferred_rendering and ssr examples. You can see that these examples break without this patch and work properly with it.

multidraw.

This commit resolves most of the failures seen in bevyengine#16670. It contains
two major fixes:

1. The prepass shaders weren't updated for bindless mode, so they were
   accessing `material` as a single element instead of as an array. I
   added the needed `BINDLESS` check.

2. If the mesh didn't support batch set keys (i.e. `get_batch_set_key()`
   returns `None`), and multidraw was enabled, the batching logic would
   try to multidraw all the meshes in a bin together instead of
   disabling multidraw. This is because we checked whether the
   `Option<BatchSetKey>` for the previous batch was equal to the
   `Option<BatchSetKey>` for the next batch to determine whether objects
   could be multidrawn together, which would return true if batch set
   keys were absent, causing an entire bin to be multidrawn together.
   This patch fixes the logic so that multidraw is only enabled if the
   batch set keys match *and are `Some`*.

Additionally, this commit adds batch key support for bins that use
`Opaque3dNoLightmapBinKey`, which in practice means prepasses.
Consequently, this patch enables multidraw for the prepass when GPU
culling is enabled.

When testing this patch, try adding `GpuCulling` to the camera in the
`deferred_rendering` and `ssr` examples. You can see that these examples
break without this patch and work properly with it.
@pcwalton pcwalton added A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Dec 10, 2024
@pcwalton pcwalton added this to the 0.16 milestone Dec 10, 2024
pcwalton added a commit to pcwalton/bevy that referenced this pull request Dec 10, 2024
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**.
@kristoff3r
Copy link
Contributor

I played around with the deferred rendering example, and this happens if you first go to "Forward + Prepass", back to just "Forward" and then resize the window. I don't know if it's related to this PR or not, it didn't happen on main but main was broken in other ways.

image

@pcwalton
Copy link
Contributor Author

Probably unrelated, but I can verify for sure.

@pcwalton
Copy link
Contributor Author

@kristoff3r That bug is still there in 0.15, so it's unrelated.

@pcwalton pcwalton added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Dec 12, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 12, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 12, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 12, 2024
Merged via the queue into bevyengine:main with commit a900f68 Dec 12, 2024
28 checks passed
github-merge-queue bot pushed a commit that referenced this pull request Dec 13, 2024
…y default. (#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 (#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.
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-Bug An unexpected or incorrect behavior S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants