Wireframe rendering (how to?)

Started by
16 comments, last by Ben Foppa 9 years, 6 months ago

I've tried a few different methods of wireframe rendering, and I can't seem to find one that works nicely, even just for debugging purposes.

Simply setting glPolygonMode causes Z-fighting like nobody's business (and as a bonus point against it, it's not OpenGLES-compatible).

In general, I've just had issues using "built-in" lines because of Z-fighting; I haven't specifically tried creating a separate "wireframe bufer" here, but at the very least, there would be a lot of duplication in the buffer (or lots and lots of calls to glDraw*).

Trying to use clever shaders and discarding fragments in the middle of triangles can work, but only the triangles that would be visible in non-wireframe are rendered, because of the depth buffer. It's also annoying because geometry shaders aren't very well-supported, either in OpenGLES or even just by my own graphics drivers.

I'm currently looking into writing wireframe rendering using OpenCL, but I'm not really hopeful about this.

Any other ideas out there?

Thanks!

Advertisement

I use glPolygonMode(GL_FRONT, GL_LINE), which works perfectly without z-fighting issues. Have you tried to combine it with a pre-z-pass ?

If you're rendering wireframe on top of your regular geometry, GLEQUAL depth test should be enough. ie, wireframe will be at the same depth as the existing geometry (because it IS the existing geometry), and lines will overwrite fragments with same depth. Draw it with some bright color like green, pink or yellow.

EDIT: BTW, calling glPolygonMode with GL_FRONT is deprecated. You must call it with GL_FRONT_AND_BACK, then use glCullFace to select which face will be culled.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

I use glPolygonMode(GL_FRONT, GL_LINE), which works perfectly without z-fighting issues. Have you tried to combine it with a pre-z-pass ?

Z pre-pass will probably help though. I'll try and report back.

If you're rendering wireframe on top of your regular geometry, GLEQUAL depth test should be enough. ie, wireframe will be at the same depth as the existing geometry (because it IS the existing geometry), and lines will overwrite fragments with same depth. Draw it with some bright color like green, pink or yellow.

EDIT: BTW, calling glPolygonMode with GL_FRONT is deprecated. You must call it with GL_FRONT_AND_BACK, then use glCullFace to select which face will be culled.

I'm not rendering overtop of existing geometry (because I also want to display "hidden" triangles), but I suspect this will combine nicely with the Z pre-pass mentioned above!

And thanks for the note about GL_FRONT, I was about to ask, since I get a GL_INVALID_ENUM error using GL_FRONT, and https://www.opengl.org/sdk/docs/man3/xhtml/glPolygonMode.xml says GL_FRONT_AND_BACK is the only valid value.

Thanks for your help!

I'm not sure, but I think a double-post is appropriate for a "report back" sort of scenario?

I changed my render function to this:


      gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
      gl::DepthFunc(gl::LESS);
      gl::PolygonMode(gl::FRONT_AND_BACK, gl::FILL);

      draw();

      gl::Clear(gl::COLOR_BUFFER_BIT);
      gl::DepthFunc(gl::EQUAL);
      gl::PolygonMode(gl::FRONT_AND_BACK, gl::LINE);

      draw();

Some scattered pixels render (particularly far-away ones), but definitely not anywhere near the expected result. It's worth noting that draw() binds all the normal shaders and whatnot; I'm not sure if that might cause issues. Also, I'm pretty sure this will cause some Z-fighting still, since lines that touch one another would fight over that pixel, no? (assuming I'm not drawing them all in the same color, which I'm not - I'd like to be able to distinguish things somewhat based on their color).


I'm not rendering overtop of existing geometry (because I also want to display "hidden" triangles), but I suspect this will combine nicely with the Z pre-pass mentioned above!

A z-prepass with polygon fill mode will set depth values for the entire faces. So a sub-sequent GL_EQUAL depth test will not let pass fragments of triangles behind.

EDIT: Or did you mean it plays nice with rendering some feature edges like intern ones?

BTW: In a z-prepass it is better (performace-wise) to disable rendering to color buffer(s); this also saves you the need to clear the color buffer(s) a 2nd time.


I'm not rendering overtop of existing geometry (because I also want to display "hidden" triangles)
Then just disable face culling (ie, glDisable(GL_CULL_FACE) ) and draw like regular geometry with LEQUAL depth test and GL_LINE for polygon mode. That's how my wireframe pass is set up.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator


I'm not rendering overtop of existing geometry (because I also want to display "hidden" triangles), but I suspect this will combine nicely with the Z pre-pass mentioned above!

A z-prepass with polygon fill mode will set depth values for the entire faces. So a sub-sequent GL_EQUAL depth test will not let pass fragments of triangles behind.

EDIT: Or did you mean it plays nice with rendering some feature edges like intern ones?

BTW: In a z-prepass it is better (performace-wise) to disable rendering to color buffer(s); this also saves you the need to clear the color buffer(s) a 2nd time.

GOOD point. Clearly I didn't think that one through..

Is there a performant way to do that besides just re-writing all my shaders without outputting/calculating fragment colors? I kind of assume if I just use glColorMask, the fragment shader will still run for everything anyway..


I'm not rendering overtop of existing geometry (because I also want to display "hidden" triangles)
Then just disable face culling (ie, glDisable(GL_CULL_FACE) ) and draw like regular geometry with LEQUAL depth test and GL_LINE for polygon mode. That's how my wireframe pass is set up.

I'm still getting "flickering", which I assume is because lines that intersect will still be fighting for the same pixels. Although.. maybe it has to do with the fact that I'm rendering textures with a GL_LINE polygon mode?

Edit: Okay, it's not because of texturing.. It might have to do with the lighting though - I'm noticing the polygons with flat lighting don't seem to be flickering..


Simply setting glPolygonMode causes Z-fighting like nobody's business (and as a bonus point against it, it's not OpenGLES-compatible).

Taking a rough guess, but I imagine this is because you can achieve the same effect with just shaders? (just make sure to do it after the transformations though so they affect the transformed Z value)

EDIT: er I was thinking about the function that lets you offset the Z value, sorry >_< But that idea still should work I suppose. Just modify the Z value a bit after you transform it.

Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.


Simply setting glPolygonMode causes Z-fighting like nobody's business (and as a bonus point against it, it's not OpenGLES-compatible).

Taking a rough guess, but I imagine this is because you can achieve the same effect with just shaders? (just make sure to do it after the transformations though so they affect the transformed Z value)

EDIT: er I was thinking about the function that lets you offset the Z value, sorry >_< But that idea still should work I suppose. Just modify the Z value a bit after you transform it.

Modify it in what way? Won't two vertices in the same position still produce the same output Z values..?

This topic is closed to new replies.

Advertisement