<p>The “blend factors” are the amount that the specified component is multiplied by while blending. “Destination” is the existing content that’s being blended “on top of”, while “source” is the new content that’s being blended “onto” it. When the blend operation is set to “add”, the final pixel value is calculated like this:</p>
<pre><code>value = source * sourceBlendFactor + destination * destinationBlendFactor
</code></pre>
<p>…so a blend factor of “one” means the value is used unchanged (multiplied by 1), “[x]Alpha” means the value is multiplied by the alpha value of x (source or destination), and “oneMinus[x]Alpha” means the value is multiplied by (1 - the alpha value of x).</p>
<p>For additive blending, you most likely want the following:</p>
<p>Objective-C:</p>
<pre><code>descriptor.colorAttachments[0].blendingEnabled = YES;
descriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOne;
descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOne;
</code></pre>
<p>Swift 5:</p>
<pre><code>descriptor.colorAttachments.colorAttachments[0].isBlendingEnabled = true
descriptor.colorAttachments.colorAttachments[0].rgbBlendOperation = .add
descriptor.colorAttachments.colorAttachments[0].alphaBlendOperation = .add
descriptor.colorAttachments.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
descriptor.colorAttachments.colorAttachments[0].sourceAlphaBlendFactor = .one
descriptor.colorAttachments.colorAttachments[0].destinationRGBBlendFactor = .one
descriptor.colorAttachments.colorAttachments[0].destinationAlphaBlendFactor = .one
</code></pre>
<p>There’s a really helpful tool for visualizing the different options <a href="https://www.andersriggelsen.dk/glblendfunc.php" rel="nofollow noreferrer">here</a>—it’s written for OpenGL, but the Metal stuff works the same way.</p>

CC BY-SA 4.0
2018-08-27T17:47:34.297Z
In Metal there is a blend factor of sourceColor as well as one called "one" whaw would source color look like? Would that just be the color squared or something?
J.Doe
CC BY-SA 4.0
2018-08-27T17:52:16.390Z
Yeah, exactly. There’s some interesting things you could do with that, but I haven’t seen it used much. You can make a “multiply” blend mode by setting the source blend mode to “destinationColor” and the destination one’s to “zero” (or vice versa).
Noah Witherspoon
CC BY-SA 4.0
2018-08-28T06:38:45.923Z
why do you set sourceRGBBlendFactor to BlendFactorSourceAlpha. Is this an error?
J.Doe
CC BY-SA 4.0
2018-08-28T15:14:29.030Z
No—it allows you to modulate the amount of color being added with the pixel’s alpha value, just like changing a Screen layer’s opacity in Photoshop.
Noah Witherspoon
CC BY-SA 4.0
2018-08-27T17:38:40.370Z
2020-08-11T18:04:18.350Z
2020-08-11T18:04:18.350Z
Noah Witherspoon
<h1>Terminology</h1>

<ul>
<li>The <em>source</em> color is the value written by the fragment/pixel shader. </li>
<li>The <em>destination</em> color is the color from the image currently in the frame buffer (that will be overridden).</li>
</ul>

<h1>Additive blending</h1>

<pre><code>// The blend formula is defined as:
// (source.rgb * sourceRGBBlendFactor  )   rgbBlendOperation (destination.rgb * destinationRGBBlendFactor  ) 
// (source.a   * sourceAlphaBlendFactor) alphaBlendOperation (destination.a   * destinationAlphaBlendFactor)
// &lt;=&gt;
// (source.rgba * 1) + (destination.rgba * 1)

descriptor.colorAttachments[0].blendingEnabled             = YES;
descriptor.colorAttachments[0].rgbBlendOperation           = MTLBlendOperationAdd;
descriptor.colorAttachments[0].alphaBlendOperation         = MTLBlendOperationAdd;
descriptor.colorAttachments[0].sourceRGBBlendFactor        = MTLBlendFactorOne;
descriptor.colorAttachments[0].sourceAlphaBlendFactor      = MTLBlendFactorOne;
descriptor.colorAttachments[0].destinationRGBBlendFactor   = MTLBlendFactorOne;
descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOne;
</code></pre>

<p>If the clear color is equal to <code>{0.0f,0.0f,0.0f,_}</code> and we draw <code>{0.1f,0.1f,0.1f,_}</code> to the same pixel a couple of times, the pixel color eventually becomes <code>{1.0f,1.0f,1.0f,_}</code> (white). Drawing <code>{0.0f,0.0f,0.0f,_}</code> (black) has no effect. We do not care about the alphas.</p>

CC BY-SA 4.0
2018-08-27T17:41:08.107Z
Can you explain blend factors. Why is the factor one rather than source color?
J.Doe
CC BY-SA 4.0
2018-08-27T17:43:10.607Z
Since you said in the comments above that you want the following blend equation: `dst.rgba` <- `src.rgba` + `dst.rgba` which basically adds the new color to the old one (so you multiply by 1)?
Matthias
CC BY-SA 4.0
2018-08-27T17:44:46.633Z
So the factor is just a scalar on the RGBA values before they are added?
J.Doe
CC BY-SA 4.0
2018-08-27T17:46:59.540Z
@J.Doe It could also be a vector: you can multiply `dst.rgba` with `src.rgba` for instance and you can also multiply with a constant color. But for additive blending, you just want to do an addition.
Matthias
CC BY-SA 4.0
2018-08-27T15:01:04.483Z
2018-08-27T18:40:53.603Z
2018-08-27T18:40:53.603Z
Matthias
<p>Forgive me, I dont really understand the basis of alpha blending. Like I know the formula but when it comes to the terms blending operation, source blend factor, and destination blend factor I am absolutely lost.</p>

<p>The goal is to do additive blending like in photoshop so black items would be invisible and items with any color would add their color resulting in an effect that pixels with many layers underneath are close to white.</p>

<p>The problem is I have no clue how to translate this to metal. For example this is how I am currently doing alpha blending (although t<a href="https://stackoverflow.com/questions/52035162/metal-alpha-blending-is-not-working">his currently isnt working</a> for whatever reason). What should I be doing for additive blending?</p>

<pre><code>descriptor.colorAttachments[0].blendingEnabled = YES;
descriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
</code></pre>

CC BY-SA 4.0
2018-08-27T17:04:25.380Z
What is stored in the frame buffer or what is the clear color?
Matthias
CC BY-SA 4.0
2018-08-27T17:23:44.917Z
The clear color is black. What do you mean what is stored in the frame buffer?
J.Doe
CC BY-SA 4.0
2018-08-27T17:30:25.373Z
You could already start with some kind of image generated during a previous pass.
Matthias
CC BY-SA 4.0
2018-08-27T17:32:11.590Z
So you basically want to use the following blend equation `dst.rgba <- src.rgba + dst.rgba`? The more non-black draws to a pixel, the larger the pixel color becomes (i.e. goes to white).
Matthias
CC BY-SA 4.0
2018-08-27T17:34:54.020Z
@Matthias Correct!
J.Doe
CC BY-SA 4.0
2018-08-27T17:39:20.643Z
Then I updated my answer with the additive blend state that you need to use.
Matthias
<blending><metal><alpha>
How to perform additive blending in Metal. What do these terms mean?
J.Doe
# How to perform additive blending in Metal. What do these terms mean?

(Asked by: username_0 on 2018-08-27)

Forgive me, I dont really understand the basis of alpha blending. Like I know the formula but when it comes to the terms blending operation, source blend factor, and destination blend factor I am absolutely lost.

The goal is to do additive blending like in photoshop so black items would be invisible and items with any color would add their color resulting in an effect that pixels with many layers underneath are close to white.

The problem is I have no clue how to translate this to metal. For example this is how I am currently doing alpha blending (although t[his currently isnt working](https://stackoverflow.com/questions/52035162/metal-alpha-blending-is-not-working) for whatever reason). What should I be doing for additive blending?

```
descriptor.colorAttachments[0].blendingEnabled = YES;
descriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;

```

**Tags:** blending, metal, alpha

> **Comments:**
> **username_1**: What is stored in the frame buffer or what is the clear color?  
> **username_0**: The clear color is black. What do you mean what is stored in the frame buffer?  
> **username_1**: You could already start with some kind of image generated during a previous pass.  
> **username_1**: So you basically want to use the following blend equation `dst.rgba <- src.rgba + dst.rgba`? The more non-black draws to a pixel, the larger the pixel color becomes (i.e. goes to white).  
> **username_0**: @username_1 Correct!  
> **username_1**: Then I updated my answer with the additive blend state that you need to use.  

---

## 2 answers

### Answer by username_2 on 2018-08-27. Score: 5

The “blend factors” are the amount that the specified component is multiplied by while blending. “Destination” is the existing content that’s being blended “on top of”, while “source” is the new content that’s being blended “onto” it. When the blend operation is set to “add”, the final pixel value is calculated like this:

```
value = source * sourceBlendFactor + destination * destinationBlendFactor

```

…so a blend factor of “one” means the value is used unchanged (multiplied by 1), “[x]Alpha” means the value is multiplied by the alpha value of x (source or destination), and “oneMinus[x]Alpha” means the value is multiplied by (1 - the alpha value of x).

For additive blending, you most likely want the following:

Objective-C:

```
descriptor.colorAttachments[0].blendingEnabled = YES;
descriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOne;
descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOne;

```

Swift 5:

```
descriptor.colorAttachments.colorAttachments[0].isBlendingEnabled = true
descriptor.colorAttachments.colorAttachments[0].rgbBlendOperation = .add
descriptor.colorAttachments.colorAttachments[0].alphaBlendOperation = .add
descriptor.colorAttachments.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
descriptor.colorAttachments.colorAttachments[0].sourceAlphaBlendFactor = .one
descriptor.colorAttachments.colorAttachments[0].destinationRGBBlendFactor = .one
descriptor.colorAttachments.colorAttachments[0].destinationAlphaBlendFactor = .one

```

There’s a really helpful tool for visualizing the different options [here](https://www.andersriggelsen.dk/glblendfunc.php)—it’s written for OpenGL, but the Metal stuff works the same way.

> **Comments:**
> **username_0**: In Metal there is a blend factor of sourceColor as well as one called "one" whaw would source color look like? Would that just be the color squared or something?  
> **username_2**: Yeah, exactly. There’s some interesting things you could do with that, but I haven’t seen it used much. You can make a “multiply” blend mode by setting the source blend mode to “destinationColor” and the destination one’s to “zero” (or vice versa).  
> **username_0**: why do you set sourceRGBBlendFactor to BlendFactorSourceAlpha. Is this an error?  
> **username_2**: No—it allows you to modulate the amount of color being added with the pixel’s alpha value, just like changing a Screen layer’s opacity in Photoshop.  

---

### Answer by username_1 on 2018-08-27. Score: 1

# Terminology

* The *source* color is the value written by the fragment/pixel shader.
* The *destination* color is the color from the image currently in the frame buffer (that will be overridden).

# Additive blending

```
// The blend formula is defined as:
// (source.rgb * sourceRGBBlendFactor  )   rgbBlendOperation (destination.rgb * destinationRGBBlendFactor  ) 
// (source.a   * sourceAlphaBlendFactor) alphaBlendOperation (destination.a   * destinationAlphaBlendFactor)
// <=>
// (source.rgba * 1) + (destination.rgba * 1)

descriptor.colorAttachments[0].blendingEnabled             = YES;
descriptor.colorAttachments[0].rgbBlendOperation           = MTLBlendOperationAdd;
descriptor.colorAttachments[0].alphaBlendOperation         = MTLBlendOperationAdd;
descriptor.colorAttachments[0].sourceRGBBlendFactor        = MTLBlendFactorOne;
descriptor.colorAttachments[0].sourceAlphaBlendFactor      = MTLBlendFactorOne;
descriptor.colorAttachments[0].destinationRGBBlendFactor   = MTLBlendFactorOne;
descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOne;

```

If the clear color is equal to `{0.0f,0.0f,0.0f,_}` and we draw `{0.1f,0.1f,0.1f,_}` to the same pixel a couple of times, the pixel color eventually becomes `{1.0f,1.0f,1.0f,_}` (white). Drawing `{0.0f,0.0f,0.0f,_}` (black) has no effect. We do not care about the alphas.

> **Comments:**
> **username_0**: Can you explain blend factors. Why is the factor one rather than source color?  
> **username_1**: Since you said in the comments above that you want the following blend equation: `dst.rgba` <- `src.rgba` + `dst.rgba` which basically adds the new color to the old one (so you multiply by 1)?  
> **username_0**: So the factor is just a scalar on the RGBA values before they are added?  
> **username_1**: @username_0 It could also be a vector: you can multiply `dst.rgba` with `src.rgba` for instance and you can also multiply with a constant color. But for additive blending, you just want to do an addition.  

---

