Sign in to follow this  
Black Knight

Conditional in HLSL pass

Recommended Posts

Is it possible to make a conditional check in a pass? I am trying to change CullMode based on a global set from the client side.If it is not possible should I just set it from the client with SetRenderState or should I make two different techniques like ShadowOneSided and ShadowTwoSided. The following code gives the error None identifier not defined. Any suggestions?
technique Shadow
{
	pass P0
	{
		ColorWriteEnable = RED;
		AlphaBlendEnable = true;
		SrcBlend = One;
        DestBlend = Zero;
		CullMode = (g_TwoSided)?(None):(CCW);
		vertexShader = compile vs_3_0 VertShadow(g_EntitySkinned);
		PixelShader  = compile ps_3_0 PixShadow();
	}
}



Share this post


Link to post
Share on other sites
This isn't something I've tried before so I don't know if it works, but it seems to at least compile:

bool g_TwoSided;
int CullType()
{
return (g_TwoSided)?(0):(2); // Can't use the "None" and "CCW" constants here
}

technique Shadow
{
pass P0
{
...

CullMode = CullType();

...
}
}



Share this post


Link to post
Share on other sites
MJP's solution looks great, but I don't know if it works.

My suggestion is if the changes are small, go for a setrenderstate.

When the changes are significant go for #ifdefs. In my deferred renderer I have a single .fx file containing the light shader, which generates 6 shaders via #ifdefs, two for each light type.

What's good about #ifdefs is you can reuse the same system to decide which features must be enabled at runtime (and rebuild the shaders on the fly). The total amount of permutations is very high as #defines control features like linear color space, shadow mapping and lighting models supported. Of course the trick is to generate a few shaders, but in case a project didn't need all lighting models, I would just tell the fx compiler not to generate that code.

The cost of switching shaders is high in D3D9, but in D3D10 if the vertex layout is the same (and in theory it's the same) the operation looks a lot cheaper, so #ifdefs could be a good solution...

Share this post


Link to post
Share on other sites
If you decide to use two techniques, one thing I discovered lately is that doing 'compile' within a technique always creates a shader, so if you compile the same shader in several techniques, you get duplicates. Better to compile before and assign to a variable.

As for the question itself, I'd say do whatever fits your code structure the most. If your code is built around techniques, then introducing another technique might be easier than introducing SetRenderTarget into the code. If, as undead's solution suggests, this isn't dynamic, but an option that's set once, and you can compile the shader with it, what he suggests sounds like a fine solution.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this