Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set better near/far planes #7573

Closed
Pessimistress opened this issue Nov 8, 2018 · 14 comments · Fixed by #8502
Closed

Set better near/far planes #7573

Pessimistress opened this issue Nov 8, 2018 · 14 comments · Fixed by #8502

Comments

@Pessimistress
Copy link

Motivation

To reduce z-fighting effect when rendering 3d objects in custom layers

Reproduce steps:

  • Click on https://codepen.io/Pessimistress/pen/aQNKKg
  • The left is rendered using deck.gl canvas, the right is rendering a deck.gl layer as custom Mapbox layer
  • Rotate each map. The right one has visibly more flickering due to z-fighting.

Cause

deck.gl's projection matrix has its near plane set to 0.1, and far plane set to 10 * distanceToTopEdge. This was implemented to match the projection matrix used prior to Mapbox 0.29: https://github.com/uber/deck.gl/blob/master/modules/core/src/viewports/web-mercator-viewport.js#L57

When using deck.gl with Mapbox's custom layer, we set the near plane to 1 / height and far plane to 1 * distanceToTopEdge, so that it matches the projection matrix used in Mapbox 0.50: https://github.com/uber/deck.gl/blob/master/modules/mapbox/src/mapbox-layer.js#L58

I wonder what was the motivation behind Mapbox's change in its projection matrix calculation. In our use cases, the old settings definitely perform better.

@mourner
Copy link
Member

mourner commented Nov 21, 2018

The change happened in 0b5520f as a part of #3790. @ansis any thoughts on this?

@ansis
Copy link
Contributor

ansis commented Mar 5, 2019

I haven't had the chance yet to dig into why we changed the values but I wanted to note that #7821 should help with depth buffer precision. Drawing in the main framebuffer gives us 24 bits of depth precision while the old approach only had 16 bits.

@Pessimistress
Copy link
Author

I can give it a try. Is #7821 released officially or as a beta?

@chloekraw
Copy link
Contributor

@Pessimistress - neither, we'll do the beta release on March 20 / final on March 27 with this change

@Pessimistress
Copy link
Author

Updated the above codepen to use 0.54.0-beta.1, still seeing the aliasing and flickering. Is there anything we need to do to unlock the new feature?

@jamiebordewyk
Copy link

@chloekraw Is there anything that @Pessimistress needs to do to unlock the feature?

@chloekraw
Copy link
Contributor

@Pessimistress - no, I think the most likely explanation is that @ansis' theory that it should help is not panning out. He can confirm though and he's also taking a look at some of these custom layers issues you've opened this week.

cc/ @jamiebordewyk

@shayke
Copy link

shayke commented Apr 10, 2019

I just wanted to point out that the antialias: true flag to the map itself works (just add it to the codepen and see).

I'm also experiencing z-fighting though, not sure if it's pure camera near/far, I think I read somewhere that deck.gl also uses a z-offset for each layer and maybe custom layers should (by the user, not mapbox) also do that in case of 3d layers with same z?

@ansis
Copy link
Contributor

ansis commented Apr 10, 2019

I spent some time digging into the switch from [0.1, 10 * distanceToTopEdge] to [1 / height, 1 * distanceToTopEdge]. I think the near plane was moved closer to the camera to prevent visible clipping when the camera is close to the object. The far plane was moved closer because it was unnecessarily far and that was wasting precision.

It's the near plane changing from 0.1 to ~0.001 that causes these artifacts. Switching to [0.01, distanceToTopEdge] seems like it should have the same precision as the old approach while having a slightly closer near plane.

I've also noticed that this flickering doesn't happen for mapbox layers. It looks like the flickering isn't caused by a lack of precision in the depth buffer, but rather a lack of precision when calculating the depth value. Is there anything that can be done on deckgl's side to lose less precision while calculating the depth value in the shader?

@Pessimistress
Copy link
Author

Pessimistress commented Apr 23, 2019

I just wanted to point out that the antialias: true flag to the map itself works

That's awesome, thank you!

I've also noticed that this flickering doesn't happen for mapbox layers

The mapbox layers you can see at this zoom level are all 2d layers. As you zoom in the z-fighting gets less severe. I do not think Mapbox's building layer is available from this far out.

@jamiebordewyk
Copy link

@ansis @chloekraw any thoughts on the @Pessimistress feedback?

@ansis
Copy link
Contributor

ansis commented Jul 17, 2019

I copied the jsfiddle into our debug page (debug-z-fighting-deckgl branch) and added a fill-extrusion example to confirm that if the same features are added as fill extrusions they do not suffer from z-fighting. I then tweaked the nearZ value until I found one that fixed the deckgl layer while not regressing our building-near-camera-clipping fix. PR here: #8502

@tsherif
Copy link

tsherif commented Aug 13, 2019

Moving the near plane generally has a much more significant effect on depth precision than moving the far plane, so it's advisable to use as large a near value as possible. This article is a great resource on the matter (despite its unfortunate choice of font and background): https://www.sjbaker.org/steve/omniv/love_your_z_buffer.html

@lachlanphillips
Copy link

This appears to be also related to the fact that the near plane doesn't take into account the FOV. Low FOVs put the camera at near infinite distance from the map, which gives very little z-depth resolution.

Ideally the user should be able to either manually set the near and far values for the camera, or set the nearZMultiplier and farZMultiplier values. To fix this you definitely need to move the near plane further from the camera, but this doesn't appear to be doable at present.

Is there any way to set these values as is? Workarounds?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants