# High-Performance Grass Rendering in Three.js + WebGPU

**URL:** <https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175>\
**Category:** Showcase\
**Tags:** library, culling, grass, lod, tsl, geometry, shaders, webgpu\
**Created:** [September 8, 2026, 7:41pm UTC](https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175 "2026-09-08T19:41:35Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Muhammad\_Bilal](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@Muhammad\_Bilal](https://discourse.threejs.org/u/Muhammad_Bilal)\
**Post date:** [September 8, 2026, 7:41pm UTC](https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175/1 "2026-09-08T19:41:35Z")

</div>

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.

The demo is now live:

> **[Three.js Grassworks — Live Demo](https://grassworks.techredux.co/demo)**
>
> Experience Three.js Grassworks, a high-performance procedural grass system for Three.js with GPU-driven deformation, dynamic wind, terrain interaction, and real-time rendering.

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 Three.js Grassworks, including terrain, trees, water, rain, player interaction, environmental effects, LOD systems, and more. The interesting challenge for me was getting all of these systems running together while keeping the grass performant.

The actual Three.js Grassworks plugin is still being polished and is planned to launch in the next couple of weeks.

I’d really appreciate feedback from the Three.js community, especially around performance, visuals, and the overall approach. There’s a waitlist inside the demo for anyone interested in the plugin.

I also made a video walkthrough of the demo:

[![](https://img.youtube.com/vi/Nhim18rc-XE/maxresdefault.jpg "Three.js Grassworks: The Demo Is Finally Here! | Link in Description") ](https://www.youtube.com/watch?v=Nhim18rc-XE)

Thanks for checking it out. I’d love to hear what you think.

---

<div class="post-metadata">

**Author:** ![Muhammad\_Bilal](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@Muhammad\_Bilal](https://discourse.threejs.org/u/Muhammad_Bilal)\
**Post date:** [September 18, 2026, 11:39am UTC](https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175/2 "2026-09-18T11:39:54Z")

</div>

## Three.js Grassworks is officially live

I’m excited to finally make Three.js Grassworks available to the public.

[Buy Three.js Grassworks](https://grassworks.techredux.co/)

The goal was simple: make it possible to add large scale, realistic, performant grass to a Three.js project without having to build the entire system from scratch.

It’s built around WebGPU and TSL and has been designed with real-world projects in mind, not just a demo scene.

Grassworks is a one-time purchase and includes support and ongoing updates.

I’m really looking forward to seeing what people build with it.

If you try it out, I’d love to hear your feedback, ideas, and feature requests.

Here’s the trailer for it:

[![](https://img.youtube.com/vi/ZC7fdt0GwQA/maxresdefault.jpg "Three.js Grassworks — The Next Generation of Procedural Grass") ](https://www.youtube.com/watch?v=ZC7fdt0GwQA)

---

<div class="post-metadata">

**Author:** ![Muhammad\_Bilal](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@Muhammad\_Bilal](https://discourse.threejs.org/u/Muhammad_Bilal)\
**Post date:** [September 22, 2026, 10:33am UTC](https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175/3 "2026-09-22T10:33:30Z")

</div>

A small update to Three.js Grassworks.

I’ve added a few more presets to the live demo, so there are now more grass styles to experiment with.

I’ve also started a video series going through Grassworks, its different features, and how you can use it in your own Three.js projects.

Video series:  
https://www.youtube.com/embed/videoseries?list=PLBZ2CAONpf7g&wmode=transparent&rel=0&autohide=1&showinfo=1&enablejsapi=1

Live demo:

> **[Three.js Grassworks — Live Demo](https://grassworks.techredux.co/demo)**
>
> Experience Three.js Grassworks, a high-performance procedural grass system for Three.js with GPU-driven deformation, dynamic wind, terrain interaction, and real-time rendering.

If you’ve been following the project, I’d love to hear what you think.

---

<div class="post-metadata">

**Author:** ![Muhammad\_Bilal](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@Muhammad\_Bilal](https://discourse.threejs.org/u/Muhammad_Bilal)\
**Post date:** [September 30, 2026, 1:40pm UTC](https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175/4 "2026-09-30T13:40:08Z")

</div>

Another update on **Three.js Grassworks**.

One thing I’ve never really liked about Grassworks was the visible LOD pop-in. I tried a bunch of different approaches to solve it, but none of them actually worked well enough, so I eventually settled on an immediate LOD switch.

For **v1.1.0** , I finally revisited it.

The solution combines **related LOD geometry with spatial dithering**. Lower LODs now remove blades from the higher LODs while keeping the remaining blades in the exact same positions. This gives me a consistent set of grass instances to work with across the different LODs.

I can then use spatial dithering to gradually transition between them instead of switching the whole grass population at once.

Here’s a before/after comparison. Both versions are using the **exact same LOD, density, and detail settings** :

[![](https://img.youtube.com/vi/WmKhYFLbZNA/maxresdefault.jpg "I Finally Fixed LOD Pop-In in Three.js Grassworks! | v1.1.0") ](https://www.youtube.com/watch?v=WmKhYFLbZNA)

The difference is pretty noticeable, and I’m much happier with how the LOD transitions look now.

This will be part of **Three.js Grassworks v1.1.0** , which is coming very soon.

[Get Three.js Grassworks](https://grassworks.techredux.co/)

---

<div class="post-metadata">

**Author:** ![Muhammad\_Bilal](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@Muhammad\_Bilal](https://discourse.threejs.org/u/Muhammad_Bilal)\
**Post date:** [October 2, 2026, 4:53pm UTC](https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175/5 "2026-10-02T16:53:02Z")

</div>

v1.1.0 is finally out.

This update brings a few improvements I’ve been working on for a while:

- Smoother LOD transitions
- Improved Billboard Grass
- Better grass interaction and influence recovery
- A new AI skill for working with the Grassworks API and workflows

The LOD changes are probably the biggest one. I reworked how the LOD geometry is generated and added spatial dithering to make transitions much smoother.

Grassworks is still built around Three.js + WebGPU/TSL and is meant for large, dense grass environments.

I’m also running a **50% discount for a limited time** with code `GRASS50`.

[![](https://img.youtube.com/vi/3Q9x-51x_OE/maxresdefault.jpg "Three.js Grassworks v1.1.0 | Procedural Grass for Three.js + WebGPU | 50% OFF") ](https://www.youtube.com/watch?v=3Q9x-51x_OE)

[https://grassworks.techredux.co/](https://grassworks.techredux.co/)

The full v1.1.0 changelog is available on the site as well.

Would love to hear what you think, especially from people using WebGPU in real projects.

---

<div class="post-metadata">

**Author:** ![Muhammad\_Bilal](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@Muhammad\_Bilal](https://discourse.threejs.org/u/Muhammad_Bilal)\
**Post date:** [October 4, 2026, 7:58am UTC](https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175/6 "2026-10-04T07:58:57Z")

</div>

One of the things I worked on in the latest version was making grass interaction feel really smooth.

The system uses an influence map to store where the grass is being affected. When something interacts with the grass, the influence is written into the map instead of changing every blade directly.

The interesting part is that the influence map moves with the camera. So instead of calculating interaction across the whole grass field, it only happens in the area around the camera.

The size of this area is customizable, and so is the resolution of the influence map. A lower resolution is cheaper and gives less detailed interaction, while a higher resolution gives more accurate interaction.

The influence also slowly fades away over time, so the grass smoothly returns to its normal position instead of snapping back.

Getting all of this to feel smooth while keeping it fast enough for large grass areas took quite a bit of work.

This is now part of v1.1.0 of Three.js Grassworks.

I made a short video showing it in action:

[![](https://img.youtube.com/vi/OVoh0fQCozU/maxresdefault.jpg "I spent a lot of time making grass interaction feel this smooth") ](https://www.youtube.com/watch?v=OVoh0fQCozU)

And if you’re interested in the system itself, it’s available here:

> **[Three.js Grassworks](https://grassworks.techredux.co/)**
>
> A high-performance procedural grass system for Three.js with GPU-driven deformation, dynamic wind, terrain interaction, and real-time rendering.

---

<div class="post-metadata">

**Author:** ![Muhammad\_Bilal](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@Muhammad\_Bilal](https://discourse.threejs.org/u/Muhammad_Bilal)\
**Post date:** [October 9, 2026, 1:28pm UTC](https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175/7 "2026-10-09T13:28:29Z")

</div>

I’ve been sharing updates about Three.js Grassworks here, but I realized I haven’t really documented the engineering journey behind it.

I’ve started a series breaking down how I built the system, from my original WebGL grass experiment to WebGPU, scaling the renderer, LODs, and getting grass to follow real terrain.

The first 5 parts are already out, and there’s a lot more to cover.

I’ll be publishing new parts regularly until the whole journey is documented, including the billboard grass system and other features.

If you’re interested in how it all started, begin here:

[Three.js Grass: From a Single Blade to a Million-Blade Field](https://techredux.co/insights/threejs-grass-from-single-blade-to-million-blade-field/?utm_source=threejs_forum&utm_medium=community&utm_campaign=threejs_grass_series&utm_content=part1)

---

<div class="post-metadata">

**Author:** ![Muhammad\_Bilal](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@Muhammad\_Bilal](https://discourse.threejs.org/u/Muhammad_Bilal)\
**Post date:** [October 14, 2026, 10:39am UTC](https://discourse.threejs.org/t/high-performance-grass-rendering-in-three-js-webgpu/94175/8 "2026-10-14T10:39:20Z")

</div>

I’ve been working on another feature for Three.js Grassworks: **Color Maps**.

Right now, grass has random color variation, but that variation is spread across the entire environment. You can’t control which colors appear in specific areas, which makes it difficult to get the exact look you’re going for.

With Color Maps, the idea is to let artists create their own maps and use them to control the colors of grass in different areas of the terrain.

This gives much more control over the final look. Different parts of the field can have completely different colors instead of relying on random variation everywhere.

Here’s a quick comparison showing the grass with and without a color map.

[![](https://img.youtube.com/vi/KOwpj7d-R_M/maxresdefault.jpg "Adding Color Maps to Procedural Grass in Three.js | Grassworks Update") ](https://www.youtube.com/watch?v=KOwpj7d-R_M)

I’m still working on it, but I’m hoping to include it in a future version of [Three.js Grassworks](https://grassworks.techredux.co/).
