Depth sorting

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Depth sorting

Postby Ian » Mon Nov 06, 2017 3:15 pm

The model3 draws many co-planar polys and you never see z fighting. I know there is a stencil test option, and as far as I can see it's only ever used for the shadow under the car in sega rally2. That's the only game to set that bit anyway. For the rest of the games, z fighting seems to magically disappear.

My working theory is the hardware must be doing a depth only pass on translucent polys. By translucent I mean PolyAlpha() not TextureAlpha(). Texture alpha is a different issue.
So it could be doing something like

Pass 1, render opaque polygons normally.
Pass 2, render translucent polys but just write depth values
Pass 3, render translucent polys normally.

The z buffer would be already filled so only the topmost polygons would render.

This is what we have currently (without the stencil hack)
Image

The left side is fully opaque, because the back side renders first, then the front of the balloon renders ontop and blends together. On the right side the front renders first, so the back is automatically depth tested out and never draws.

This is what the real hardware is doing. Quality is the best I could find :(
Image

Image

Image

Looks to me like the entire balloon is semi transparent. This is probably only possible with either depth sorting each individual poly .. which seems extremely unlikely. Or doing a depth only pass first.

Using the stencil test instead of a Z pass results in this monster
Image

The shading is wrong because on the left you only see the back side, and on the right you only see the front. So this can't be the solution that was used.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Depth sorting

Postby Ian » Mon Nov 06, 2017 3:20 pm

To disprove this .. should be able to find some examples of translucent polys blending together in the same priority layer.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Depth sorting

Postby HarryTuttle » Mon Nov 06, 2017 3:47 pm

Ian wrote:Pass 1, render opaque polygons normally.
Pass 2, render translucent polys but just write depth values
Pass 3, render translucent polys normally.


That's basically what I did time ago for each priority level (ending up to many render passes) fixing, among the others, the breaking glass scene in ECA attract mode. However I messed up 'cause I wrongly included also TextureAlpha() :roll:

But I think that's the right approach.
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: Depth sorting

Postby Ian » Mon Nov 06, 2017 3:52 pm

I am not sure how else it could be done. The balloons show it's clearly not using the stencil buffer.
Here is one more example that we have seen before from ECA

Image

There is some specular applied to the glass, but absolutely no blending overlap.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Depth sorting

Postby Ian » Sat Nov 18, 2017 9:59 am

Not had much time to supermodel this week
I did briefly look into this issue again. I found simple doing a depth pass first for transluent polys is not enough. The reason is because 2 polys drawn at the same depth, will be drawn and blended twice. Ie the shadows in many games.

The solution it to do a depth pass, then change how the stencil buffer and depth test work

So
something like this

Code: Select all
   glStencilFunc   (GL_EQUAL, 0, 0xFF);         // basically stencil test passes if the value is zero
   glStencilOp      (GL_KEEP, GL_KEEP, GL_INCR);   // if the stencil test passes, we incriment the value
   glStencilMask   (0xFF);


What that does is only incriment the stencil value, if the depth test passes

Then we render the scene for opaque polys normally

Then ..

Code: Select all
      glColorMask   (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);         // disable colour writing for a depth pass   
      RenderScene   (pri, false, PolyType::polyAlpa);
      glDepthFunc   (GL_EQUAL);
      glColorMask   (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);            // re-enable again
      glEnable   (GL_STENCIL_TEST);
      RenderScene   (pri, false, PolyType::polyAlpa);
      glDisable   (GL_STENCIL_TEST);


Color mask turns off writing to the colour buffer. So the first render scene only writes depth values.
Then we change the depth function to only pass if the depth values are equal to those in the depth buffer. So this will only draw the topmost polys. It will still z fight with co-planar polys with the same depth values, but we can fix that with the stencil buffer. If the depth test passes, it will increment the value in the stencil buffer, and prevent further co-planar polys from drawing.

This almost totally fixes every z fighting issue in the games. But there are still some minor order related transparency errors
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am


Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 1 guest