Alpha blending varying from one run to the next?

Started by
8 comments, last by trojanfoe 6 years, 1 month ago

Hi there, I have an issue with the SpriteRenderer I have developed.  I seem to be getting different alpha blending from one run to the next.

run2.thumb.png.06a31d8f93e279af6aebae616d30dce5.pngrun1.thumb.png.3ff6d548a4bb5d34070e4e908452d9c4.png

I am using DirectXTK and have followed the advise in the wiki and have converted all my sprite images to pre-multiplied alpha using TexConv.exe:


texconv -pow2 -pmalpha -m 1 -f BC3_UNORM -dx10 -y -o Tests\Resources\Images Tests\ResourceInput\Images\*.png

and here is the code that applies the blend states (using the DIrectXTK CommonStates class):


ID3D11BlendState* blendState = premultAlphas ? m_commonStates->AlphaBlend() : m_commonStates->NonPremultiplied();
m_deviceContext->OMSetBlendState(blendState, nullptr, 0xffffffff);

Can anyone think of what I am doing wrong?

Indie Game Dev

Advertisement

OK, so it looks like it's the depth state that are interfering with it.  If I turn off the depth tests and draw back-to-front by z-order, I get the desired results:

run3.thumb.png.c1f6024fe856d456cb92e9ae02ac7ba1.png

 

So it looks like I have more to learn :)

Indie Game Dev

3 hours ago, trojanfoe said:

If I turn off the depth tests and draw back-to-front by z-order, I get the desired results

This is a very common issue with alpha-blending. The depth buffer is written to even for fully transparent pixels, so if the transparent object is drawn first, the opaque object behind it will fail the depth test.

Your sprite looks pretty hard-edged, you might be able to get away with just using alpha-testing instead (which doesn't suffer from this issue).

Otherwise, the standard approach is to first render all opaque objects normally, then render all alpha-blended objects sorted from back-to-front.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Hey thanks for the reply.  I seem to be getting pretty good results by sorting back-to-front and then by texture, so I will just dump the depth state stuff altogether.

Indie Game Dev

1 hour ago, trojanfoe said:

I seem to be getting pretty good results by sorting back-to-front and then by texture, so I will just dump the depth state stuff altogether.

Aye, that's reasonable.

In many games the opaque objects in a scene massively outnumber the transparent objects, so you can save a lot of processing by only sorting the transparent objects.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

yes that seems a good way.

A depth stencil is only of use if its used to block other later draws.

Hi CortexDragon, you originally had lots of interesting looking information in your reply about how various techniques could be used to do this properly, but you edited it away.  Why was that?

Indie Game Dev

On 06/03/2018 at 7:28 AM, trojanfoe said:

Hi CortexDragon, you originally had lots of interesting looking information in your reply about how various techniques could be used to do this properly, but you edited it away.  Why was that?

I had described a generic way for a 3d renderer with transparency and using [earlydepthstencil], but realised since your things in front are rather small (you dont have large opaque objects in front of other opaque objects), I realised that your way of not using depth testing might be faster for your situation.

I had written something like this, which allowed you to take advantage of [earlydepthstencil] :-

1. First draw opaque (non transparent) objects front to back with depth test enabled, depth write enabled, and [earlydepthstencil].

2. Then draw transparent objects back to front with depth test enabled, depth write DISABLED and [earlydepthstencil]

The reason the opaque objects are drawn front to back is so further back objects that are drawn later and are blocked by closer objects will bypass their pixel shaders due to [earlydepthstencil]

The reason for the transparent objects depth test is to not draw those that would be blocked by the non transparent ones that had been previously drawn. Their depth write is disabled so they dont accidently block something drawn behind them later due to incorrect sorting of the back to front

 

Hey thanks for the information CortexDragon.

Indie Game Dev

This topic is closed to new replies.

Advertisement