Blending Colors with Metal the same way as iOS
When working with Metal shaders, you might need to blend two colors together. If both colors are fully opaque its very simple: use the top color.
Things get a little interesting when one or both colors are translucent. There are multiple ways to blend translucent colors together. Ideally, we want to find an approach that matches iOS’s native behavior.
If you read about alpha compositing, there are two common methods of blending translucent colors: straight alpha and premultiplied alpha. After some testing, I found that iOS normal blend mode closely resembles premultiplied alpha. Straight alpha is noticably different.
The, the actual implementation of the color blending is straightforward:
// In your metal file
half4 colorBlend(
half4 bottomColor,
half4 topColor)
{
half a_0 = topColor.a + bottomColor.a * (1 - topColor.a);
half3 c_0 = topColor.rgb + (bottomColor.rgb * (1 - topColor.a));
return half4(c_0, a_0);
}This will give you color blending behavior that matches native iOS rendering!
Examples
Here are a few visual tests that compare the metal blendingto iOS’s native blending.
Get Kieraj Mumick’s stories in your inbox
Join Medium for free to get updates from this writer.
For each test:
- I picked two colors: a top color and a bottom color.
- On the left, I used a shader that implements the
colorBlendfunction above. - On the right, I used two
ZStack-ed rectangles in SwiftUI to let iOS perform the native blending.
Behind both versions, I added the text “Hello world” to help evaluate transparency.
When comparing the results, I looked at two things:
- Hue Matching — Do the blended colors look visually similar?
- Transparency Matching — Is the visibility of the text behind them roughly the same?
In the image below, you can see that the results are nearly identical in both hue and transparency. That tells us this blending logic is a good match for what iOS does.








