Sign in to follow this  

eliminating z-fighting resulting from multi-pass rendering

This topic is 3097 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
I don't know how you're missing the answer which was stated multiple times: use the exact same transformations for the final vertex position in each pass.

i.e. mul(worldViewProj, position) != mul(mul(viewProj, world), position)
etc.

Share this post


Link to post
Share on other sites
likewise im not quite sure how ur missing the problem ive stated multiple times :P

i cant use the exact transformation again since it might have changed in the meantime.. rendering and logick are on different threads

Share this post


Link to post
Share on other sites
Quote:
Original post by EternityZA
i cant use the exact transformation again since it might have changed in the meantime.. rendering and logick are on different threads
So double-buffer your logic updates - changing the data while rendering it is really not a good idea.

Share this post


Link to post
Share on other sites
Quote:
Original post by EternityZA
likewise im not quite sure how ur missing the problem ive stated multiple times :P

i cant use the exact transformation again since it might have changed in the meantime.. rendering and logick are on different threads


Multiple-pass rendering implies the following:


1) renderScene()
1.a) renderObject()
1.a.1) renderObjectWithPass(0)
1.a.2) renderObjectWithPass(1)
// repeat for rest of passes
// repeat for rest of objects


Logic does not come into the picture at all, every scene render should be rendering all of the passes, thus resulting in multi-pass rendering.

Now - if you're saying that you render the scene, do logic, then render the scene again as a second pass, then we can begin by saying that is not multi-pass rendering, but simply per-frame rendering. If you know how the second render should appear over the first render, you can play with the depth bias functions or perhaps even disable depth checking/writing.

Share this post


Link to post
Share on other sites

This topic is 3097 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this