eliminating z-fighting resulting from multi-pass rendering

Started by
14 comments, last by Wilhelm van Huyssteen 14 years, 9 months ago
Hey. in my engine multi-pass rendering seems to create a lot of z-fighting even in 32 bit color depth. what would be the best way to completely eliminate this?
Advertisement
For the second pass, disable depth-writes and use GL_EQUAL for glDepthFunc.

[OpenTK: C# OpenGL 4.4, OpenGL ES 3.0 and OpenAL 1.1. Now with Linux/KMS support!]

that won't solve z-fighting

z-fighting on multipass techniques can just appear if you change something in the way you transform stuff. e.g. slightly different way of generating some matrices or a slightly different shader (sometimes due to optimizations) or on older hardware by mixing vertexshader and fixfunction rendeirng.

the only way to avoid z-fighting in multi pass is to draw with _exactly_ the same transformations.
It will solve z-fighting, if you lay out depth in the first pass and use this depth information in subsequent passes. At least, this is how I solved z-fighting in my last GL3.1 project.

If you are using GLSL, take a look at the "invariant" keyword - might be of help.

[OpenTK: C# OpenGL 4.4, OpenGL ES 3.0 and OpenAL 1.1. Now with Linux/KMS support!]

hmmm.. so it might be that my game logic runs in 1 thread at 100 cycles a second and my rendering thread in another at a max of 60 fps meaning that some of my passes might render a newer state thatn others... think that might be it? i dont realy want to rewrite my engine into a single thread or strugle to find some other workaround unles im certain of it
i didnt c your second post. thnx il look into that
Quote:Original post by Fiddler
It will solve z-fighting, if you lay out depth in the first pass and use this depth information in subsequent passes.

I think you might not fully understand z-fighting.
Z-fighting happens due to inaccuracy of two passes during the depth compare. changing the depth compare function wont solve z-fighting, as this does not eliminate any inaccuracy. Reusing the depth information from previous passes is also not a solution for z-fighting. How would you want to know if a z-value of a pixel belongs to the same object of a previous pass or to another objects that was covering it? beyond that, how do you want to get the value that you want to reuse? copy to a depth texture and read it in fragment program and then outputing it via depth-write ?

Sadly, the only solution is to have the _exactly_ the same transforms in all passes for an object.


Maybe you belive http://en.wikipedia.org/wiki/Z-fighting more than me ;)


Quote:
At least, this is how I solved z-fighting in my last GL3.1 project.
honestly, no offense, but that sounds odd.
Quote:Original post by EternityZA
hmmm.. so it might be that my game logic runs in 1 thread at 100 cycles a second and my rendering thread in another at a max of 60 fps meaning that some of my passes might render a newer state thatn others... think that might be it? i dont realy want to rewrite my engine into a single thread or strugle to find some other workaround unles im certain of it

you render at the same time from data that is modified by the logic? then it's pretty obvious that objects can be moved in between passes and this will result in z-fighting and other more serious artifacts (imagine the logic deletes an objects while you're trying to render from it).

you need to synchronize that in a proper way, the rendering data shall be consistant from the beginning till the end of processing your render-frame.
You are right of course, the only way to combat z-fighting is to ensure your transformations remain invariant between passes. I was describing the pre-Z technique, which orthogonal to this.

I checked my commit log and it seems I fixed a bug that caused z-fighting at the same time as I implemented pre-Z - hence my confusion.

[OpenTK: C# OpenGL 4.4, OpenGL ES 3.0 and OpenAL 1.1. Now with Linux/KMS support!]

taking my engine back to 1 thread is not an option. many features like for instance dynamic resource loading or just the loading of a new area using a loading screen thats also 3d with movement that needs to be redrawn is something i simply cant imagine putting in a single thread (unles some1 here knows how i could pull it of)

so i need to lock the data while drawing from it? this sounds like a night mare :P

anyway what would be the best way to go about this... i cant let my logic thread hang in there and w8 for the render thread to finish (that wil just break everything!) and i cant let my render thread w8 for my logic thread becuz that would probely look horrible :P

so im thinking about buffering the final absolute transformations of all my objects the following way

- create 10 sets of data
- each logick thread iteration wil store the final absolute transformations of all my objects in a different set (incremental)

-the render thread will then always use the current set - 1 to transform the scene.

for example if the logick thread is writing into set 3 at the time the render thread starts its iteration the render thread wil transform using set 2 giving it enough time to finish drawing because the logick thread first needs to complete 8 additional iterations (4,5,6,7,8,9,10,1)before getting back at set 2.

since my logic thread runs at a 100 hz the framerate would have to drop below 12.5 or something before z-fighting would return and even then i can just increase the amount of sets :P

does this sound logical/sane/feasible?

if not what would you do?

This topic is closed to new replies.

Advertisement