#Additive blending on sprites

7 messages · Page 1 of 1 (latest)

vagrant mason
#

I am trying to make certain sprites blend additively by using Bevy's sprite pipeline copied to my own app and adding a BlendState.
The BlendState is as follows:

BlendState {
    color: BlendComponent {
        src_factor: BlendFactor::SrcAlpha,
        dst_factor: BlendFactor::One,
        operation: BlendOperation::Add,
    },
    alpha: BlendComponent {
        src_factor: BlendFactor::SrcAlpha,
        dst_factor: BlendFactor::One,
        operation: BlendOperation::Add,
    },
}

With this, I assume that the alpha is squared as the src_factor of the alpha is itself.
So for example: if the alpha is 0.5, it will become 0.25.
And the color will be multiplied by this alpha since the src_factor is alpha.
So color of rgb(255, 0, 0) should become rgb(64, 0, 0).

However, by using a color picker on the resulting color with the background as black, the resulting color is rgb(187, 0, 0).
Also by using it on a back ground of rgb(28, 115, 112), the result becomes rgb(189, 115, 112). And 28 + 187 definitely isn't 189.
So it's not adding them.

Since I am new to graphics programming, I might have misunderstood how the blending function works.
Is additive blending possible?

grave dirge
vagrant mason
#

Additive blending on sprites

vagrant mason
# grave dirge I'd suggest looking over this PR. I don't have an exact answer, but I believe it...

After looking through the code, it uses BlendState::PREMULTIPLIED_ALPHA_BLENDING.
Which means each of the two components are set to BlendComponent::OVER.
Giving a blend equation of (1 * src) + ((1 - src_alpha) * dst) for color and alpha.
In the shaders, the color is multiplied by alpha then the alpha is set to zero for additive blending.
The equation then becomes:

  • Color: src*src_alpha + dst
  • Alpha: dst

I attempt to replicate this by making my BlendState as follows:

BlendState {
    color: BlendComponent {
        src_factor: BlendFactor::SrcAlpha,
        dst_factor: BlendFactor::One,
        operation: BlendOperation::Add,
    },
    alpha: BlendComponent {
        src_factor: BlendFactor::Zero,
        dst_factor: BlendFactor::One,
        operation: BlendOperation::Add,
    },
}

So the source alpha will be multiplied by zero then added to destination, which will result in no change.

However, the result was not correct either.
0.5 alpha with color rgb(255, 0, 0) on black still gives rgb(187, 0, 0), which is incorrect.
Correct color should be rgb(255, 0, 0) * 0.5 + rgb(0, 0, 0) = rgb(128, 0, 0).

And it seems that it's still not adding:
By using it on a background of rgb(28, 115, 112), the color becomes rgb(189, 115, 112).

grave dirge
vagrant mason