Jump to content
  • Advertisement
Sign in to follow this  
stevereine

hlsl if then else question

This topic is 965 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can someone tell me why the following pixel shader code works and the second bit of code doesn't? This is excerpted from a .fx file that otherwise works fine. The only thing that is changing is the litcolor.r value in the if-then code. It seems that if I don't change the litcolor.r value, all works fine. Why would changing this value cause the shader to not compile correctly? I know it's not a real useful bit of code, but just trying to see what the limitations of pixel shaders are. Thanks!
struct VS_OUTPUT
{
	float4 Position : POSITION; // vertex position
	float4 Diffuse : COLOR0; // vertex diffuse color
};

float4 ColorPS(float4 vPosition : POSITION, float4 c : COLOR0) : COLOR
{
	VS_OUTPUT Output;

	float4 litcolor = float4(0.0f, 0.0f, 0.0f, 0.0f);

	if (vPosition.x>1000)
	{
		litcolor.r=0.0f;
	}
	//else
	//{
	//	litcolor.g=1.0f;
	//}

	return litcolor;
}
and the following gives me a shader compiler error?
ColorPS(float4 vPosition : POSITION, float4 c : COLOR0) : COLOR
{
	VS_OUTPUT Output;

	float4 litcolor = float4(0.0f, 0.0f, 0.0f, 0.0f);

	if (vPosition.x>1000)
	{
		litcolor.r=1.0f;
	}
	//else
	//{
	//	litcolor.g=1.0f;
	//}

	return litcolor;
}
Edited by Hodgman
added [code] [/code] tags

Share this post


Link to post
Share on other sites
Advertisement

What's the error message that you get?

There could be a difference because in the first shader, the compiler might be completely optimizing away your if statement -- before the if, litcolor.r is zero, and then after the if, litcolor.r is still always zero no matter what... so the if provably does nothing and can be removed.

Edited by Hodgman

Share this post


Link to post
Share on other sites

Thank you Hodgman for the edit, I will try to stick to that format in the future.
 
FYI - This is Directx9, and the error is not actually when the shader is compiled, but occurs in the GetTechniqueByName statement in the C++ code. Technique code in shader is as follows;

Technique mytechnique
{

	pass PO
	{
		//SetVertexShader( CompileShader( vs_2_0, Ripple()));
		vertexShader = compile vs_2_0 Ripple();
		pixelShader = compile ps_2_0 ColorPS();
	}
 
	pass P1
	{
		//SetVertexShader( CompileShader( vs_2_0, Ripple()));
		vertexShader = compile vs_2_0 Ripple();
		pixelShader = compile ps_2_0 ColorPS();
	}
 
}

 
Steve

Edited by Hodgman
added [code] tags

Share this post


Link to post
Share on other sites
error X4502: invalid input semantic 'POSITION': Legal indices are in [1,15]
error X4502: invalid ps_3_0 input semantic 'POSITION'
 
POSITION isn't a legal semantic for a pixel shader in dx9. You probably want VPOS. You also probably want a way to view your compile errors. 
 
The first shader works because the entire body of the function is compiled out, and it never checks the semantics because they're never used.

Share this post


Link to post
Share on other sites

Hi Hodgman,

 

The error is 'unhandled exception at 0x003C3B5F. Access violation reading location 0x00000000. Maybe not an error in shader compilation then, but looks like maybe it's not getting a correct pointer value when returning from the GetTechniqueByName function. 

 

I think you're on the right path when suggesting that it's optimizing away the if statement. HLSL code is a very interesting animal.

 

Steve

Share this post


Link to post
Share on other sites

Access violation reading location 0x00000000

That means that you're using a NULL pointer when calling GetTechniqueByName, probably because the effect failed to compile.
 
Dingleberry posted the actual compiler error that you should be getting, above.
"float4 vPosition : POSITION" is not valid in a D3D9 pixel shader.
You got lucking in your first shader, as it optimized away the read of vPosition and saved you. In the second shader, you're actually accessing vPosition, causing this error.

Share this post


Link to post
Share on other sites

OK Dingleberry, you have solved my problem. I didn't mention it until my second post, but I was using ps_2_0 to compile. I noticed you had compiled my code in ps_3_0 so switched to that and switched to the VPOS semantic. It now works exactly as I had hoped it would. Being the OCD individual that I am, I might just go back and try to understand the difference between ps_2 and ps_3 to find out what went wrong, maybe no good explanation. I also need to read up on semantics, don't understand the difference between VPOS and POSITION.

 

thank you very much!

 

Steve  

Share this post


Link to post
Share on other sites

VPOS/POSITION is just a silly D3D9 quirk sad.png
 
Vertex shaders output a value to POSITION, which is then used to rasterize triangles on the render-target.
However, pixel shaders at the time were unable to read POSITION at all!
People often ended up doing hacks like having the VS write position into TEXCOORD0 as well -- because the PS is able to read TEXCOORD0:

struct VS_OUTPUT
{
	float4 Position : POSITION; // vertex position
	float4 Position2 : TEXCOORD0; // also vertex position!!
};

ps_3_0 introduced VPOS as a kind of work-around here. It doesn't contain the exact same data as the POSITION variable -- but it does contain POSITION after it's also been adjusted for the viewport and converted into pixel coordinates.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!