PDA

View Full Version : Weird shader behavior: discard and gl_Normal



pdobrev
12-11-2008, 03:57 AM
Hello!

I have a really strange (at least to me) problem with a bunch of glsl shaders.
So, this is my workflow:
- I'm rendering a point cloud (glPointSize=1) and first want to mark some points
- I do a bunch of rendering passes marking the points and after each pass I discard the points that have been marked in previous runs. This I can do in two ways:
- manually remove the marked points from the dataset after each rendering (slow)
- pass a vertex array containing information about which point has already been marked and use a simple test in the shader like
if (marked == 1)
discard;
- After the marking process, I do a completely different rendering with visualization purposes (and not marking), with a different pair or shaders and from a different viewpoint.

The problem:
If I use discard; in the marking fragment shader, I get that gl_Normal is always 0 in the rendering shader, even though I'm passing non-zero normals along the geometry.

If I manually remove the marked points from the dataset, everything works out fine.

No GL errors, no shader warnings.

Any clue would be highly appreciated!

Petar.

Jan
12-11-2008, 04:37 AM
I think you should post your shader, without it, it is difficult to say.

Jan.

pdobrev
12-11-2008, 04:52 AM
I'm using the shader4 extension to get the integer pipeline, but this, I think, has nothing to do with the problem (since there is no problem if I comment the discard line there)



#extension GL_EXT_gpu_shader4 : enable

varying float distanz;

flat varying unsigned int pointNum;
flat varying int isMarked;

uniform unsigned int dataset;


varying out uvec4 intColors;

void main()
{
if(distanz == 0.0)
discard;

// if the point is already marked, don't update the fb
// PROBLEM: fix me!!!! if this is uncommented, the normals (o_O) get all messed up
if (isMarked == 1)
discard;

uvec4 res = uvec4(dataset, pointNum, 0, 0);

intColors = res;
}

bertgp
12-11-2008, 07:19 AM
Where/how do you use gl_Normal? I can't find it in the code you posted.

pdobrev
12-11-2008, 07:27 AM
The gl_Normal is in the rendering shader, but it does nothing more than Phong shading rendering. gl_Normal is passed from the vertex shader to the fragment shader in a varying variable. I don't think there's need to post that as well, but if you think it might help, I could post the vertex/fragment shader for the phong illumination I'm using.

I know it looks totally disconnected and it should be that way, but for some reason, having the discard in that fragment shader changes all normals to 0 and screws up the phong rendering later.

pdobrev
12-11-2008, 08:00 AM
OK, the problem was the following.
isMarked is a varying variable that just transfers the value of the marked attribute variable from the vertex shader to the fragment.
When the line with the "discard" is commented, the shader compiler determines that isMarked is not used anywhere, hence there is no point to transfer its value from the vertex shader, hence the attribute value in the vertex shader also doesn't have any meaning. So, OpenGL assigned an invalid handle to the attributeLocation and the attribute wasn't used.

When the lines are not commented, the values for the attribute variable are actually passed in an array, and since I forgot to disable it afterwards, it got carried onto the rendering shader, messing up the normal.

So, in fact, the problem was that i didn't disable the attribute array after the shader had done its job.


Sorry for the bother and thanks for your time!

Best regards,
Petar.