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

Add previous_view_uniforms.inverse_view #12902

Merged
merged 4 commits into from Apr 7, 2024

Conversation

JMS55
Copy link
Contributor

@JMS55 JMS55 commented Apr 7, 2024

Objective


Changelog

  • Added prepass_bindings::previous_view_uniforms.inverse_view.
  • Renamed prepass_bindings::previous_view_proj to prepass_bindings::previous_view_uniforms.view_proj.
  • Renamed PreviousViewProjectionUniformOffset to PreviousViewUniformOffset.
  • Renamed PreviousViewProjection to PreviousViewData.

Migration Guide

  • Renamed prepass_bindings::previous_view_proj to prepass_bindings::previous_view_uniforms.view_proj.
  • Renamed PreviousViewProjectionUniformOffset to PreviousViewUniformOffset.
  • Renamed PreviousViewProjection to PreviousViewData.

@JMS55 JMS55 added C-Enhancement A new feature A-Rendering Drawing game state to the screen C-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide labels Apr 7, 2024
@JMS55 JMS55 requested a review from pcwalton April 7, 2024 18:00
Copy link
Contributor

@pcwalton pcwalton left a comment

Choose a reason for hiding this comment

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

LGTM with that.

crates/bevy_pbr/src/prepass/prepass_bindings.wgsl Outdated Show resolved Hide resolved
@JMS55 JMS55 requested a review from mockersf April 7, 2024 18:18
@superdump superdump added this pull request to the merge queue Apr 7, 2024
Merged via the queue into bevyengine:main with commit 31b5943 Apr 7, 2024
27 checks passed
pcwalton added a commit to pcwalton/bevy that referenced this pull request Apr 7, 2024
preparation for GPU occlusion culling.

Two-phase occlusion culling [1], which is generally considered the
state-of-the-art occlusion culling technique. We already use two-phase
occlusion culling for meshlets, but we don't for other 3D objects.
Two-phase occlusion culling requires the construction of a *hierarchical
Z-buffer*. This patch implements an opt-in set of passes to generate
that and so is a step along the way to implementing two-phase occlusion
culling, alongside GPU frustum culling (bevyengine#12889).

This commit copies the hierarchical Z-buffer building code from meshlets
into `bevy_core_pipeline`. Adding the new `HierarchicalDepthBuffer`
component to a camera enables the feature. This code should be usable
as-is for third-party plugins that might want to implement two-phase
occlusion culling, but of course we would like to have two-phase
occlusion culling implemented directly in Bevy in the near future.

Two-phase occlusion culling will be implemented using the following
procedure:

1. Render all meshes that would have been visible in the previous frame
   to the depth buffer (with no fragment shader), using the previous
   frame's hierarchical Z-buffer, the previous frame's view matrix (cf.
   bevyengine#12902), and each model's previous view input uniform.

2. Downsample the Z-buffer to produce a hierarchical Z-buffer ("early",
   in the language of this patch).

3. Perform occlusion culling of all meshes against the Hi-Z buffer,
   using a screen space AABB test.

4. If a prepass is in use, render it now, using the occlusion culling
   results from (3). Note that if *only* a depth prepass is in use, then
   we can avoid rendering meshes that we rendered in phase (1), since
   they're already in the depth buffer.

5. Render main passes, using the occlusion culling results from (3).

6. Downsample the Z-buffer to produce a hierarchical Z-buffer again
   ("late", in the language of this patch). This readies the Z-buffer
   for step (1) of the next frame. It differs from the hierarchical
   Z-buffer produced in (2) because it includes meshes that weren't
   visible last frame, but became visible this frame.

This commit adds steps (1), (2), and (6) to the pipeline, when the
`HierarchicalDepthBuffer` component is present. It doesn't add step (3),
because step (3) depends on bevyengine#12889 which in turn depends on bevyengine#12773, and
both of those patches are still in review.

Unlike meshlets, we have to handle the case in which the depth buffer is
multisampled. This is the source of most of the extra complexity, since
we can't use the Vulkan extension [2] that allows us to easily resolve
multisampled depth buffers using the min operation.

At Jasmine's request, I haven't touched the meshlet code except to do
some very minor refactoring; the code is generally copied in.

[1]: https://medium.com/@mil_kru/two-pass-occlusion-culling-4100edcad501

[2]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSubpassDescriptionDepthStencilResolveKHR.html
pcwalton added a commit to pcwalton/bevy that referenced this pull request Apr 7, 2024
preparation for GPU occlusion culling.

Two-phase occlusion culling [1], which is generally considered the
state-of-the-art occlusion culling technique. We already use two-phase
occlusion culling for meshlets, but we don't for other 3D objects.
Two-phase occlusion culling requires the construction of a *hierarchical
Z-buffer*. This patch implements an opt-in set of passes to generate
that and so is a step along the way to implementing two-phase occlusion
culling, alongside GPU frustum culling (bevyengine#12889).

This commit copies the hierarchical Z-buffer building code from meshlets
into `bevy_core_pipeline`. Adding the new `HierarchicalDepthBuffer`
component to a camera enables the feature. This code should be usable
as-is for third-party plugins that might want to implement two-phase
occlusion culling, but of course we would like to have two-phase
occlusion culling implemented directly in Bevy in the near future.

Two-phase occlusion culling will be implemented using the following
procedure:

1. Render all meshes that would have been visible in the previous frame
   to the depth buffer (with no fragment shader), using the previous
   frame's hierarchical Z-buffer, the previous frame's view matrix (cf.
   bevyengine#12902), and each model's previous view input uniform.

2. Downsample the Z-buffer to produce a hierarchical Z-buffer ("early",
   in the language of this patch).

3. Perform occlusion culling of all meshes against the Hi-Z buffer,
   using a screen space AABB test.

4. If a prepass is in use, render it now, using the occlusion culling
   results from (3). Note that if *only* a depth prepass is in use, then
   we can avoid rendering meshes that we rendered in phase (1), since
   they're already in the depth buffer.

5. Render main passes, using the occlusion culling results from (3).

6. Downsample the Z-buffer to produce a hierarchical Z-buffer again
   ("late", in the language of this patch). This readies the Z-buffer
   for step (1) of the next frame. It differs from the hierarchical
   Z-buffer produced in (2) because it includes meshes that weren't
   visible last frame, but became visible this frame.

This commit adds steps (1), (2), and (6) to the pipeline, when the
`HierarchicalDepthBuffer` component is present. It doesn't add step (3),
because step (3) depends on bevyengine#12889 which in turn depends on bevyengine#12773, and
both of those patches are still in review.

Unlike meshlets, we have to handle the case in which the depth buffer is
multisampled. This is the source of most of the extra complexity, since
we can't use the Vulkan extension [2] that allows us to easily resolve
multisampled depth buffers using the min operation.

At Jasmine's request, I haven't touched the meshlet code except to do
some very minor refactoring; the code is generally copied in.

[1]: https://medium.com/@mil_kru/two-pass-occlusion-culling-4100edcad501

[2]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSubpassDescriptionDepthStencilResolveKHR.html
pcwalton added a commit to pcwalton/bevy that referenced this pull request Apr 7, 2024
preparation for GPU occlusion culling.

Two-phase occlusion culling [1], which is generally considered the
state-of-the-art occlusion culling technique. We already use two-phase
occlusion culling for meshlets, but we don't for other 3D objects.
Two-phase occlusion culling requires the construction of a *hierarchical
Z-buffer*. This patch implements an opt-in set of passes to generate
that and so is a step along the way to implementing two-phase occlusion
culling, alongside GPU frustum culling (bevyengine#12889).

This commit copies the hierarchical Z-buffer building code from meshlets
into `bevy_core_pipeline`. Adding the new `HierarchicalDepthBuffer`
component to a camera enables the feature. This code should be usable
as-is for third-party plugins that might want to implement two-phase
occlusion culling, but of course we would like to have two-phase
occlusion culling implemented directly in Bevy in the near future.

Two-phase occlusion culling will be implemented using the following
procedure:

1. Render all meshes that would have been visible in the previous frame
   to the depth buffer (with no fragment shader), using the previous
   frame's hierarchical Z-buffer, the previous frame's view matrix (cf.
   bevyengine#12902), and each model's previous view input uniform.

2. Downsample the Z-buffer to produce a hierarchical Z-buffer ("early",
   in the language of this patch).

3. Perform occlusion culling of all meshes against the Hi-Z buffer,
   using a screen space AABB test.

4. If a prepass is in use, render it now, using the occlusion culling
   results from (3). Note that if *only* a depth prepass is in use, then
   we can avoid rendering meshes that we rendered in phase (1), since
   they're already in the depth buffer.

5. Render main passes, using the occlusion culling results from (3).

6. Downsample the Z-buffer to produce a hierarchical Z-buffer again
   ("late", in the language of this patch). This readies the Z-buffer
   for step (1) of the next frame. It differs from the hierarchical
   Z-buffer produced in (2) because it includes meshes that weren't
   visible last frame, but became visible this frame.

This commit adds steps (1), (2), and (6) to the pipeline, when the
`HierarchicalDepthBuffer` component is present. It doesn't add step (3),
because step (3) depends on bevyengine#12889 which in turn depends on bevyengine#12773, and
both of those patches are still in review.

Unlike meshlets, we have to handle the case in which the depth buffer is
multisampled. This is the source of most of the extra complexity, since
we can't use the Vulkan extension [2] that allows us to easily resolve
multisampled depth buffers using the min operation.

At Jasmine's request, I haven't touched the meshlet code except to do
some very minor refactoring; the code is generally copied in.

[1]: https://medium.com/@mil_kru/two-pass-occlusion-culling-4100edcad501

[2]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSubpassDescriptionDepthStencilResolveKHR.html
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-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide C-Enhancement A new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants