0
\$\begingroup\$

A bit novice on directx11. I am rendering some textured quads out of PNG files (with alpha transparency) and get some inconsistency with my alpha blending. I have a background changing color constantly and you can see transparency is there , since in the transparent bits of the texture you can see the background colour below.

enter image description here

However , when it comes to having one texture on top of another it seems to skip the one below and use the background colour instead!

enter image description here

I can provide some code but I don't exactly know where to problem might sprawl from yet.

Any ideas? Thanks!

\$\endgroup\$
  • \$\begingroup\$ You should take a look at DirectX Tool Kit for DX11, in particular the SpriteBatch and CommonStates classes. \$\endgroup\$ – Chuck Walbourn Mar 8 '18 at 17:32
  • \$\begingroup\$ Thank you! Summarizing i was able to finalize my DX unit by using the DXTK, which greatly took a lot of abstraction away. \$\endgroup\$ – Javier Dieguez Oct 1 '18 at 17:30
1
\$\begingroup\$

You need to set your alpha blending state according to the effect you want to achieve. In the Output Merge Stage (when you combine the objects you're drawing with the backbuffer) the blending occours for each pixel according to the following equation:

finalColor = backbufferColor * DestBlend + pixelColor * SrcBlend
(same for alpha)

In your case I think you wonna set

SrcBlend = D3D11_BLEND_SRC_ALPHA;
DestBlend = D3D11_BLEND_INV_SRC_ALPHA;

For example if your current alpha is 0.1 (the pixel is almost trasparent) you'll get:

finalColor = backBufferColor * 0.9 + pixelColor * 0.1

which is the effect you need, I think.

Sources:

https://msdn.microsoft.com/en-us/library/windows/desktop/ff476087(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ff476200(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ff476086(v=vs.85).aspx

Then you need to render first the opaque objects to fill the backbuffer with the colors you're going to blend with the transparent pixels. You also need to sort the transparent objects you're going to render based on their depth (you render first the deepest), since the blending operation is not commutative (using INV_SRC_ALPHA and SRC_ALPHA). A normal rendering pipeline is (using z testing):

-turn on z writing (in depth stencil state)
-render all opaque objects
-turn off z writing
-render all transparent objects from the farthest to the nearest

In you're case I think you're first rendering the cross and then the rectangle so you're blending the transparent pixels of the cross quad with what there's on the depth buffer: the background colour. Since the depth writing is on, you block the rendering of other pixels with the same depth (the blue rectangle's ones).

If you only mind to use completely transparent or opaque objects (not alpha = 0.5 for example) you can use the discard() function in you're pixel shader based on an alpha threshold:

If(pixel.aplha < 0.01f) discard()

This function blocks the pixel before it reaches the Output Merging stage, as if I hasn't ever existed and so you don't write is depth, allowing other pixels to be rendered in that position. If this is your case you can render everything in one pass discarding those pixels.

On a side note: order indipendent transparency (OIT) is a difficult topic which is still being researched I think. You'll still probably get pretty consistent results if you don't order the transparent objects (I think it depends on the variance of the alpha channel of the different quads/pixels).

I hope I've been clear enough. Ask for everything :)

\$\endgroup\$
  • \$\begingroup\$ You should also be aware of the concept of 'premultiplied alpha'. See this blog post \$\endgroup\$ – Chuck Walbourn Mar 8 '18 at 17:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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