Alpha Blending Backwards?

Started by
5 comments, last by sbroumley 18 years, 4 months ago
Hello, in learning to program DirectX, I believe I've come across a bug in transparency in my program. Screenshot 1 (~280Kb) is how the demo is supposed to look. This is an image of an alpha blended textured quad, above a no-alpha textured polygon, all above another alpha-blended textured quad. The scene looks fine from above, you can see all three objects through the top alpha-blended quad, as seen in Screenshot 1, HOWEVER, when the camera is below the scene, looking upwards, this is a different issue. When seen from below (See screenshot 2) the bottom-most textured quad is improperly alpha-blended. When seen looking-through the bottom quad, one cannot see the top-most quad, yet you can see the un-alpha-blended textued poly in the middle! Try the .exe, you'll see what I mean. 1 . For reference, my alpha-blending code is:

D3D_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
D3D_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
D3D_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);



[Edited by - Muhammad Haggag on December 6, 2005 9:35:33 AM]
Advertisement
It's not actually a transparency bug that you've encountered, alpha blended objects are generally supposed to be rendered in order from furthest to closest. Depth testing every object is a lot of work though, so there is a flag that will give you the results you are looking for. Before you render your alpha blended objects set these flags:

D3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, true);D3DDevice->SetRenderState(D3DRS_ALPHAREF, 0x00000088);D3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);


And when you are done just turn the alpha test off, like so:

D3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);


Hope that helps,
-Chris
Sorry, this did not help. I am getting the same results as the first time. If I am not mistaken, aren't AlphaRef and AlphaFunc only relevant when performing Alpha Testing to see if the alpha levels are above a certain level? I don't see how this would help...
You may have misunderstood bengaltgrs. He was saying that you MUST render these objects from 'furthest-from-camera' to 'closest-to-camera' which requires a bit of sorting.

Quote:
aren't AlphaRef and AlphaFunc only relevant when performing Alpha Testing to see if the alpha levels are above a certain level

Exactly. Even if a pixel is completely transparent it is still drawn and as well as sent to the z-buffer. Alpha-testing can be used to alleviate z-buffer issues as well as improve performance by skipping over these pixels.
Please do not inline large images (larger than 80Kb). Your original post contained 2 embedded images weighing in at half a megabyte - someone at 56K would've definitely committed suicide [smile].

One consideration is that alpha blending objects like that don't require depth buffering. That's where you bug is coming from, the first object is writing to the depth buffer (the lower plane), then the top plane is, but it's being depth tested out. These things should be alpha blended over the scene. Compare to the depth buffer, but don't write to it, and it should solve your problem.
A nice easy method for fixing such problems is to use an additive blend mode instead of a multiply blend mode. This way it doesn't matter what order you render the primitives in.

The settings are something like this:

// Turn on additive blend mode
D3D_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
D3D_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
D3D_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

// Turn off Z write, but still perform Z test
D3D_Device->SetRenderState(D3DRS_ZWRITEENABLE,0);
D3D_Device->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE);

You will also have to tweak the artwork to get the desired look.
Steve Broumley

This topic is closed to new replies.

Advertisement