July 25th, 2023
Blend State is a set of rules in a computer program that tells the GPU how to mix colors. For example, if there's a red object behind a blue object, the computer might need to mix the red and blue colors to show what the human eye would see. This is called Blending. If the colors don't mix the right way, the picture might look strange to us. Blend State helps the computer mix the colors the right way. It can make the difference between a picture looking real and a picture looking off.
When we talk about blending, we have the source color, and the destination color. The source color is the color that the computer is trying to add to the picture, the new color that comes in. The destination color is the color that is already in the picture where the new color is being added. These two colors are what the computer looks at when it decides what the final color will be after blending.
In the RGBA model, every color is described by four numbers. The first three numbers are for Red, Green, and Blue. By changing these three numbers, we can make any color we want. For example, in you pick a pure red color in Photoshop, the values will be 255, 0, 0, indicating that the red channel has the maximum value and the green and blue channels have the minimum value. In hexadecimal the same can be achieved by stringing together three values like this #ff0000
. In Direct3D11 we normalize the values to the range of 0.0f-1.0f
, so we'll get red by using 1.0f, 0.0f, 0.0f
.
The last number is for Alpha, which is a bit different - it tells us how see-through or solid a color is. If a color's Alpha is low, that means the color is very see-through. If a color's Alpha is high, that means the color is very solid, and you cannot see what's behind it.
In Vortice.Windows, you create a blend state by defining a BlendStateDescription
. It decides what color the area of overlap should be. When defining a BlendStateDescription
, you have control over several properties. The IsBlendEnabled
tells your program whether you want to mix colors or not. The SourceBlend
and DestinationBlend
help you program understand how you want to mix the color of your new object (source) with the color already on the screen (destination).
The blend factors decide how much of each color will be in the final mix and blend operations are about how you combine the colors. You have options like Add (adds the colors), Subtract (subtracts one color from the other), or RevSubtract (subtracts the other way around), and so on. We'll be going through these in a moment.
You could blend colors in the pixel shader, but blend state is not applied there. Instead, it's a part of the pipeline that runs after the pixel shader, often called the output merger stage. Here, the final color for a pixel is decided before it gets displayed on the screen. You tell the GPU how to combine the color from the pixel shader with the color that's already on the screen at that pixel's spot. In general, performing blending of two textures using the blend state is more efficient than doing it in the pixel shader. The reason is that blend state operations are specifically designed and optimized for blending colors and transparency during the rendering process.
Render targets are where you draw or render your shapes or objects in your program. Each render target can have different rules about how to mix colors. These rules are part of the blend state settings inside RenderTargetBlendDescription
. Each render target can have its own RenderTargetBlendDescription
, meaning you can set different color mixing rules for different render targets.
In blending, you usually mix the color and alpha of your new object with the color and alpha already on the screen. But sometimes you might want to mix the color and alpha differently. You can mix the color one way and the alpha another way with SourceBlend
and DestinationBlend
for color, and SourceAlphaBlend
and DestinationAlphaBlend
for alpha. By setting these properties, you can control how you mix color and alpha separately.
Blend factors are part of the rules that decide how colors mix in your program. Let's take a look of some blend factors that you might use.
Here's a handy online tool for testing different blend factors and operations. It's for OpenGL, so you might need to use your imagination a bit, but the basic principles are the same.
Visual glBlendFunc + glBlendEquation Tool by Anders Riggelsen
BlendOption.Zero
D3D11_BLEND_ZERO
(0, 0, 0, 0)
Ignores the color it's linked to. If it's used as the source blend, it ignores the color of the new object. If it's used as the destination blend, it ignores the color already on the screen.
BlendOption.One
D3D11_BLEND_ONE
(1, 1, 1, 1)
Keeps the color it's linked to. If it's the source blend, it keeps the color of the new object. If it's the destination blend, it keeps the color already on the screen.
BlendOption.SourceColor
D3D11_BLEND_SRC_COLOR
(Rs, Gs, Bs, As)
Applies the color of the new object. If you're using it as the source blend, it takes the color of the new object and multiplies it. If you're using it as the destination blend, it takes the color of the new object and multiplies the color already on the screen.
BlendOption.DestinationColor
D3D11_BLEND_DEST_COLOR
(Rd, Gd, Bd, Ad)
Uses the color already on the screen. If it's the source blend, it multiplies the color of the new object by the color already on the screen. If it's the destination blend, it multiplies the color already on the screen by itself.
BlendOption.BlendFactor
D3D11_BLEND_BLEND_FACTOR
(Rf, Gf, Bf, Af)
Uses a constant color that you can set yourself. If it's the source blend, it multiplies the color of the new object by this constant color. If it's the destination blend, it multiplies the color already on the screen by this constant color.
BlendOption.Source1Color
D3D11_BLEND_SRC1_COLOR
(Rs1, Gs1, Bs1, As1)
Works the same as BlendOption.SourceColor
, but it uses the color of a second source.
BlendOption.InverseSourceColor
D3D11_BLEND_INV_SRC_COLOR
(1 - Rs, 1 - Gs, 1 - Bs, 1 - As)
Uses the opposite of the color of the new object. If you use it as the source blend, it subtracts the color of the new object from white. If you use it as the destination blend, it subtracts the color of the new object from the color already on the screen.
BlendOption.InverseDestinationColor
D3D11_BLEND_INV_DEST_COLOR
(1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad)
Uses the opposite of the color already on the screen. If it's the source blend, it subtracts the color already on the screen from white, then multiplies the color of the new object. If it's the destination blend, it subtracts the color already on the screen from white, then multiplies the color already on the screen.
BlendOption.InverseBlendFactor
D3D11_BLEND_INV_BLEND_FACTOR
(1 - Rf, 1 - Gf, 1 - Bf, 1 - Af)
Uses the opposite of the constant color that you set. If it's the source blend, it subtracts your constant color from white, then multiplies the color of the new object. If it's the destination blend, it subtracts your constant color from white, then multiplies the color already on the screen.
BlendOption.InverseSource1Color
D3D11_BLEND_INV_SRC1_COLOR
(1 - Rs1, 1 - Gs1, 1 - Bs1, 1 - As1)
Works the same as BlendOption.InverseSourceColor
, but it uses the opposite of the color of a second source.
BlendOption.SourceAlpha
D3D11_BLEND_SRC_ALPHA
(As, As, As, As)
Uses the alpha value of the new object. Alpha value controls transparency. If it's the source blend, it multiplies the color of the new object by its own alpha value. If it's the destination blend, it multiplies the color already on the screen by the alpha value of the new object.
BlendOption.DestinationAlpha
D3D11_BLEND_DEST_ALPHA
(Ad, Ad, Ad, Ad)
Uses the alpha value of the color already on the screen. If it's the source blend, it multiplies the color of the new object by the alpha value of the color already on the screen. If it's the destination blend, it multiplies the color already on the screen by its own alpha value.
BlendOption.SourceAlphaSaturation
D3D11_BLEND_SRC_ALPHA_SAT
(f, f, f, 1), where f = min(As, 1 - Ad)
Saturates the alpha value of the new object. If you use it as the source blend, it multiplies the color of the new object by the lower value between the alpha of the new object and the inverse of the alpha already on the screen. is not suitable for the destination blend.
BlendOption.Source1Alpha
D3D11_BLEND_SRC1_ALPHA
(As1, As1, As1, As1)
Works the same as BlendOption.SourceAlpha
, but it uses the alpha value of a second source.
BlendOption.InverseSourceAlpha
D3D11_BLEND_INV_SRC_ALPHA
(1 - As, 1 - As, 1 - As, 1 - As)
Uses the opposite of the alpha value of the new object. If it's the source blend, it subtracts the alpha value of the new object from 1, then multiplies the color of the new object. If it's the destination blend, it subtracts the alpha value of the new object from 1, then multiplies the color already on the screen.
BlendOption.InverseDestinationAlpha
D3D11_BLEND_INV_DEST_ALPHA
(1 - Ad, 1 - Ad, 1 - Ad, 1 - Ad)
Uses the opposite of the alpha value of the color already on the screen. If it's the source blend, it subtracts the alpha value of the color already on the screen from 1, then multiplies the color of the new object. If it's the destination blend, it subtracts the alpha value of the color already on the screen from 1, then multiplies the color already on the screen.
BlendOption.InverseSource1Alpha
D3D11_BLEND_INV_SRC1_ALPHA
(1 - As1, 1 - As1, 1 - As1, 1 - As1)
Works the same as BlendOption.InverseSourceAlpha
, but it uses the opposite of the alpha value of a second source.
Blend operations are part of the blend state in Vortice.Windows. They decide how we mix the colors of our new shape and the colors already on the screen.
BlendOperation.Add
D3D11_BLEND_OP_ADD
SourceColor + DestinationColor
This operation adds the color of the new shape and the color already on the screen together.
BlendOperation.Subtract
D3D11_BLEND_OP_SUBTRACT
SourceColor - DestinationColor
This operation takes away the color already on the screen from the color of the new shape.
BlendOperation.ReverseSubtract
D3D11_BLEND_OP_REV_SUBTRACT
DestinationColor - SourceColor
This operation takes the color of the new shape from the color already on the screen.
BlendOperation.Min
D3D11_BLEND_OP_MIN
Min(SourceColor, DestinationColor)
This operation picks the smallest value between the color of your new shape and the color already on the screen.
BlendOperation.Max
D3D11_BLEND_OP_MAX
Max(SourceColor, DestinationColor)
This operation picks the largest value between the color of your new shape and the color already on the screen.
BlendOperation.LogicOp
D3D11_BLEND_OP_MIN (with appropriate logic operation)
This blend operation uses logic operations to mix colors. It is more advanced and less commonly used.
Blend state settings can have an impact on how fast your program runs. If your blend state is complex, it might slow things down. If you want to keep your program running fast, here are some things to consider:
Avoiding complex blending: While blending can create cool effects, it's also a bit demanding for your computer. If you use simple blend states like "Opaque"
, it can keep things running smoother.
Reducing overdraw: Overdraw happens when you draw over the same pixel multiple times. Each time you draw on a pixel, the computer has to blend colors. So, less overdraw means less blending, and that can speed up your program.
Careful ordering of drawing operations: The order you draw things can also affect speed. Drawing opaque objects first and then transparent ones can help. This way, the computer might skip blending for pixels covered by opaque objects.
The blend state is set using the OutputMerger.SetBlendState()
function. Changing blend states often can slow down your program. So, plan ahead and change blend states as little as possible. For example, group your drawing operations by blend state. Draw all items with one blend state, then change the state and draw the next group, and so on. Also, remember that more transparency means more blending. If you can get the effect you want with less transparency, go for it. Less blending means faster performance.
In the end, faster performance comes from a good balance. You need to balance the look you want with the speed you need. A fast program is great, but not if it doesn't look the way you want it to. So, make smart choices with your blend state settings. Keep it simple when you can, and only use complex blending when you really need it. And always keep an eye on how your choices affect performance. With some careful planning, you can get the look you want and keep your program running smooth.