Skip to content

Implement alpha to coverage (A2C) support. #12970

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

Merged
merged 10 commits into from
Apr 15, 2024
Merged

Conversation

pcwalton
Copy link
Contributor

@pcwalton pcwalton commented Apr 15, 2024

Alpha to coverage (A2C) replaces alpha blending with a hardware-specific multisample coverage mask when multisample antialiasing is in use. It's a simple form of order-independent transparency that relies on MSAA. "Anti-aliased Alpha Test: The Esoteric Alpha To Coverage" is a good summary of the motivation for and best practices relating to A2C.

This commit implements alpha to coverage support as a new variant for AlphaMode. You can supply AlphaMode::AlphaToCoverage as the alpha_mode field in StandardMaterial to use it. When in use, the standard material shader automatically applies the texture filtering method from "Anti-aliased Alpha Test: The Esoteric Alpha To Coverage". Objects with alpha-to-coverage materials are binned in the opaque pass, as they're fully order-independent.

The transparency_3d example has been updated to feature an object with alpha to coverage. Happily, the example was already using MSAA.

This is part of #2223, as far as I can tell.


Changelog

Added

  • The AlphaMode enum now supports AlphaToCoverage, to provide limited order-independent transparency when multisample antialiasing is in use.

[Alpha to coverage] (A2C) replaces alpha blending with a
hardware-specific multisample coverage mask when multisample
antialiasing is in use. It's a simple form of [order-independent
transparency] that relies on MSAA. ["Anti-aliased Alpha Test: The
Esoteric Alpha To Coverage"] is a good summary of the motivation for and
best practices relating to A2C.

This commit implements alpha to coverage support as a new variant for
`AlphaMode`. You can supply `AlphaMode::AlphaToCoverage` as the
`alpha_mode` field in `StandardMaterial` to use it. When in use, the
standard material shader automatically applies the texture filtering
method from ["Anti-aliased Alpha Test: The Esoteric Alpha To Coverage"].
Objects with alpha-to-coverage materials are binned in the opaque pass,
as they're fully order-independent.

The `transparency_3d` example has been updated to feature an object with
alpha to coverage. Happily, the example was already using MSAA.

[order-independent transparency]: https://en.wikipedia.org/wiki/Order-independent_transparency

["Anti-aliased Alpha Test: The Esoteric Alpha To Coverage"]: https://bgolus.medium.com/anti-aliased-alpha-test-the-esoteric-alpha-to-coverage-8b177335ae4f
@pcwalton pcwalton requested review from IceSentry and superdump April 15, 2024 04:39
@pcwalton pcwalton requested a review from superdump April 15, 2024 05:11
@pcwalton pcwalton requested a review from superdump April 15, 2024 05:29
Copy link
Contributor

@superdump superdump left a comment

Choose a reason for hiding this comment

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

The MIP-level scaling, which could be a preprocessing thing, can wait I suppose.

The article also mentions an issue with Unity's cascaded shadow mapping that I'm wondering if we are also affected by and need to address. But that can also be done in a follow-up. I would appreciate confirmation of whether it is an issue for us though. :)

@pcwalton
Copy link
Contributor Author

@superdump I've changed the logic to fall back to alpha mask with a cutoff of 0.5 if MSAA is off.

As for the Unity bug: Translated to Bevy concepts, the Unity issue is that if you use ExtendedMaterial<StandardMaterial, ...> with alpha to coverage on, shadows won't show up because Unity's shadow mapping has a fragment shader that leaves the alpha value at 0.0, and alpha to coverage is enabled during the shadow pass. Bevy is unaffected by this for two reasons. First, Bevy doesn't enable alpha to coverage during the shadow pass. Second, Bevy disables the fragment shader entirely during the shadow mapping pass. Section 26.4 of the Vulkan spec requires that, when the fragment shader is disabled, alpha to coverage doesn't modify the coverage mask, which prevents the Unity bug.

@IceSentry
Copy link
Contributor

In the transparency example, when the alpha blended cube has an alpha of 0 the shadows disappear, but they remain there for the A2C cube. I think that should be handled the same way for both

@pcwalton
Copy link
Contributor Author

@IceSentry The shadow behavior for A2C now matches blend.

@pcwalton pcwalton requested a review from IceSentry April 15, 2024 18:38
@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen labels Apr 15, 2024
@IceSentry
Copy link
Contributor

IceSentry commented Apr 15, 2024

Alright, just one final tiny nitpick, in the example, on the system that updates the alpha of all meshes. There should be a short description of what happens to a2c meshes.

It should probably mention the thing you replied to me in discord about the limitation of MSAA samples

@pcwalton
Copy link
Contributor Author

@IceSentry Done.

@pcwalton pcwalton 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 Apr 15, 2024
@superdump superdump added this pull request to the merge queue Apr 15, 2024
Merged via the queue into bevyengine:main with commit 1141e73 Apr 15, 2024
28 checks passed
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-Feature A new feature, making something new possible S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants