Texture lookup with dynamic loop in fragment shader not working

Hello!

I have a weird problem with my shader.

In the fragment shader I’m reading data from a 3D texture in a for-loop until the correct alpha value is found, with a maximum number of iterations specified as a uniform int (currently 320). The fragment color is then determined by the number of iterations done along with the last RGB read from the texture. So far there’s no problem, it works perfectly.

The problem appears when I try to speed things up with a 2D texture of the same width and height as the 3D one. Before the for-loop I read a value from it to determine a starting point for the loop to avoid unnecessary texture lookups.
What happens is that the shader compiles fine with no warnings, but then it does nothing. Apparently the fragment shader doesn’t even get called!

The vertex shader is a simple pass-through one, and there are no other stages. Both textures are of 16-bit float RGBA format. I’m working on a Windows 7 with a GeForce GTX 560 Ti.

If someone could tell me what’s wrong with this or if there’s an alternative way to do it (there has to be a dynamic loop in the fragment shader though), I would very much appreciate it!

ps. With a correct alpha value I mean a range (as in 0.8<A<0.9).

??

Try specifying a texture lookup with an explicit LOD value.

Thank you for your response. Correct me if I’m wrong, but that seems to be about mipmaps and artefacts caused by discontinuities in the texture.
I forgot to mention that I don’t create mipmaps, and I use GL_LINEAR filtering for the 3D texture and GL_NEAREST for the 2D texture.
Also I don’t get artefacts but the whole fragment shader refuses to work. My shader doesn’t get overridden by the default pipeline or what’s-it-called, but instead no fragments are output.

Try forcing the color to a known value (e.g. 0,0,1,1) and assuming that “fixes it”, move it up in your logic toward the source until you find the problem.

Failing that, post a standalone test prog illustrating your problem, or at least the shader source.

Great advice, thanks! I still don’t get what’s wrong, though.

I added a part that sets the color white if the starting point read from the 2D mask is smaller than a given value, and black otherwise, then returns from main(). If this part is before any lookups from the 3D texture, it works. It can also be after them if they can’t affect the final color.

It won’t work if it’s right after the first alpha check. So this doesn’t work:

i0=int(texture2D(mask, maskCoord).r);
for (int i=i0; i<layers; i++) {
    data=texture3D(map, mapCoord);
    if (data.a>0.5) {
        gl_FragColor=vec4(1.0);
        return;
    }
    if (i0>100) gl_FragColor=vec4(0.0);
    else gl_FragColor=vec4(1.0);
    return;
}

Just to clarify, this does work:

i0=int(texture2D(mask, maskCoord).r);
for (int i=i0; i<layers; i++) {
    data=texture3D(map, mapCoord);
    if (i0>100) gl_FragColor=vec4(0.0);
    else gl_FragColor=vec4(1.0);
    return;
    if (data.a>0.5) {
        gl_FragColor=vec4(1.0);
        return;
    }
}

Does the program also validate with no warnings?

Specifically: if you added a 2D sampler but you forgot to set that uniform before drawing, then it is likely that you are asking the program to sample from unit 0 as both 2D and 3D, which is illegal.

That has to be it! I’m not at my computer now so I can’t test it, but it fits exactly!
I thought that 2D and 3D samplers had their own “name spaces” so I didn’t set the uniforms as those are the only textures I use at the moment.

Thank you so much! This has been driving me crazy!

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.