Alpha test in Xen 2.0

Apr 9, 2011 at 4:48 PM


I recently udpated my project, running with xen 1.8, to xen 2.0.

I don't manage to find a way to enable and configure alpha test, like I did before with:

state.RenderState.AlphaTest.Enabled = true;
state.RenderState.AlphaTest.AlphaTestFunction = CompareFunction.Greater;

Any idea ?

No more Alpha test in xen 2.0 ??

Apr 9, 2011 at 5:08 PM

AlphaTest was removed from XNA 4. This is mainly for compatibility reasons between the xbox and phone.

You will need to modify the shader in use to use the clip() instruction, so manually reject pixels based on your own logic. Although be careful, because clip() can have a mild performance impact in some situations (so only use it where you really need it).

The reason they did this is pretty simple - modern graphics chips don't actually support alpha test as a fixed function state (anything DX10 or above, the xbox, the phone, etc). It is emulated by the driver, which internally modifies the shader before it gets used if alpha test is needed - which is obviously very inefficient.

Apr 9, 2011 at 5:48 PM

Ok i see.

I can easily use clip() in my own pixel shaders, but the thing is that most of the time I use your MaterialShader class, wich is pretty cool ...

Material.fx does not provide this feature in its vertex shaders right ?

It could be really nice to include it and add a "AlphaTestEnable" flag in MaterialShader ^^

Maybe i'll try to do it.

But anyway, thanks for the quick reply ;)

Apr 9, 2011 at 10:17 PM
Edited Apr 9, 2011 at 10:19 PM

I don't think it'd be too hard. The only snag is that MaterialShader is pushing the limit of pixel shader 2 - The most complex version has one instruction to spare, but unfortunately clip() requires at least 2.

So in order to add it, you'd need to bump them all to pixel/vertex shader 3.

Once done, you can use pixel shader 3 static branching, so I'd put in a boolean flag in the shader to branch on - forced to a boolean register:

bool p_useAlphaTest : register(b0);

Then at the end of the two pixel shaders, add the appropriate clip code:

if (p_useAlphaTest) clip(rgba.a); // or whatever

Then in the IMS_Base interface, add:

bool P_useAlphaTest { set; }

That would allow you to easily set the flag, no matter which shader is being used internally - however that'll still require hooking up inside the MaterialShader class, but I'll let you figure that out :-) I won't spoil all the fun

Apr 10, 2011 at 8:48 PM

Hehe ok :P

I'll check this out