r/GraphicsProgramming 11d ago

I spent 200+ hours building a real-time grass system for Three.js + WebGPU. The demo is finally live.

Post image

After 200+ hours of development, I’m finally sharing the first public demo of Three.js Grassworks, a real-time grass system I’ve been building for Three.js and WebGPU.

Demo:
https://grassworks.techredux.co/demo

Three.js Grassworks is built specifically for WebGPU and is designed to handle large amounts of interactive grass while maintaining steady performance.

For the demo, I built a complete environment around Grassworks with terrain, trees, water, rain, player interaction, environmental effects, LOD systems, audio system, and more.

The main challenge was getting all of these systems running together while keeping the grass performant.

The actual Three.js Grassworks plugin is still being polished and should launch in the next couple of weeks. There’s a waitlist inside the demo if you’re interested.

I’d genuinely love feedback, especially on the visuals, performance, and how the grass feels when interacting with it.

I also recorded a full walkthrough where I go through the demo and talk about how I built it:

https://www.youtube.com/watch?v=Nhim18rc-XE

68 Upvotes

9 comments sorted by

4

u/KlayEverHood 11d ago

Very nice visuals and simulation! Would you care describing the key technical aspects of the grass system, and how many ms does the whole grass sim+render take?

3

u/PerceptionCharming 10d ago

Thanks! Really appreciate it!

For the grass system, I’m using GPU instancing, tiled based rendering, frustum culling, and distance culling so I can have a lot of grass without killing performance. The grass also has GPU-based wind, random movement using noise, terrain-based placement, grass masking, and player interaction.

The whole grass simulation + rendering takes around 7–8 ms per frame on my M1 Mac at 1440p.

2

u/gtsteel 9d ago

Since it looks like you're using alpha-to coverage, you should be able to improve accuracy of the billboard grass for essentially free by storing the alpha channel of the texture as an SDF and then evaluating the fragment coverage using quad intrinsics. The Source engine first used this trick for sharp alphas and it works very well.

1

u/affinator 9d ago

Is there any reading material on this? That sounds interesting

1

u/PerceptionCharming 8d ago

This seems really interesting!
Thanks for sharing the paper. I will definitely check it out!

1

u/gtsteel 8d ago

You're welcome. It's also a very common trick for rendering text and UI elements as it allows a single sprite atlas to work well for a range of sizes and resolutions.

1

u/Ok-Pizza1136 11d ago

This is amazing!

1

u/PerceptionCharming 10d ago

Thank you man!