Jump to content
  • Advertisement
Sign in to follow this  
gogogigo

HLSL if-statement

This topic is 3441 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

My Compiler always stops at the easiest if-statement (phongshader) : float4 std_PS(vertexOutput IN) : COLOR { float3 diffContrib; float3 specContrib; float3 Ln = normalize(IN.LightVec); float3 Vn = normalize(IN.WorldView); float3 Nn = normalize(IN.WorldNormal); phong_shading(IN,Lamp0Color,Nn,Ln,Vn,diffContrib,specContrib); float3 diffuseColor = tex2D(ColorSampler,IN.UV).rgb; float3 result = specContrib * 0.9 +(diffuseColor*(diffContrib+AmbiColor)); if (result.x == 1.0f) return float4(1.0f,1.0f,1.0f,1.0f); // <-- Here it stops return float4(result/100,1); } When I replace the last 2 rows with: if (1.0f == 1.0f) return float4(1.0f,1.0f,1.0f,1.0f); return float4(result/100,1); ... there is no Problem I Use vs_3_0 and ps_3_0 and Visual Basic.NET. Why does my Compiler stops??

Share this post


Link to post
Share on other sites
Advertisement
This would be a typical 'you tell me?' scenario. How do you compile your shaders? What parameters do you use? What does the compiler give as output?

Now, if I had to take a wild guess, I'd say you have something bad in the function phong_shading, or perhaps you go over the PS instruction limit, which in PS_3_0 is 512. If you use the if(1.0f == 1.0f) return float4(1,1,1,1); line, the HLSL FX compiler will see that being always true, and it will just discard *ALL* (assuming you have default optimizations on) of your pixel shader code and replace that with a simple return float4(1,1,1,1); statement, which compiles fine.

But really, that's just a guess. If you're able to post more specific information, someone can probably help better.

Share this post


Link to post
Share on other sites
I might be wrong but I dont think PS 3.0 supports conditional returns.

The reason it would work when you put in a tautology like if 1=1 is that compiler would optimze that statement out.

instead, just use the conditional to compute a float4 finalcolor.rgb and return that.

Share this post


Link to post
Share on other sites
Thanks, but there's still the same problem, even if I reduce the Shader to these lines:

float4x4 WvpXf : WorldViewProjection;

texture ColorTexture : DIFFUSE;
sampler2D ColorSampler = sampler_state {
Texture = <ColorTexture>;
AddressU = Wrap;
AddressV = Wrap;
};

struct appdata {
float3 Position : POSITION;
float4 UV : TEXCOORD0;

};

struct vertexOutput {
float4 HPosition : POSITION;
float2 UV : TEXCOORD0;
};

vertexOutput std_VS(appdata IN) {
vertexOutput OUT;
OUT.UV = IN.UV.xy;
OUT.HPosition = mul(float4(IN.Position.xyz,1),WvpXf);
return OUT;
}

float4 std_PS(vertexOutput IN) : COLOR {
float3 diffuseColor = tex2D(ColorSampler,IN.UV).rgb;
if (diffuseColor.x) return float4(1,1,1,1); ///////// <====
return float4(diffuseColor,1);
}

technique Main {
pass p0 {
VertexShader = compile vs_3_0 std_VS(); // or vs_2_0
PixelShader = compile ps_3_0 std_PS(); // or ps_2_0
}
}



This Shader works perfect in NVidia FXComposer, but not in my program.
The Error is/are in my program:

...\phong.fx(76): error X3500: asymetric returns from if statements not yet implemented
...\phong.fx(85): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression
ID3DXEffectCompiler: Compilation failed

I can't do anything with this description.
I compile the Shader with the (managed) function Effect.FromFile ( Shaderflags.Debug)

Share this post


Link to post
Share on other sites
I relatively unfamiliar with the HLSL syntax, but does the 'return' keyword in HLSL the same like it would in say C++, C#, VB?

If so, then that would explain the behavior:


// original source but reformated

float4 std_PS(vertexOutput IN) : COLOR
{
float3 diffContrib;
float3 specContrib;
float3 Ln = normalize(IN.LightVec);
float3 Vn = normalize(IN.WorldView);
float3 Nn = normalize(IN.WorldNormal);

phong_shading(IN,Lamp0Color,Nn,Ln,Vn,diffContrib,specContrib);

float3 diffuseColor = tex2D(ColorSampler,IN.UV).rgb;
float3 result = specContrib * 0.9 +(diffuseColor*(diffContrib+AmbiColor));

if (result.x == 1.0f)
return float4(1.0f,1.0f,1.0f,1.0f); // <-- Here it stops

return float4(result/100,1);
}



Share this post


Link to post
Share on other sites
Put it like this:

float4 outValue = float4(result/100,1);
if (result.x == 1.0f) outValue = float4(1.0f,1.0f,1.0f,1.0f);
return outValue;
}

Usually compiler will allow you to use several "return" but only at the end of the shader and only first one will actually work. Practically it means that only one "return" can be used.

Share this post


Link to post
Share on other sites
if (result.x == 1.0f)

Dont think this will solve your problems but you should avoid using equal/not-equal with floating point numbers anyway.

Share this post


Link to post
Share on other sites
Quote:

The Error is/are in my program:

...\phong.fx(76): error X3500: asymetric returns from if statements not yet implemented
...\phong.fx(85): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression
ID3DXEffectCompiler: Compilation failed

I can't do anything with this description.
I compile the Shader with the (managed) function Effect.FromFile ( Shaderflags.Debug)


My guess would be that the compiler doesn't like it if your "if" branch returns something and your "else" branch does not.
Simple test for that would be to put an "else" before your final return statement.
I'm just guessing what could be meant by "asymmetrical returns from if statements", though.
If that isn't a solution at all or not for your case, I'd just go with Viik's solution.

Share this post


Link to post
Share on other sites
Are you using XNA? The FX compiler used by XNA is out of date and doesn't support conditional returns. Check this post at the xna forums on how to use the latest FX compiler: Link

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!