BlendState: Deprecate NORMAL
#105
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Its alpha result part (which isn't specified explicitly, so matches the rgb result part) doesn't make any sense.
dstis the color of the render target / framebuffer,srcis the color of the thing being rendered.BlendState.NORMALisresult.rgb = src.rgb * src.a + dst.rgb * (1-src.a)result.a = src.a * src.a + dst.a * (1-src.a)The rgb part makes sense if you're working with regular alpha blending.
However the alpha part does not because it means that if you e.g. draw a 50% opaque quad (
src.a = 0.5) on a fully opaque background (dst.a = 1), you'll suddenly end up with a partially translucent framebuffer (result.a = 0.5 * 0.5 + 1 * (1-0.5) = 0.25 + 0.5 = 0.75), even though we'd expect it to be opaque given the previous background was already opaque.Similarly you get incorrect results rendering a 50% opaque quad on a 50% opaque background; you'd expect the combination to be 75% opaque (
result.a = 0.75) but it's actually just 50% opaque (result.a = 0.5 * 0.5 + 0.5 * (1 - 0.5) = 0.25 + 0.25 = 0.5).The correct equation to use is
result.a = src.a * 1 + dst.a * (1-src.a)(which makes sense if you think of alpha as "how much it obscures the background").In the first scenario this gives
result.a = 0.5 * 1 + 1 * (1-0.5) = 0.5 + 0.5 = 1as expected.In the second scenario this gives
result.a = 0.5 * 1 + 0.5 * (1-0.5) = 0.5 + 0.25 = 0.75as expected.This PR therefore deprecates
BlendState.NORMALin favor of a newBlendState.ALPHAwhich uses the correct blending (I've called itALPHAbecause it's standard "alpha blending"; considered usingDEFAULTbut that might be confusing because MC only started using it with 1.16, while older versions apparently didn't really know what they were doing either).This PR also adds a
BlendState.PREMULTIPLIED_ALPHAwhich takes the same equation parameters and also applies them to the rgb part. This is a generally superior way of doing blending (e.g. it works correctly when compositing different partially translucent intermediate render results), despite it being not as well known as conventional blending. See these blog posts for explanations: 1 2 3