Short Question about Alpha Blending

Started by
3 comments, last by catrexis 10 years, 7 months ago

Hi =)
I follow the tutorials from rastertek.com (#13 today) and just created my own pikachu-cursor. I took a PNG-File, deleted the background and switched it to a DDS-File. When I view only the alpha-channel of this file, the pikachu is white and the background is black. So far so good...
In his/her Tutorails he added a function called "TurnOnAlphaBlending();", that registers a BlendingState with the following D3D11_BLEND_DESC:


   blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
    blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
    blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
    blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
    blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
    blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
    blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
    blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f;

When I understand alpha blending right, now a Pixel won't be drawn on the screen, if its alpha-channel is 0.0f and you can see what's below it...

But when I draw my Cursor its background is not totally transparent. You can see through but its like you see through a violett glass.

I had to add a few lines in my PixelShader:


if(textureColor.a == 0.0f)
    {
        textureColor = float4(0.0f,0.0f,0.0f,0.0f);
    }

Then I get the result I want.

But I don't know why??? If the alpha-value is zero, that sould be enough, shouldn't it? Why does the color have to be black? Or what sould I change to get the right result without the last lines?

I hope, you can help me =)

Cat

Advertisement

You want this:


blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;

In your case with BLEND_ONE, the source color (the color being written to the backbuffer) was always used, regardless of alpha value. ONE simply means 1, that's always the full color. This was added (BLEND_OP_ADD) to the color which exists already in the backbuffer multiplied by 1 - alpha, because of BLEND_INV_SRC_ALPHA.

The right setting for your case is BLEND_SRC_ALPHA, where the source color is multiplied by the alpha, so if alpha is 0, nothing is written and you don't need your pixel shader "fix".

The resulting equation is:

final_color = source_color * alpha + desc_color * (1 - alpha)

while your wrong equation was:

final_color = source_color * 1 + desc_color * (1 - alpha)

or

final_color = source_color + desc_color * (1 - alpha)

If you want more details about this or about blending in general, just ask ;)

Okay, thanks so far =)

You discribed it very well =)

Just one more question:

In my tutorials, he just switches alpha-blending on when its needed. Couldn't I leave it switched on during the whole drawing process? Or does it speed up the programm, when it doesn't have to evaluate the alpha value?

Yep, you definitely should enable alpha blending only when you need it. It is a relatively expensive operation, so don't use it when there won't be any visible effect at all (when the alpha is 1 anyway).

Ideally you each frame draw first all opaque objects, then enable blending, draw transparent objects and disable blending. And transparent objects should be ordered by their distance from camera (distant first, closer last).

Okay thank you =)

This topic is closed to new replies.

Advertisement