-
-
Notifications
You must be signed in to change notification settings - Fork 36.1k
WebGLRenderer: Sort on bounding sphere center, not origin #25913
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
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
|
One other effect to note – with this change, it's more likely that sort order will change as the camera moves. That's really the point of sorting by z-depth from the camera in the first place! But the sort is likely more discriminative now, so it's something to be aware of, if a previously-stable sort is now view dependent. |
* EnvironmentNode: Fix flipY after improve positionWorldDirection * WebGPUBackground: Fix clip background * WebGPURenderer: Added update from #25913 * WebGPURenderer: Improve vertex format support. * Example webgpu_backdrop: Fix space * Added webgpu_loader_gltf_compressed example * cleanup
|
I hadn't seen this change. This will break intent for a lot of models, quite to the contrary to what the issue description states people are aware that pivot position influences render order as it does in any engine. Three will now differ from this and make it impossible to actually control render order on purpose. Please revert this change. It makes it impossible to intentionally control order of transparent objects. Let me know if you need example models that now break. Unity and Unreal sort by pivot (so, by origin, not by bounds). |
|
I searched various discussion threads and found (non-authoritative) claims that Unreal, Unity, and Babylon.js all sort by center of bounds. I couldn't find claims they sort by pivot point. I don't have proof or authoritative references here, and it would be great to have that — if you have more information about Unity and Unreal here, could you share it? |
|
Comment by a Babylon.js developer, 2021 — "the default front to back sorting is using the bounding box center as the sorting key". Comment by a Senior Software Engineer at Unity, 2015 — "The same way all transparent objects are distance-sorted in unity, which is simply using the center of the AABB (I just checked the code for this, and it surprised me a bit actually.. I would have expected some consideration of box size and closest point to the camera, but it is purely the centre of the box)". |
|
Would be nice to have a debug GLB file that shows how engines sorts objects. |
|
@donmccurdy I'll double check! |
This doesn't sound like a good reason to do something similar-ish to other engines If it's possible to make this change coherent with all the references you mentioned with 8 arithmetic operations I think it's worthwhile |
|
Much of what three.js (or any renderer) does is finding acceptable approximations for exact but costly calculations. In this case, both are approximations. Consider that the additional function calls and arithmetic operations have overhead per object in the scene, and that there may be many, many objects. There would be a stronger case for using the AABB center instead of the sphere center if we had either of: (a) real-world examples where this choice matters, or (b) performance benchmarks showing they are similarly fast for large (1000+ object) scenes. |
|
As far as I read the code I linked to, computing the boundingBox is 2 times faster than the boundingSphere in regards to the number of vertices That being said, I think the better argument here is the one you made that it's better to have the same behavior as other engines¹ - and in that regards the boundingSphere's is probably closer but also quite different than the boundingBox' center (b): https://jsfiddle.net/ayn8gus0/2/, https://jsfiddle.net/pgt13c5k/12/ Generating a counter example should be simple but iff (b) is incorrect ( --- footnotes ² I'm pretty sure the |
|
Ah sorry for miscommunication here, but the cost of computing the bounds is not the issue. To my understanding we compute both shapes anyway for frustum culling. That is a one-time initialization cost, unrelated to this PR. What I'm concerned about is the per frame cost of extracting the center from our pre-computed bounds. If we're doing that at 60 FPS for 1,000 objects, 1–2 milliseconds of overhead per frame would matter. |
|
Ah, oh, thanks for clarifying. I think it's a side effect of this PR to consider even if only for the first frame (encountered in the wild) And regarding the box vs. sphere - I think I'm becoming convinced the center is the same according to the current implementation - the additional pass seems only related to the radius |


It's common practice for modelers to "apply" or "freeze" transforms, setting object origins to zero, which creates a problem for our default sort.
By sorting on the center of an object's bounding sphere, rather than its origin, we may improve the odds of drawing triangles in the intended order. This change fixes #25820, and could reduce overdraw more broadly. I did some light performance comparisons on larger scenes – after the bounding sphere is initially computed, I didn't see a significant difference in sorting one way or another.
I didn't find any authoritative sources on other engines, but random internet comments claim Unity and Unreal Engine sort by the bounding box center. I use the bounding sphere instead, simply because it's easier and more efficient to access its center than to compute the center of a THREE.Box3 instance.