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

Allow depth direction preference option. #8

Open
AdaRoseCannon opened this issue Aug 20, 2024 · 6 comments
Open

Allow depth direction preference option. #8

AdaRoseCannon opened this issue Aug 20, 2024 · 6 comments

Comments

@AdaRoseCannon
Copy link
Member

In WebGPU it is possible to format your depth buffer in reverse Z for an improvement of depth fidelity.

Many WebGL experiences today use forward-z. For Safari on VisionOS we need to convert forward-z buffers to reverse-z for os compatibility which is expensive.

It would be good for the Session to be able to indicate to Websites that the session prefers reverse Z and for the Website to indicate that it has indeed provided reverse-Z. This would allow an additional performance improvement for WebGPU experiences.

@toji
Copy link
Member

toji commented Aug 21, 2024

As far as the site indicating that it's using reverse depth goes, that should already be supported via setting depthNear to a greater number than depthFar. See the RenderState section in the spec:

depthNear and depthFar are used in the computation of the projectionMatrix of XRViews. ... They also determine how the values of an XRWebGLLayer depth buffer are interpreted. depthNear MAY be greater than depthFar.

That allowance for near and far to be reversed was added specifically to enable reverse-Z rendering.

It should be noted that the reason that reverse-Z rendering is preferred in many cases doesn't have anything to do with performance, but instead is about more evenly distributing depth precision across the full range of the depth buffer, which can help quite a bit with z fighting in distant geometry. I've always liked how this post visualizes the benefit.

That page also demonstrates why the technique is not used very often with WebGL. The [-1, 1] depth range used by OpenGL/WebGL's clip volume counteracts many of the benefits of a reversed Z buffer, bunching up most of the precision in the middle of the range. This is probably why almost nobody has bothered to use it for WebXR content to date. For the same reason I'm a bit hesitant to think that a property advertised from by the API as to which method is preferred with be very impactful. Most WebGL-based content will probably continue to be forward-Z, and I suspect a great deal of WebGPU content will be reverse-Z, especially if we can advocate for it as a best practice. Implementations will have to deal with either regardless, since we've been advertising this as a capability of the API since day 1.

@AdaRoseCannon
Copy link
Member Author

I think what would be really useful when we start making samples for WebXR+WebGPU we include ones for both depth types.

@klausw
Copy link

klausw commented Aug 22, 2024 via email

@AdaRoseCannon
Copy link
Member Author

Is there any implementation where reverse Z has a performance cost due to
requiring extra operations, basically the inverse of the Vision OS
siruation? That seems unlikely, but if it does exist it would be an
argument for exposing such a runtime preference.

I would be really interested in this. As much as I would love for there to be a developer hint I feel developers would probably pick their depth direction early on in the project for whatever is appropriate for their content and then probably be unwilling to change it on the fly since it will likely expose unexpected depth issues. Or if it's something that is handled at the library level then a display which differs from the status-quo with regards to this hint will see experiences not work simply because the developers didn't test their depth both ways.

If it does seem unlikely that there will be a performance impact for other platforms it would be great if reverse-z was the default for WebXR+WebGPU.

@CodyJasonBennett
Copy link

FWIW, I implemented reverse depth in the WebGL part of three.js with mrdoob/three.js#29445 if that in any way facilitates testing here, and can implement this on the WebGPU side as well. Uses EXT_clip_control since the [0, 1] clipping range is necessary, with [0, 0.8] being most of the usable range of floating point, and inverting the near/far planes gives a better distribution overall with perspective projection. I don't see anything left here other than receiving matrices in the right range with #12, and developers flipping the reported near/far values as per #8 (comment).

@mwyrzykowski
Copy link

We could consider removing the default values of 0.1 and 1000 when the WebGPU backend is specified during session created (or flipping them so near is 1000 and far is 0.1). Other than that, I agree, I don't see anything to do.

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

No branches or pull requests

5 participants