-
-
Notifications
You must be signed in to change notification settings - Fork 36.2k
WebGLRenderer: Add ReversedCoordinateSystem, fix shadows with reverseDepthBuffer.
#31370
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
Conversation
…rseDepthBuffer`.
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
| float depth = 1.0 - unpackRGBAToDepth( texture2D( tDiffuse, vUv ) ); | ||
| gl_FragColor = vec4( vec3( depth ), opacity ); | ||
| float depth = unpackRGBAToDepth( texture2D( tDiffuse, vUv ) ); | ||
| #ifdef USE_REVERSEDEPTHBUF | ||
| if ( depth == 1.0 ) depth = 0.0; // wrong clear value? | ||
| // [0, 1] -> [-1, 1] | ||
| depth = depth * 2.0 - 1.0; | ||
| // Reverse to forward depth (precision is already destroyed at this point) | ||
| depth = 1.0 - depth; | ||
| #endif | ||
| gl_FragColor = vec4( vec3( 1.0 - depth ), opacity ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ensures that appearance is consistent regardless of configuration (press T on the shadow map example).
The special handling on L50 is a clearing bug, though, but I am not sure how to go about it. The same is in shadowmap_pars_fragment.
| /** | ||
| * Reversed coordinate system [1, 0]. | ||
| * | ||
| * Used for reverse depth buffer. | ||
| * | ||
| * @type {number} | ||
| * @constant | ||
| */ | ||
| export const ReversedCoordinateSystem = 2002; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we not technically need "ReversedWebGPUCoordinateSystem" and "ReversedWebGLCoordinateSystem"? Or is this just for WebGPU?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point reverse depth buffer will also be supported in WebGPURenderer. If the respective computations in Matrix4 differ in WebGL and WebGPU, then we should indeed rename to ReversedWebGLCoordinateSystem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only need one. Matrix4 as implemented will just work in WebGPU (its derivation is based on how we make one for WebGPU normally), provided that depth comparisons and clear values are configured to be reversed. Reverse depth can only be implemented with a [0, 1] NDC range, which is what WebGPU and modern graphics APIs use and what we use in WebGL via EXT_clip_control, which is otherwise [−1, 1]. I explain why this range matters in floating point and the nature of it in previous comments, more recently in #29445 (comment).
Regarding changes, apart from the reversed range, they are the same as you would make when migrating from WebGL to WebGPU. The WebGPU side would only be concerned about the reversed range. The only other constant I would consider would be for an infinite reversed matrix, which only works for perspective #11755. Explicitly handling Infinity might be a better way, provided we document it.
Importantly, as we no longer automatically convert the projection matrix for a configured camera, it is possible to construct an infinite reversed projection matrix in user-land. I'd be happy to create an example for exploration purposes and show its effect for derivations in post-processing. I found it simplifies things tremendously when dealing with depth and occlusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reversed coordinate system?
The depth range or depth mapping is reversed, not the coordinate system.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is not true here, and yet the use is still incorrect, although not strictly, but this is the API we established to make WebGPU possible #26140, which uses modern D3D convention. Do we really need to be pedantic about this, or can you suggest another API that would make sense?
I must say that I am incredibly unhappy to entertain sweeping, breaking changes for the sake of correctness if not strictly (in)correct, and I think that notion is disillusioned to begin with. Unless you have another suggestion, I think we need to live with words not having a strictly encompassing or even correct meaning at all times.
Fixed #29770
Description
Introduces
ReversedCoordinateSystemto produce a [0, 1] reversed projection matrix. This was previously done internally on the GPU with #29445. For backwards compatibility purposes, I have deprecated this conversion, and it now emits a warning, encouraging cameras to be configured withReversedCoordinateSystemwhen using reverse depth. As reverse depth in WebGL relies onEXT_clip_control, it is best to use feature detection:Shadow maps are also fixed in this PR, which previously had misconfigured shadow cameras and the wrong comparison operator (as depth is now reversed). Shaders that rely on a specific NDC range or linearize depth still need to be updated.
I have not updated cascaded shadow maps (CSM) and other add-ons like GTAO with this PR.
All shadow map types were tested with this PR. Below is a quality comparison after changes with/without
reverseDepthBuffer.Note that an ideal setup for
reverseDepthBufferconfigures a floating-point depth buffer in post-processing #29445 (comment).BasicShadowMapPCFShadowMapPCFSoftShadowMapVSMShadowMap