Sign in to follow this  
michaelruecker

Blending black area invisible

Recommended Posts

michaelruecker    196

I am currently stuck with a blending problem.

 

Basically I am having a lot of billboards each with an image and some black space around that image. All I want is to replace that black color with whatever is in the background so that it becomes invisible.

 

Original billboard image:

smiley.jpg

 

Background:

background.jpg

 

Expected result:

result_expected.jpg

 

Yet I have tried everything I could imagine with my BlendStateDescription, DepthStencil and BlendFactor. Nothing bringt me to my expected result.

 

Without blending I get the following result: (As expected)

 

result_no_blending.jpg

 

With :

blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
 
Or:
 
blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
 
I get:
 
result_add.jpg
 
As stated earlier I have tried a hundred other combinations. Nothing successful yet. 
 
Also I thought when I set my BlendFactor to {0.0f, 0.0f, 0.0f, 0.0f) it would handle the black color as my alpha channel. But it aparently does not. Actually nothing I do with SrcBlendAlpha, DestBlendAlpha and BlendOpAlpha has ANY effect.
 

Share this post


Link to post
Share on other sites
haegarr    7372

Alpha masking (D3D11_BLEND_SRC_ALPHA and companions) requires an alpha channel provided by the billboard. From your description it isn't clear whether such a channel is available .. the OP mentioned to use the black color as mask. What is the case?

 

Although not familiar with D3D, I would expect  

blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
to work in case that the billboard provides an alpha (where alpha = 0 means full transparency), and the billboard isn't pre-multiplied by alpha. This does a calculation like so:
   colordest := ( 1 - alphasrc ) * colordest + alphasrc * colorsrc
 
If, on the other hand, the billboard is pre-multiplied, then
blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;

should do the job:

   colordest := ( 1 - alphasrc ) * colordest + 1 * colorsrc,pre
Edited by haegarr

Share this post


Link to post
Share on other sites
Juliean    7068

blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;

 

This setting achieves something called aditive blending, where both your new image and the content of the background are added together, to achieve the final color. It should work with:

blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRCALPHA;
blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRCALPHA;
blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;

This takes the new image * new image alpha + background * (1 -  new image alpha). I'm not to sure if the constants are named 100% correct, just look for the correct equivalent. The one thing that was incorrect in your example is therefore the operation on the background (dest), with one the background color is always considered 100% in the output.

Edited by Juliean

Share this post


Link to post
Share on other sites
michaelruecker    196

Thank you both!

 

Apparently I had no alpha channel in my image, that's why it never worked.

 

Since I am not using additive blending now, my billboards flipping from back to front and vice versa. (In some frames billboard 1 is in front of 2 and then in the next frame it is the other way around)

 

I guess I have to sort the billboards by depth now am I correct about this or is there another way?

Share this post


Link to post
Share on other sites
Juliean    7068

I guess I have to sort the billboards by depth now am I correct about this or is there another way?

 

For pictures that consist only of solid (1.0f alpha) and completely-transparent (0.0f alpha) pixels, you can clip(image.a > 0.0001f ? 1 : -1) in the pixel shader (refered to as "alpha-testing", and continue using the zbuffer. In this case though, you don't need to enable alpha blending at all. Otherwise, if not usign additive/subtractive blending, you have little choice but to do sorting.

Edited by Juliean

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this