z-buffer discontinuity in shaders

Started by
15 comments, last by amtri 10 years, 2 months ago

OK. I got the color and the depth each written to a different texture in an FBO. For the color texture I use


glTexImage2D (GL_TEXTURE_2D,0,GL_RGBA,400,400,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,geom_color,0);

and for the depth texture I use


glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT24,400,400,0,GL_DEPTH_COMPONENT,GL_FLOAT,0);
glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,geom_depth,0);

At the end I bind the 0 frame buffer and draw 2 triangles that cover the entire window, using the color texture to draw them. Everything works fine.

Now I would like to use a shader to post-process my geometry. I have 2 textures: one with the color and one with the depth. I want to use both in the shader: I will look at the value of the depth using a filter to detect an edge (something I've already done outside of a shader and I know it works well) and, depending on the value of the filter, I will use either the color from the color texture or just set the color to black to highlight the edge (I'm not worried about the edge algorithm now).

My question is: how do I setup the shader to use 2 textures at the same time. I'm truly confused by this: one texture contains a vec4; the other a single float; and both are used in the shader at the same time.

If somebody could give me some pointers on what needs to be done in the client and the shader to use these 2 textures at the same time I would appreciate it.

Thanks.

Advertisement

If somebody could give me some pointers on what needs to be done in the client and the shader to use these 2 textures at the same time I would appreciate it.

Same thing you do for multitexturing, just don't blend in the shader. Here's a tutorial if you're unfamiliar with multitexturing.

If you are using an edge detection algorithm, why not just use the dot product. If dot product of (normal,viewvec) < .01 or something, you can make the pixel black.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

If you are using an edge detection algorithm, why not just use the dot product. If dot product of (normal,viewvec) < .01 or something, you can make the pixel black.

It's not as simple as it sounds. My image consists of hundreds of thousands of triangles, many of them in the exact same orientation but just slightly parallel to each other. Sometimes I may have dozens of layers of closely spaced parallel surfaces and it's difficult to see them. They are all oriented the same way, with the same normal, so the best way to distinguish them is to highlight their edges. I could, in theory, just draw the line segment defining the feature edges, but that would take longer than just doing an image processing with a shader - which is why I'm going the shader route.

I could really use some help with what I believe is very basic. I created a framebuffer object, attached a depth and a color texture to it, and drew 2 triangles along with the text "Hello World" on top. I then took the 2 textures, extracted the data from them just to check that they were correct. They were: in one I see the RGB values, and in the other I see a single floating point number with values as expected given my triangles.

Then I bind the "0" framebuffer and draw 2 triangles to the screen with the color texture; not a problem. I see the image just as expected, so I'm confident that my textures are ok (at least the color one since I'm drawing with it).

Now comes the part I don't understand: all I'm trying to do is to use a shader to display the same image: no manipulation at this point as I'm getting my feet wet with textures.

This is what my vertex shader looks like:


void main()
{
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   gl_TexCoord[0] = gl_MultiTexCoord0;
}

And this is my fragment shader:


uniform sampler2D colortex;
void main()
{
   gl_FragColor = texture2D(colortex,gl_TexCoord[0].st);
}

The shader program compiles and links with no errors.

In the client code I have


GLuint colortexloc = glGetUniformLocation (prog,"colortex");
glUniform1i (colortexloc,0);

Everything else is the same. I expected the image to be displayed just as before. Can somebody point towards something that's obviously wrong or missing? If I comment out the "glUseProgram" call then the image is properly displayed again. So it does look like a problem with the trivial shader code above.

Any help is appreciated. Thanks!

I've made some more progress on my own, and ran into a more concrete issue: I have both a 1D and a 2D texture on unit 0 (GL_TEXTURE0). I use one or the other by using glEnable/glDisable.

In my shader I have a sampler2D and a sampler1D. Both are assigned to unit 0.

Whenever I switch from the 1D/2D textures I send a uniform flag indicating which texture is being used. If it's the 1D texture I use texture1D using as first argument the sampler1D variable, and as second argument gl_TexCoord[0].s; if it's the 2D texture I use texture2D using as first argument the sampler2D variable, and as second argument gl_TexCoord[0].st.

My problem is that the 2D texture does not show.

By setting the output color in the fragment shader to vec4(gl_TexCoord[0].s,gl_TexCoord[0].t,0.,1.) I can tell that the 2D texture coordinates are correct. So my problem is that somehow switching to texture2D(sampler2D,...) after displaying the using texture1D(sampler1D,...) is not working.

If I turn off the shader program then the images are displayed as expected, so the client program is correct.

Any thoughts? Have I misunderstood how a single unit is to be used with multiple textures?

Thanks.

One more piece of information: I am drawing the 1D texture first, then the 2D texture.

If I reverse the order, then my 2D texture works fine, but my 1D texture does not.

And I know for a fact that my uniform flag indicating which texture I'm using is being passed down correctly, and it is using sampler1D for the 1D texture and sampler2D for the 2D texture. But, for some reason, after the first texture is drawn - either 1D or 2D - the second one in the same unit is not drawn.

Not clear why this is the case...

This topic is closed to new replies.

Advertisement