-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
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
Material: Add alpha to coverage define, add clipping & alpha test anti aliasing #22172
Conversation
A very informative post https://bgolus.medium.com/anti-aliased-alpha-test-the-esoteric-alpha-to-coverage-8b177335ae4f |
Here's an example of how the define can be used to smooth alpha test materials using textures with smooth gradients. The alphaToCoverage setting will already help smooth out alpha test textures with a stark alpha contrast but as mentioned in the article @WestLangley posted it can still cause issues with mip maps and linear texture interpolation:
And here's a zoomed in shot of the difference in edge quality (left is dev, right is new alphaToCoverage + alphaTest): |
@mrdoob is this interesting to you? I'm happy to finish out adding support for clip plane edges and alpha test textures if so. This Oculus VR guide recommends using alpha to coverage for alpha cutout materials. And here's an article (cached version linked because the main site has a cookie pop up that's difficult to navigate) that discusses Street Fighter 4 using alpha to coverage for fences and leaves:
|
…ge-define # Conflicts: # src/renderers/webgl/WebGLPrograms.js
Very nice! Is there any case in which we wouldn't want to have this always enabled? |
Unfortunately when it's enabled for partially transparent objects you get this kind of banding where there should be smooth gradients since the opacity is mapped to one of the 4 (8?) MSAA coverage levels. See this image from the table above: |
Also when a user want to display very sharply pixelated transparent texture (low resolution + alphaTest + NearestFilter), I suppose this feature would interfere with the ability to do that ? 🤔 |
How about when |
With this PR And it can actually still be worthwhile to enable A2C when using an alpha map and not use alpha test. Some of the articles I referenced in this comment discuss how A2C can be used to alleviate some of the apparent volume loss when using alpha test with texture mipmaps, though there may need to be other changes needed to make this "just work". That's all to say that A2C has a variety of uses beyond just the ones added here so I don't think this should be an automatically toggled. |
Yes, sorry. I was basically reconsidering
Mainly looking for API suggestions that make this more intuitive for new devs. |
I don't know. I don't think we can but perhaps I'm just overly detail oriented. I actually removed the "alpha to coverage" toggle for the
I hesitate to use names that obscure what's actually happening. "Alpha To Coverage" is a searchable term that gives information on what's actually happening at the GPU level and I think that's a good thing. Something like "alphaTestSmooth" also implies this only works in a single use case -- it doesn't. End users can write shaders with the alpha to coverage behavior in mind to get smooth edges with procedural fragment shaders and has benefits even when alphaTest isn't bein used.
This API feature is referred to as "alpha to coverage" in Vulkan, DirectX, and WebGPU. |
@mrdoob I see it hasn't been added to any milestone -- is this blocked because it can't be implicitly enabled? This PR just enhances the existing Material.alphaToCoverage flag and doesn't add any new APIs so if we wanted to reevaluate how alphaToCoverage is toggled I think that could happen in a future PR. |
vec4 diffuseColor = vec4( diffuse, opacity ); | ||
#include <clipping_planes_fragment> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious, what's the reason for moving the call to the clipping code below the calculation for the diffuse color, in many of the shaders?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clipping fragment code block now multiples into the diffuse color alpha to perform the alpha test AA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, makes sense. Thanks for explaning
# Conflicts: # src/renderers/webgl/WebGLPrograms.js
I remember a tool that did show the diff as red/pink pixels or something similar. However, I don't know anymore how it was used and whether it was ever integrated in the CI. |
It is an essential part of the E2E test -- the difference screenshots are autogenerated, so you can just download the artefact from the run and see them there. |
Thanks - finding the artifacts in the Github UI is non trivial. I've reverted example changes since it's possible there are small differences in how the CI and my local machine are performing A2C sampling:
You can see they're both anti-aliased at the stipe edgues but still look different. The last issue is with
|
|
@sunag thank you! Well this is ready to merge, again, if we could. |
Related issue: --
Description
This PR is a draft to add a
#define
forALPHA_TO_COVERAGE
to materials whenmaterial.alphaToCoverage = true
and updates materials clipping planes to take advantage of the option to antialias clipped edges. I don't expect that thealphaToCoverage
field will be toggled frequently so hopefully adding a new define in this case is okay. The define can eventually be used for other applications like smoothing aliased edges whenalphaTest
is true. If the feature is agreeable I can go ahead and make the rest of the needed changes.A couple things to be aware of:
transparent = true
objects which is probably not worth it. Or we could just use the new clipping method code always which will work even if alpha to coverage = false but be slightly more expensive.Some updated demos with an "alphaToCoverage" GUI toggle:
webgl_clipping
webgl_clipping_intersection
webgl_clipping_stencil
And some images: