Not logged in, Join Here! or Log In Below:  
News Articles Search    

 Home / 3D Theory & Graphics / Alpha Blending in DirectX Account Manager
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.

February 07, 2005, 09:13 AM

I have some questions regarding alpha blending in DirectX.
I create a texture with alpha value = 128 and two quads.

I render in the following order.
1. Quad is rendered at z = -100.
2. The texture is rendered at z = -50.
3. Second quad is rendered at z = 10.

Both the quad ( 4 vertices ) and texture has alpha value as 128.

I set the alpha blend states in direct x by the following;
dxDevice.RenderState.AlphaBlendEnable = true;
dxDevice.RenderState.SourceBlend = Blend.SourceAlpha;
dxDevice.RenderState.DestinationBlend = Blend.InvSourceAlpha;

My eye point is located at z = -500. Near Plane is 1 and Far Plane is 1000.
The problem I am facing is that the objects rendered are not transparent. (can't see through them). However when I rotate the object by 180 degrees (equivalent to seeing from z = 500) the objects are transparent.

Also the transparency seems to be affected by the order in which the quad and the textures are rendered.

I am not able to understand the behaviour of alpha blending in DirectX.

Please share your thoughts on this subject.


February 07, 2005, 10:26 AM

You have to sort all transparent triangles based on distance from the viewpoint, to get correct transparency


February 07, 2005, 11:04 AM

There is 2 type of alpha blending/testing

1- The See-Through (Sprite)
2- The Real Transparency (Color blending)

See-Through is when a specific color will not be shown
You apply a ''mask'' with the equation you gave
dxDevice.RenderState.AlphaBlendEnable = true;
dxDevice.RenderState.SourceBlend = Blend.SourceAlpha;
dxDevice.RenderState.DestinationBlend = Blend.InvSourceAlpha;

This will imprint a black mask in the Destination data color and then
will write only the Source where this mask is
You will get Full color where the mask is and no color where he's not
You carve a place in the image and then draw only in that black shape

Real Alpha Blending will do Real Transparency
For this you will have to use a Function for the Alpha Blending
You will put the alpha test state to ON

The Order that you put the Triangle or Quad is important
in the See-Through because you basically apply Sprite to the color buffer
that is already there
Not only do you have to draw the back triangle first
but you will have to put the Z buffer Writing State to OFF (Disable)

The easiest way is to find an example in the SDK and see how they make it work


March 30, 2005, 07:52 PM

I have run into a similar issue. The draw order is screwing up everything that has textures with transparent regions. This is the only place on the internet I've found so far that has anything similar to the problem I'm having.

I cannot believe you, the game programmer, has to manually order each triangle in distance from the camera. This simply cannot be right. There has to be a setting that fixes the issue. This is a insane amount of distance calculations you'd have to do and sorting to make this work. Trust me, I've tried. It's impossible to do for every mesh, let alone every triangle, that has a transparent region. Even if it was possible, then it would not work all the time because what if two triangles are partially overlapping? One portion of the first triagle could be in front of the second while the other portion of the first triangle could be behind the second. A simple ordering of the triangles from distance from the camera wouldn't work. It is an issue with the Z-buffer writing when it shouldn't be.

This is what it seems like to me: DirectX is writing to the Z-buffer even though it is not drawing the pixel because it found the transparent color in the texture.

There must be a setting somewhere that makes sure it only draws onto the Z-buffer when it actually draws a pixel and does not draw anything to the z-buffer when it finds the color-keyed pixel and thus shouldn't be drawing anything!

Am I clear at all? It's easier explained with pictures. Essentially, my little practice game looks fine... as long as you don't move the camera around too much because then sometimes the draw order is wrong. In real games, the game programmer cannot be manually changing the draw order to make it work. There are too many triangles with transparent regions to manually sort and my solution above would make it so you could order things in any order just like you do with normal 3D shapes. I can't imagine how many 3D games (even Duke Nukem 3D!) that have quads or whatever with textures with transparent regions and it's not a problem but for some reason it's a huge issue with DirectX 9.

-Dr. Zoop


March 31, 2005, 02:13 AM

Dr. Zoop (are you the same Dr Zoop as on our forums by the way?), unless I gravely misread your post, you are simply wrong. And you really should use google a lot more, because there is heaps of info on doing transparent rendering correctly out there.

I advice you to pick up any open source 3d engine (ogre, irrlicht, etc.), and look at the source. They all handled the problem in exactly the way you describe as "It's impossible to do for every mesh, let alone every triangle".


March 31, 2005, 03:53 AM

Well, unfortunately, that is the way it is. To get semi-transparent surfaces to turn out right, you have to order them yourself, and draw them in far-to-near order. All games with correct looking alpha blending does this, and yes, it is a pain.

There are couple of additional things though: if you use additive blending, you can simply turn z-testing off, and then you don't have to sort the surfaces.

If you enable alpha-testing (instead of alpha-blending), you will have fully transparent pixels NOT being written at all, which is fine if you want similar behaviour to colorkeying. This way you will not have to sort your surfaces, and pixels will only write to the z-buffer if they are opaque. But then you will lose semi-transparency.

What a lot of games do is either filter out semi-transparent surfaces, and render them last, sorted by depth, or they filter out objects containing semi-transparent materials, and render them last, sorted by depth. More often than not, minor artefacts are just ignored, because it would take up more power to fix them than it's worth.


March 31, 2005, 11:37 AM

You don't need to sort if you use, say, alpha testing. Fragment either passes or fails. That is not translucency, I know, but useful hack to reduce the amount of sorting. Everyone knows about this anyway but I mentioned it in hopes it might be useful to someone. ;)


March 31, 2005, 01:32 PM

You can also enable alpha testing with a threshold of 1 and alpha blending at the same time. This gets rid of all pixels with alpha 0, so they won't be drawn in the z-buffer (and won't incur the cost of blending) but still lets you use blending on the other pixels.


March 31, 2005, 01:36 PM

Isn't that an optimization that the driver would automatically do?

The problem with alpha testing is that multisample antialiasing can't smooth the hard edges it produces.


March 31, 2005, 01:44 PM

some drvers might do, some drivers definitely don't. I wouldn't count on it being done.


March 31, 2005, 11:17 PM

I am very excited by the number of answers! This may mean that I will finally get this problem solved!

By the way, I am obviously brand new to Direct3D programming. I just picked it up a few months ago by reading tutorials online. I apologize for my "newbieness" when it comes to what all happens in the background. Gotta learn sometime :-).

I am not worried about semi-transparent things yet. So, I would like to try one of the simpler methods mentioned earlier. It was said a few times to simply turn on AlphaTestEnable:

If you enable alpha-testing (instead of alpha-blending), you will have fully transparent pixels NOT being written at all, which is fine if you want similar behaviour to colorkeying. This way you will not have to sort your surfaces, and pixels will only write to the z-buffer if they are opaque. But then you will lose semi-transparency.

I have tried that without avail. I am guessing then the problem is that I cannot use the colorkey to make the transparency anymore. Is that correct? If I recall correctly from somewhere I read, when I load the texture, I have to the alpha to one on the pixel. Is that what I should do?

Thanks for the help everyone! I am also sorry for posting about something that sounds like is everywhere on the web. I didn't even know how to describe my problem so that I could put it into google! I just googled "texture transparency" and prayed. Hehe. Luckily I found this site! Thank you all again, I'll be checking in again,

-Dr. Zoop

By the way, I think I am the only Dr. Zoop anywhere. Unless someone stole my name. Hehe. I also go by Commando Zoop if that rings any bells.


April 01, 2005, 12:03 AM

Sorry to repost. I tried to edit, but it was past the time limit.

I was looking around trying to find a way to add the alpha channel manually to a texture after loading from a file (like a BMP) but I could not find it--I just don't know what it's called. If I knew what to look for it'd be easier to google :-P.

I do not see any easy ways of getting access to an alpha channel from the texture object. I am guessing I have to open a graphics stream, but from that point I am not sure. Especially because I'm guessing it'll depend on the format you load the pictures from. If anyone has any links that show how to do that, that'd be great!

Essentially, I am asking for an example of the quoted suggestion in my previous post.

-Dr. Zoop


April 01, 2005, 01:28 AM

Yes that is correct, you can not use colorkey as you could in directdraw, but you can get similar behaviour by using alpha testing and an alpha channel.

Use this function:

UINT Width,
UINT Height,
UINT MipLevels,
DWORD Usage,
DWORD Filter,
DWORD MipFilter,
D3DCOLOR ColorKey,

which lets you create a texture from a file (dds, bmp, png and others). Notice the ColorKey parameter? That can be used to have this method automatically create such an alpha channel to be used instead of a color key.

And don't worry about being a newbie, we all were at some point in time :-)


April 01, 2005, 11:47 AM

I'm using managed DirectX, so things look a little different. But there should be equivalents to everything, or almost everything. Arn't I using the equivalent to that function?:

  1. myTexture = TextureLoader.FromFile(D3DDev, BitmapPath, myWidth, myHeight, 1, 0, Format.A8R8G8B8, Pool.Managed, Filter.None, Filter.None, Drawing.Color.Magenta.ToArgb())

I am fairly sure that's the same function, identical arguements. If that's the same function, then um... something else is not right. I have been using that function for loading textures since the beginning and tried turning on the alpha-testing recently and it still gets weird visual fragments when things are drawn in the wrong order. Are there other settings I have flip?

Thanks again!
-Dr. Zoop


April 02, 2005, 03:47 AM

Problem solved.

It turns out I was using the default alpha function and not Compare.NotEqual. I just surfed the web a bit looking for "direct3d alphatest" to see if I could find any examples that used an alpha-testing. Once I found one, just looked at what I was missing, and that was all it was. Now it works! Yay!

But, it doesn't mean I understand why.... why not equal? Anyone have any recommended links and/or examples for explaining what goes on exactly when alphaing? I would like to read up on it because I know one day I'll want to have semi-transparencies... which means ordering polygons and everything. I might as well start reading up on it!

Thanks all :-),
-Dr. Zoop

This thread contains 15 messages.
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.