# Alpha blending woes

This topic is 4180 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have a particle texture with an alpha channel and I'm using Direct3D. After experimentation I found that SrcBlend = SrcAlpha and DestBlend = InvSrcAlpha seems to do what I want (render my particle with a specified color, don't blend with the background, and dont draw the transparent parts of the texture). Short question: I'm trying to make particles fade out. I can change their color but changing the alpha has no effect. I assume this is a blending problem because if I turn it off the particles fade like I expected (but the transparent parts are drawn, obviously). Longer question: What is SrcBlend and DestBlend? I vaguely understand that setting one of these to, say, D3DBLEND_SRCALPHA multiplies all the colors of the texture by the value of the alpha channel, but little else. Apologies if my questions are poor, I'm struggling with a lot of new (to me) things right now.

##### Share on other sites
Quote:
 Original post by AbsolutDewAfter experimentation I found that SrcBlend = SrcAlpha and DestBlend = InvSrcAlpha seems to do what I want (render my particle with a specified color, don't blend with the background, and dont draw the transparent parts of the texture).Longer question: What is SrcBlend and DestBlend?

Basically, these are the parameters to decide how much of the 'src' and 'dest' pixel to put in the replacement pixel that you're generating. 'SrcBlend = SrcAlpha' means 'take an amount from the src image (your particle in this case) proportional to the source's alpha'. 'DestBlend = InvSrcAlpha' means 'take an amount from the dest image (whatever was previously rendered) inversely proportional to the source's alpha'. So if your particle's alpha value for a given pixel was 0.75, the new pixel would be (particleRGB * 0.75) + (screenRGB * 0.25).

Now, I'm no 3D expert, certainly not with modern hardware, so this next advice may no longer apply. However, as well as there being per-pixel alpha (which is in your alpha channel), there is per-vertex alpha, which you specify when sending the polygons to be rendered. By changing this on all applicable vertices from the default of 1.0 to something lower, you can effectively fade out the whole polygon. How to do this probably depends on how you're rendering those particles.

##### Share on other sites
Haven't specifically used it, but it sounds like what your lookin for.

SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true)SetRenderState(D3DRS_SRCBLENDALPHA,D3DBLEND_SRCALPHA)SetRenderState(D3DRS_DESTBLENDALPHA,D3DBLEND_INVSRCALPHA) static int BlendIn;static D3DCOLOR BlendOut;BlendIn = 255; // <-- control transparency here, 0 to 255 valueBlendOut=D3DCOLOR_ARGB(BlendIn,BlendIn,BlendIn,BlendIn);d3ddev->SetRenderState(D3DRS_BLENDFACTOR, BlendOut);SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BLENDFACTOR)SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVBLENDFACTOR)

This should blend your alpha seperately and allow src / dest blending seperately in a fading fashion by controlling the blendfactor :)

Let me know how this works... I'm makin it up as I go.

[Edited by - Ebola0001 on September 8, 2006 6:55:36 AM]

##### Share on other sites
Quote:
 Original post by KylotanBasically, these are the parameters to decide how much of the 'src' and 'dest' pixel to put in the replacement pixel that you're generating. 'SrcBlend = SrcAlpha' means 'take an amount from the src image (your particle in this case) proportional to the source's alpha'. 'DestBlend = InvSrcAlpha' means 'take an amount from the dest image (whatever was previously rendered) inversely proportional to the source's alpha'. So if your particle's alpha value for a given pixel was 0.75, the new pixel would be (particleRGB * 0.75) + (screenRGB * 0.25).

Seems kinda obvious now! Guess I just didn't understand how it fit together.

Quote:
 Original post by Ebola0001This should blend your alpha seperately and allow src / dest blending seperately in a fading fashion by controlling the blendfactor :)

Thanks! I'll try to work with that when I get home. Seems like a lot of extra work though =/ Why doesn't it just use the alpha value from my vertex (like how Kylotan described). Should it be?

##### Share on other sites
Which version of DirectX are you using? Each has different ways of handling things, due to the rapid changes in graphics technology. It is perhaps because you've missed a setting somewhere (D3DRS_ALPHABLENDENABLE?)

##### Share on other sites
Quote:
 Original post by KylotanWhich version of DirectX are you using? Each has different ways of handling things, due to the rapid changes in graphics technology. It is perhaps because you've missed a setting somewhere (D3DRS_ALPHABLENDENABLE?)

I'm using DX9. I'm using a shader to texture/change color of particles (modified and tinkered with from an example I found in the SDK). I'm obviously no shader expert but I've looked up everything I'm using and to the best of my understanding this isn't doing anything more than setting the texture and vertex color as if I'd done it in code (though it seems a bit like voodoo to me!), it's just convenient for me to "script" my rendering.

float4 Color;VSTEXTURE_OUTPUT VSTexture    (    float4 Position : POSITION,     float3 Normal   : NORMAL,    float2 TexCoord : TEXCOORD0    ){    VSTEXTURE_OUTPUT Out = (VSTEXTURE_OUTPUT)0;    float3 P = mul(Position, World);                    // position (view space)    P = mul(float4(P, 1), View);                    // position (view space)       Out.Position = mul(float4(P, 1), Projection);   // projected position    Out.Diffuse  = Color;    Out.TexCoord = TexCoord;                        // texture coordinates        return Out;    }pass PTexture{    // single texture/one directional light shader    VertexShader = compile vs_1_1 VSTexture();    PixelShader  = NULL;            // texture    Texture[0] = (Tex0);    // enable alpha blending    AlphaBlendEnable = TRUE;    ZWriteEnable     = FALSE;    Lighting         = FALSE;    SrcBlend         = SrcAlpha;    DestBlend        = InvSrcAlpha;}

And then each frame I use:

D3DXCOLOR newColor;newColor.a = 0.5f;newColor.r = 1.0f;newColor.g = 0.0f;newColor.b = 0.0f;pEffect->SetFloatArray("Color", newColor, 4);

But no matter what I set a to, it's always rendered fully visible as if a = 1, though I can change the color with r, g, b to whatever I like.

##### Share on other sites
I am only familiar with the fixed-function pipeline, not shaders, so can't really help here. You could try asking on the DirectX forum if you're still having trouble though.