2
\$\begingroup\$

In my fragment shader I have passed an uniform int uLightType variable, which indicates what type of light is in usage right now. The problem is that if-else branching does not work correctly - the fragment shader performs instructions in every if statement block.

if (uLightType == 1) { // Spotlight light type
    vec3 depthTextureCoord = vDepthPosition.xyz / vDepthPosition.w;
    shadowDepth = unpack(texture2D(uDepthMapSampler, depthTextureCoord.xy));
}
else if (uLightType == 2) { // Omni-directional light type
    shadowDepth = unpack(textureCube(uDepthCubemapSampler, -lightVec));
}

In the case when uLightType equals 1, unless I comment out the content of the second if block, it assigns an another value to shadowDepth.

Also while uLightType equals 1, when I remove the second 'if' block and change == to != like in the sample code below, nothing happens (which means that uLightType really equals 1).

if (uLightType != 1) { // Spotlight light type
    vec3 depthTextureCoord = vDepthPosition.xyz / vDepthPosition.w;
    shadowDepth = unpack(texture2D(uDepthMapSampler, depthTextureCoord.xy));
}

Also, when I manually create an int variable (which is not an uniform) like this: var lightType = 1; and replace uLightType with it in the if-else branch, everything works fine, so I guess it have something to do with the fact that uLightType is the uniform.

\$\endgroup\$
2
  • \$\begingroup\$ if you're using uniform to define part of shader behavior and that behavior is expensive on gpu, i'd suggest making separate shaders without if statement and just checking which to use outside of shader since openGL probably just calculates both statements in paralel, and that also might be the cause of your problem... \$\endgroup\$
    – Opsenas
    Jun 4, 2014 at 11:28
  • \$\begingroup\$ @Opsenas I believe that splitting this shader (which is not a complicated one) into smaller ones and then switching them when needed would be more expensive than using simple if-else ladder. IMO this >>>discussion<<< covers it well. Also I have seen fragment shaders on some threads where if-else blocks worked well when checking the equality between an uniform int and a number (like >>>this<<< one). \$\endgroup\$
    – Winged
    Jun 4, 2014 at 12:18

2 Answers 2

2
\$\begingroup\$

It's pretty clear that your uniform isn't getting to the shader. As proved by pre-setting lightType manually. My 2nd guess would be precision hints but it looks like you're sending pretty small numbers to it. But also double check the precision can handle the value.

If an IF-ELSE branch isn't working as expected you have to assume it's not the IF-ELSE commands but the logic or values inside the ()'s.

Nine times out of nine when something is going wrong in a NEW shader where all the code looks right to me, it's that I'm not getting the value to the uniform. So however you do that in your system double check it. That's going to be it.

Here's what I would do. First just set gl_frag = to your uLightType in a way that will tell you if the value you're sending it is getting there or not. Something like:

lowp float test = uLightType/3.0;  // since your value is 1, 2, or 3.
gl_frag = vec4(test, test, test, 1.0);

Then keep trying to get a specific value there. Once you know that the uniform is getting what you're sending it, then you can debug the rest of your code.

As a side note, I do believe that one of the commenters is right though. That you will want to avoid if branching in the shader. It really slows it down. UUBER shaders aren't all they're cracked up to be. I always prefer multiple shaders over that.

\$\endgroup\$
0
\$\begingroup\$

What's the question - why it doesn't work as expected?

Is shadowDepth variable assigned a value before these checks?

Perhaps thread coalescing for some reason doesn't end well and it executes parts of the code it shouldn't.


Generally, branching on older versions of the OpenGL (ES) is bad, so you should avoid it, both for performance/readability reasons.

To debug shaders, there are two main approaches:

  • write multiple shader (chunks) and test them separately
  • use #define

Second option is good for keeping things in place, you have to look at just one file, so I would suggest that one.

Creating additional value is just horrible, it takes your time, you have to manage code for it, and strange things (like this here) can happen.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .