-
-
Notifications
You must be signed in to change notification settings - Fork 36k
Add BatchedMesh LOD and BVH example page #31239
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
This is really cool. I think it would be neat if there was some way to see what the LODS closer to the horizon look like. Maybe a boolean settings like 'staticLOD' or 'freezeDistanceCalculation' that maintains the last stored distance from each mesh to the camera, such that when you move towards the back of the scene you can more clearly see how the LODs detail changes based on distance. Maybe my eyes are just bad and I just can't see the LODs for the farthest objects : ) |
I could override the |
I've added the freeze flag with latest commit. |
I think the small value of the far plane is giving misleading results.
iMac M1, Chrome 137.0.7151.120 and Safari 18.5 (20621.2.5.11.8) -- running full-screen |
Yes, it's true, the performance becomes bad in that case. By increasing the Also on the CPU side we have a slowdown due to the sort of instances (500k each frame) and frustum culling that loses the benefits of using BVH by having to filter all nodes. I can modify the example if necessary, I can add LODs with fewer triangles, space the instances more between them to make them render less, scale them differently, or change the example completely. Updated example here. |
It seems to be the case that uploading even a not-so-large buffer to the GPU is causing framerate dips. It's not exactly clear to me why this is the case because the buffers are otherwise not that large. When following your steps the BatchedMesh is drawing (and therefore uploading an instruction buffer for) ~60,500 meshes which results in an FPS of 40 down from 120. However that's only 0.5 MB of data to upload for a draw (two Int32 buffers at 60,500 elements). However when explicitly marking the "matricesTexture" as "needsUpdate" with a shorter far plane, forcing a full reupload of the texture every frame my framerate only dips to 100. That texture is 3.9MB, though (dimensions of ~492x492). It's really not clear to me where or why this bottleneck is here. Perhaps @greggman or @kenrussell have some insight here? To boil it down: Why does uploading a pair of buffers totally 0.25MB for multidraw tank framerate so significantly (120 to 40 fps) while uploading a texture of size 32MB every frame does not (120 to 100 fps)? This is in WebGL2 on Chrome. |
@gkjohnson what OS and GPU type is this slowdown happening on? I have a feeling that the heuristics I added to ANGLE's Metal backend on top of @greggman 's Does replacing any |
#31239 (comment) updated with OS / device info |
I'm running on:
But I see the same slowdown on Safari Version 18.5 (20621.2.5.11.8).
Can you elaborate on what you mean by this? Is this something you're suggesting to do in ANGLE or for WebGL calls? It doesn't look like we need to use either of these functions when calling extension.multiDrawArraysWEBGL. |
@gkjohnson my thought was that if the app-level code (either in Three or in these demos) has one or more buffer objects that it's updating using However if the problem's happening on Windows too, then the root cause is probably different and this workaround probably won't work. (Or maybe ANGLE's D3D11 backend has the same performance issue.) Apologies, I'm on leave through the end of July, and can't help in any significant way right now. Hope that @greggman or @vonture might be able to help. Please consider posting to the WebGL Dev List and, if you can provide a small test case showing the poor performance of the |
Thanks Ken -
Yeah the Int32Array buffers are passed directly to the multi draw functions with the length of buffer to use, as required by the API. And the issue still occurs when passing the full length of the buffers in as the draw count.
cc @CodyJasonBennett is providing a small, WebGL-only demonstration of the poor performance when using large buffers with multidraw something you would be interested in helping to provide? I'd look into it but I don't think my raw WebGL API knowledge is quite as sharp. Specifically I think it's worth showing that the performance is better when uploading a significantly larger texture vs a smaller amount of buffer data for multidraw. |
Sure. I understand the issue is not updating a I have experiments where I stream geometry with As for known issues, I am only aware of https://groups.google.com/g/webgl-dev-list/c/ChKpSHZNbI8/m/1oUaWiCBCQAJ?pli=1 where the CPU-side buffers can undergo an expensive type conversion in the browser, but we seem to pass the correct type to avoid it, reading the related commits. |
I've created a small demo here. BatchedMesh is passing Int32Arrays into the multiDrawArraysWebGL function to draw a geometry that does not change and is using textures to store transform data. That texture also does not change unless a transform is updated. The core of the issue is that when drawing all 50,000 objects with no sorting or culling (meaning no extra work per frame) the framerate dips significantly (~55fps on my machine down from 120) and it's not clear why. The first assumption might be that uploading those multidraw buffers may be too large and slowing down the frame when uploading to the GPU. But if you draw a low amount of objects and upload a 500px x 500px floating point texture every frame, which is ~10x more memory, then my framerate remains at 120 so buffer size being the only issue doesn't line up. So I think a minimal WebGL demonstration here would be showing that calling Happy to talk about this more on Discord if needed. |
I'll post this to the WebGL dev list and angle later but I've created a reproduction showing multi-draws poor performance with a large amount of instances here. The repro shows that there is a drastic performance drop when drawing the same amount of instances with multi draw compared to |
thanks for the repo! |
Thanks! @greggman @kenrussell - would you still like me to make a topic on the WebGL Dev List and make report an Angle bug? |
Description
Hi! I've created an example that demonstrates how to manage LODs for
BatchedMesh
geometries, along with BVH acceleration for raycasting and frustum culling.It's built using my
@three.ez/batched-mesh-extensions
library together withthree-mesh-bvh
by @gkjohnson.@mrdoob Unlike the version published in X, here I also added raycasting and GUI.
You can check out the live demo here: https://agargaro.github.io/three.js/examples/webgl_batch_lod_bvh.html
Is that okay or should I create a different type of example?