Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm using XNA 4.0 to create a 2D game and while implementing a layer tinting pixel shader I noticed that when the texture's alpha value is anything between 1 or 0 the end result is different than expected.

The tinting works from selecting a colour and setting the amount of tint. This is achieved via the shader which works out first the starting colour (for each r, g, b and a) :

float red = texCoord.r * vertexColour.r;

and then the final tinted colour :

output.r = red + (tintColour.r - red) * tintAmount;

The alpha value isn't tinted and is left as :

output.a = texCoord.a * vertexColour.a;

The picture in the link below shows different backdrops against an energy ball object where it's outer glow hasn't blended as I would like it to. The middle two are incorrect as the second non tinted one should not show a glow against a white BG and the third should be entirely invisible.

The blending function is NonPremultiplied.

enter image description here

Why the alpha value is interfering with the final colour?

share|improve this question
2  
It sounds like a classic issue of not using (or using when you shouldn't) pre multiplied alpha values. –  Phil Mar 25 '13 at 23:28
1  
Agreed, it sounds like you want the surrounding glow to be additive while the energy ball is opaque. Classic case where premultiplied-alpha images would do the job. Also, tinting is usually done by multiplying the texture color by the tint color, rather than lerping to the tint color as you have it. –  Nathan Reed Aug 7 '13 at 6:25
add comment

1 Answer

This is the best blend function I've found to achieve the results I wanted. I ended up rejigging the render function for the game so that each object can decide which BlendState it wants to use.

This is the BlendState I used, it's the same as NonPremultiplied except AlphaSourceBlend is changed from Blend.SourceAlpha to Blend.One:

BlendState alphaBlend = new BlendState()
{
    AlphaBlendFunction = BlendFunction.Add,
    AlphaSourceBlend = Blend.One,
    AlphaDestinationBlend = Blend.InverseSourceAlpha,

    ColorBlendFunction = BlendFunction.Add,
    ColorSourceBlend = Blend.SourceAlpha,
    ColorDestinationBlend = Blend.InverseSourceAlpha
};
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.