Difficulty with transparency

Jan 29, 2009 at 5:34 AM
Edited Jan 29, 2009 at 5:39 AM
I'm drawing billboarded trees, unsorted by depth, and with Xen I get what can only be depth buffer issues. The symptom is that depending on the order drawn, some trees that are behind others get cut off in a straight line at the (otherwise invisible) edge of the billboard of the tree in front.  But with (seemingly) the same RenderState settings in straight XNA, the issue doesn't occur. 
I've been hammering on this for a while now and have run out of ideas.  The last test I tried, setting many RenderState properties to ensure a match between the Xen and XNA settings was:

XNA:  this works, regardless of draw order or World property in the BasicShader attached to tree1 and tree2

GraphicsDevice.RenderState.AlphaBlendEnable = false;

GraphicsDevice.RenderState.AlphaTestEnable = true;
GraphicsDevice.RenderState.ReferenceAlpha = 50;
GraphicsDevice.RenderState.AlphaFunction =
CompareFunction.Greater;
GraphicsDevice.RenderState.DepthBufferEnable =
true;
GraphicsDevice.RenderState.DepthBufferWriteEnable =
true;
GraphicsDevice.RenderState.DepthBufferFunction =
CompareFunction.LessEqual;

tree2.Meshes[0].Draw();
tree1.Meshes[0].Draw();

Xen:  this doesn't work... changing draw order and the DrawState's World matrix change which trees are cut off, but I haven't found the difference between this and the XNA version causing the issue.

state.RenderState.AlphaBlend.Enabled =
false;
state.RenderState.AlphaTest.Enabled =
true;
state.RenderState.AlphaTest.ReferenceAlpha = 50;
state.RenderState.AlphaTest.AlphaTestFunction =
CompareFunction.Greater;
state.RenderState.DepthColourCull.DepthTestFunction =
CompareFunction.LessEqual;
state.RenderState.DepthColourCull.DepthTestEnabled =
true;
state.RenderState.DepthColourCull.DepthWriteEnabled =
true;

tree2.Draw(state);
tree1.Draw(state);

In XNA the trees are Microsoft.Xna.Framework.Graphics.Models, with a BasicEffect each, and with Xen the trees are Xen.Ex.Graphics.ModelInstances.  I realize that's not optimal, and I'll probably change the Xen trees to a buffer of position vectors drawn with a custom billboarding shader eventually, but I've been stymied trying to figure out what's preventing the trees from drawing right, first.  I've cut out the billboarding calculations, assuming they have nothing to do with the issue.  At this point I'm wondering if the XNA BasicShader is doing something that the ModelInstance default Material shader isn't... but I'm guessing now because I've been thrashing too long.  (I'm also starting to suspect the problem is something completely obvious and I'm just not thinking... :-)  )

Any ideas out there?

Coordinator
Jan 29, 2009 at 6:53 AM

Hi.

That is odd. Neither ModelInstance or MaterialShader alter render state in any way, so I'm not sure what the problem might be. Others have managed to get transparent models working without problems (see here).

If you provide a screenshot of each version, that would go along way to understanding what is happening. The model instance texture importer options are the same as the defaults for XNA models (I believe) so I doubt that is the issue (were you using colour key in the XNA code?).

Honestly I'm not sure. Sorry :-/

Jan 30, 2009 at 1:51 AM
I must be setting state somewhere in my scene and not popping back to a nominal state.
To isolate the problem, I made a standalone app using straight XNA to display the 2 trees, and an identical app using Xen.

Both work.

Now I just need to hunt down where I screwed up...
Jan 30, 2009 at 2:11 AM
Huh, what do you know?  In my main app, the one I was having problems with, I had a DrawStatisticsDisplay added to the DrawTargetScreen.
Even when you don't request the stats to be shown, it still passes the cull test and it must do something to the state that it's not resetting.

Removing the line that added the DrawStatisticsDisplay to the DrawTargetScreen makes everything work perfectly.

Not sure if this is something that can (or should) be cleaned up in the DrawStatisticsDisplay code... I think I can just write another IDraw class to draw my scene, push the DrawState, draw the DrawStatisticsDisplay, then pop the DrawState again to work around it.  That seems a little gross though...

 

Coordinator
Jan 30, 2009 at 5:40 AM

That is very odd.

The stat overlay will only draw the 'press F12 to toggle' text, and after a few seconds this fades out and nothing will be drawn. Even when the text is drawing, it will push/pop the render state.

Is this running on the xbox? because I have been struggling with a lot of xbox specific xna bugs.
If it's possible, I would greatly appreciate if you can send the code that is causing the problems (and ideally with the xna code that works)

Jan 30, 2009 at 5:40 AM
Wrote that too soon.  Adding back any IDraw causes the rendering to go wrong... in different ways depending on the RenderState modifications by the new IDraw.  I can't find a way to post screenshots from images on my harddrive and don't have webspace to post them, so I'll have to email what I'm seeing.
Jan 31, 2009 at 6:53 AM
Anybody reading this with the same problem... StatusUnknown found the problem and fixed it.  

The problem exists on either platform, so if you're using AlphaTesting open up State.cs in the Xen project, in the Graphics folder, goto line 823 and change AlphaBlendEnable to AlphaTestEnable and recompile the library.
Alpha will work perfectly with that change.