hlsl if then else question

Started by
8 comments, last by stevereine 8 years, 2 months ago
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;
}
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.

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

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.

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

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.

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

I didn't see your other post so I just guessed you were using ps_3_0. POSITION isn't a semantic in either case though. See: https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx#PS

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.

I've got quite a bit to learn, thank you all gentlemen!

Steve

This topic is closed to new replies.

Advertisement