Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Blending and the GPU
If you open Photoshop and look at the layer panel, you can see a list of blending operations that are available to composite layers together:
![[Pasted image 20260328113313.png]]
This list is far longer than the blend modes [available in Processing](https://processing.org/reference/blendMode_.html), why?
This is because, in the context of a render pipeline, [blending or blend state](https://www.w3.org/TR/webgpu/#blend-state) is defined via [fixed function hardware](https://en.wikipedia.org/wiki/Fixed-function_(computer_graphics)) that defines how the GPU moves pixels into a color target (i.e. texture, framebuffer, etc.) after a fragment shader has run. More specifically, many useful compositing operations make use of division, which is [expensive for computers](https://en.wikipedia.org/wiki/Division_algorithm) and thus not implemented in fixed function graphics pipelines.
Alpha blending and render phases
In a traditional game engine like Bevy, objects in a 3d scene are drawn in the following order: first, all opaque items are drawn with depth buffer writes enabled. This allows for aggressive batching as items that are occluded by other objects will be rejected by the early Z test. In other words, the draws can be unordered. After this, transparent and transmissive materials that require alpha blending are drawn back to front, i.e. are sorted.
Typically, this means that transparent materials are substantially more expensive as, in the worst case, they may require constantly switching pipelines as items are drawn one by one.
With respect to blending, this means that most materials are either blended via "replace" (i.e. opaque, where one item fully occludes another) or alpha blending. Bevy's
[AlphaMode](https://docs.rs/bevy/latest/bevy/prelude/enum.AlphaMode.html)supports other modes that are less frequently used for some materials that are typically on the VFX spectrum (fire, laser beams, etc).Processing and batching
The default blend mode for Processing
BLENDi.e. alpha blending. We adopt this same convention but are doing some additional magic behind the scene. Because libprocessing is built on top of Bevy, we aggressively take advantage of Bevy's built in material batching in order to reduce the number of draw calls we issue.In the core render loop, in between each flush, we detect whether what the user is drawing actually requires alpha blending (i.e. whether the alpha channel is set) and only set the blend mode for items that do. Thus, from the perspective of the user, alpha blending "just works", but in our implementation if the user does not ever draw items that use alpha we will efficiently dispatch all their items in a single draw.
Recent [changed to Bevy](bevyengine/bevy#23005) now allow transparent items that share a render pipeline to be [drawn together](https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_multi_draw.html). This is also helpful as it eliminates a major source of overhead
ProcessingMaterialIn order to facilitate changing arbitrary
[BlendState](https://docs.rs/wgpu/latest/wgpu/struct.BlendState.html)beyond what Bevy supports viaAlphaMode, we need to have a custom specialization function. As such, we now use anExtendedMaterialthat wrapsStandardMaterial. We still use the default PBR shaders, so aren't customizing the material uniform at all here, but this allows us to override the PBR shader's blend mode.We also perform a similar trick in custom material support.