Three-nanite: Unreal Nanite in Three.js
16 comments
·February 7, 2025jms55
tetris11
Bevy is very cool! Do you have nanite demos to view?
jms55
Not a very impressive example yet, it's mainly there for our CI system[1] to ensure that no one accidentally breaks the meshlet feature, but there is an example you can run to get a basic idea of the feature.
You can download Bevy https://github.com/bevyengine/bevy, and run `cargo run --release --examples meshlet --features meshlet`. After it compiles you'll get prompted to download a bunny.meshlet_mesh file. Click the link to download and create and place it in the appropriate folder, and then run the example again.
There's also this video from the Bevy 0.14 release notes demonstrating it, but performance/quality has improved a _lot_ since then: https://bevyengine.org/news/bevy-0-14/many_bunnies.mp4
andrewmcwatters
I was so impressed when I first read about this. Fantastic work.
jms55
Thank you for the kind words! Expect another blog post sometime soonish for Bevy 0.16. Although a smaller one, I've unfortunately not had much time to contribute to Bevy and work on virtual geometry lately.
tetris11
It would be really fun to see a Nanite demo where the Reference PoV and and Viewer PoV were independent.
That way I could see exactly which meshes are being rendered (w.r.t to the reference), and then rotate around the scene (as a viewer) to get a better idea of where mesh cutting/optimizing is happening.
Right now, all I see from these demos are highly performant scenes with rabbits in them. I want to peek behind the veil and see how deep the rabbithole actually goes!
araes
Not sure if this is the creator of the Github project, yet one improvement would be view frustrum culling.
Registers 700,000 triangles even when there's nothing visible on-screen, just because the Stanford rabbits happen to be nearby in terms of LOD.
Even something "simplistic", like LOD quadtree culling with a view frustrum would probably dramatically reduce triangle counts and speed up rending even further.
That said, still an impressive demo, and compared to what I often see done with three.js, really fast rendering speeds for the sheer quantity of instanced geometry being shown.
On pretty mediocre old hardware, circa late 2010's Celeron with integrated graphics, getting 20 fps near-field in about the worst case of display, and 40 fps with the far-field heavily LOD reduced.
ivanjermakov
Aren't other optimizing techniques are out of scope? Why would author implement frustum culling in a tech demo for dynamic LODs?
tomovo
I'd say if it's proof of concept just to follow the process that Nanite does, then other optimizations are out of scope. However if it's supposed to achieve the same GOAL as Nanite, which I think is provide rich detail at reasonable frame rate then 1) add mode with full LOD to compare performance gains & visual impact 2) do low hanging fruit kind of optimizations as well to match whatever Unreal probably does as well.
andrewmcwatters
Because it's a deeply integrated part of virtualized geometry.
You could just cull an entire object, but the larger the associated geometry, the more unnecessary geometry you keep out of the viewport. This defeats a large selling point of virtualized geometry. It's not just about clustering and simplifying meshes from an extremely high detailed source, but also rendering the portions that are actually important.
That being said, this implementation is very cool as it stands. It addresses arguably the most important actual parts of virtualized geometry, I think.
opera_phantom
Somewhat related, but Unreal Engine 5 runs in a browser now using WebGPU, courtesy of a startup. The spacelancers demo is the best performing one, looks visually stunning too. No nanite support yet though, unfortunately:
vivsbest
This is seriously impressive stuff.
ImHereToVote
Awesome. I understand it doesn't use Nvidias recent open sourced Nanite like LOD meshlet clustering pipeline.
jms55
Nvidia's recent stuff is also really cool, but more aimed at raytracing using their new CLAS extensions, rather than raster like Nanite. The main difference is that Nvidia is using SAH splits to partition the mesh, since spatial distribution of triangles is really important for ray tracing unlike raster.
AMD should also be coming out with something like this soon, maybe when RDNA4 launches. Just yesterday they released their DGF SDK, based on the paper they published a bit ago for basically the same thing as Nvidia (except Nvidia does the compression in hardware with an opaque format, rather than leaving it up to devs to implement an open format via an SDK).
null
null
Self promotion: I've been working on a WebGPU version of Nanite for over a year now. If you found the OP's work interesting, you might enjoy my very long blog posts on the topic.
https://jms55.github.io/posts/2024-06-09-virtual-geometry-be...
https://jms55.github.io/posts/2024-11-14-virtual-geometry-be...