Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

#ActualJTippetts

Posted 11 July 2012 - 06:22 AM

It is not correct to use SourceAlpha, One when using pre-multiplied alpha in order to do an additive blend. The thing with pre-multiplied alpha is that an additive blend is controlled purely by the alpha channel of the source.

Here is the formula for the typical SrcAlpha/OneMinusSrcAlpha blend:

OutColor=Src.rgb*Src.alpha + Dest.rgb*(1-Src.alpha)

Premultiplication merely performs the Src.rgb*Src.alpha step beforehand, so that component of the function can be replaced as so:

OutColor=Src.rgb+Dest.rgb*(1-Src.alpha)

Say you have a typical alpha-blended sprite with alpha of 1 where the colors are non-zero (ie not black, or not supposed to be transparent) and alpha of 0 with rgb=0 otherwise. The alpha is premultiplied. Wherever the color is black and the alpha is 0, the result of the operation is this:
OutColor=0+Dest.rgb*(1-0)
OutColor=Dest.rgb

Meaning that the final pixel is solely what is already in the destination, no blend. Conversely, wherever there is color and an alpha of 1:

OutColor=Src.rgb + Dest.rgba*(1-1)
OutColor=Src.rgb

Meaning that the final pixel is solely what is in the source, none of the destination affects it. Values in between 0 and 1 properly affect it.

Now this assumes that the Src.rgb*src.alpha operation was done as a pre-process pass, so that places where the alpha=0 are set to rgb=0,0,0. What if this is not the case, though? What if you have a pixel in the source with an alpha of 0 and a non-zero rgb?

OutColor=Src.rgb+Dest.rgb*(1-0)
OutColor=Src.rgb+Dest.rgb

The result is an additive blend of Src.rgb and Dest.rgb. No change of blend state is required. By varying the alpha value, you can reduce the power of the additive effect until at 1 it becomes just the standard replacement blend. So by keeping your alpha values close to 0, you can have varying strengths of additive blend, without having to overload the source alpha to 0 and losing your details.

#3JTippetts

Posted 11 July 2012 - 06:21 AM

It is not correct to use SourceAlpha, One when using pre-multiplied alpha in order to do an additive blend. The thing with pre-multiplied alpha is that an additive blend is controlled purely by the alpha channel of the source.

Here is the formula for the typical SrcAlpha/OneMinusSrcAlpha blend:

OutColor=Src.rgb*Src.alpha + Dest.rgb*(1-Src.alpha)

Premultiplication merely performs the Src.rgb*Src.alpha step beforehand, so that component of the function can be replaced as so:

OutColor=Src.rgb+Dest.rgb*(1-Src.alpha)

Say you have a typical alpha-blended sprite with alpha of 1 where the colors are non-zero (ie not black, or not supposed to be transparent) and alpha of 0 with rgb=0 otherwise. The alpha is premultiplied. Wherever the color is black and the alpha is 0, the result of the operation is this:
OutColor=0+Dest.rgb*(1-0)
OutColor=Dest.rgb

Meaning that the final pixel is solely what is already in the destination, no blend. Conversely, wherever there is color and an alpha of 1:

OutColor=Src.rgb + Dest.rgba*(1-1)
OutColor=Src.rgb

Meaning that the final pixel is solely what is in the source, none of the destination affects it. Values in between 0 and 1 properly affect it.

Now this assumes that the Src.rgb*src.alpha operation was done as a pre-process pass, so that places where the alpha=0 are set to rgb=0,0,0. What if this is not the case, though? What if you have a pixel in the source with an alpha of 0 and a non-zero rgb?

OutColor=Src.rgb+Dest.rgb*(1-0)
OutColor=Src.rgb+Dest.rgb

The result is an additive blend of Src.rgb and Dest.rgb. No change of blend state is required. By varying the alpha value, you can reduce the power of the additive effect until at 1 it becomes just the standard replacement blend.

#2JTippetts

Posted 11 July 2012 - 06:17 AM

It is not correct to use SourceAlpha, One when using pre-multiplied alpha in order to do an additive blend. The thing with pre-multiplied alpha is that an additive blend is controlled purely by the alpha channel of the source.

Here is the formula for the typical SrcAlpha/OneMinusSrcAlpha blend:

OutColor=Src.rgb*Src.alpha + Dest.rgb*(1-Src.alpha)

Premultiplication merely performs the Src.rgb*Src.alpha step beforehand, so that component of the function can be replaced as so:

OutColor=Src.rgb+Dest.rgb*(1-Src.alpha)

Say you have a typical alpha-blended sprite with alpha of 1 where the colors are non-zero (ie not black, or not supposed to be transparent) and alpha of 0 with rgb=0 otherwise. The alpha is premultiplied. Wherever the color is black and the alpha is 0, the result of the operation is this:
OutColor=0+Dest.rgb*(1-0)
OutColor=Dest.rgb

Meaning that the final pixel is solely what is already in the destination, no blend. Conversely, wherever there is color and an alpha of 1:

OutColor=Src.rgb + Dest.rgba*(1-1)
OutColor=Src.rgb

Meaning that the final pixel is solely what is in the source, none of the destination affects it. Values in between 0 and 1 properly affect it.

Now this assumes that the Src.rgb*src.alpha operation was done as a pre-process pass, so that places where the alpha=0 are set to rgb=0,0,0. What if this is not the case, though? What if you have a pixel in the source with an alpha of 0 and a non-zero rgb?

OutColor=Src.rgb+Dest.rgb*(1-0)
OutColor=Src.rgb+Dest.rgb

The result is an additive blend of Src.rgb and Dest.rgb. No change of blend state is required. By varying the alpha value, you can reduce the power of the additive effect until at 0 it becomes just the standard replacement blend.

#1JTippetts

Posted 11 July 2012 - 06:13 AM

It is not correct to use SourceAlpha, One when using pre-multiplied alpha in order to do an additive blend. The thing with pre-multiplied alpha is that an additive blend is controlled purely by the alpha channel of the source.

Here is the formula for the typical SrcAlpha/OneMinusSrcAlpha blend:

OutColor=Src.rgb*Src.alpha + Dest.rgb*(1-Src.alpha)

Premultiplication merely performs the Src.rgb*Src.alpha step beforehand.

Say you have a typical alpha-blended sprite with alpha of 1 where the colors are and alpha of 0 where the black is. The alpha is premultiplied. Wherever the texel is black and the alpha is 0, the result of the operation is this:
OutColor=0+Dest.rgba*(1-0)

Meaning that the final pixel is solely what is already in the destination, no blend. Conversely, wherever there is color and an alpha of 1:

OutColor=Src.rgb + Dest.rgba*(1-1)

Meaning that the final pixel is solely what is in the source, none of the destination affects it. Values in between 0 and 1 properly affect it.

Now this assumes that the Src.rgb*src.alpha operation was done as a pre-process pass, so that places where the alpha=0 are set to rgb=0,0,0. What if this is not the case, though? What if you have a pixel in the source with an alpha of 0 and a non-zero rgb?

OutColor=Src.rgb+Dest.rgb*(1-0)

The result is an additive blend of Src.rgb and Dest.rgb. No change of blend state is required. By varying the alpha value, you can reduce the power of the additive effect until at 0 it becomes just the standard replacement blend.

PARTNERS