# Grass, butterflies and trees with instancing

**URL:** <https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646>\
**Category:** Demos and projects\
**Tags:** instances, thininstances, thin-instance\
**Created:** [November 12, 2023, 7:22pm UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646 "2023-11-12T19:22:36Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [November 12, 2023, 7:22pm UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/1 "2023-11-12T19:22:36Z")

</div>

Hello everyone!

After watching the last [video of Simon Dev on grass](https://youtu.be/bp7REZBV4P4), I was inspired to recreate and expand it using BabylonJS. So I had a lot of fun with instances and stuff and it came up nicely I think:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/9/0/90a0614bf9e8fbfdf285d8b2d61a851b728a1b28.jpeg)

You can try it out at [Hello BabylonJS !](https://barthpaleologue.github.io/AssetScattering/) (WASD or ZQSD to move around the character)

The framerate holds at 60fps most of the time (not on the screenshot lol) on my Iris Xe integrated GPU. I think the trees my be to blame on that one I am not sure.

All the source code is available [on github](https://github.com/BarthPaleologue/AssetScattering) and I made a PG for a minimal patch of grass [here](https://playground.babylonjs.com/#VMA5LR#7) that should be easy to reuse if anyone needs.

I went a bit further by implementing some LoD for the thin instances, and also making the player repell the grass and butterflies.

While making the forest, I also made a higher res version of the texture for the babylon tree. You can find it [here](https://github.com/BarthPaleologue/AssetScattering/blob/master/src/assets/Tree.png)

---

<div class="post-metadata">

**Author:** ![musk](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/musk/32/17156_2.png) [@musk](https://forum.babylonjs.com/u/musk)\
**Post date:** [November 13, 2023, 2:42am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/2 "2023-11-13T02:42:15Z")

</div>

Thanks for your work, this is definitely very helpful !

---

<div class="post-metadata">

**Author:** ![carolhmj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/carolhmj/32/25918_2.png) [@carolhmj](https://forum.babylonjs.com/u/carolhmj)\
**Post date:** [November 17, 2023, 12:43pm UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/3 "2023-11-17T12:43:14Z")

</div>

It looks super good!!!

---

<div class="post-metadata">

**Author:** ![mawa](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/mawa/32/12384_2.png) [@mawa](https://forum.babylonjs.com/u/mawa)\
**Post date:** [November 17, 2023, 2:39pm UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/4 "2023-11-17T14:39:56Z")

</div>

Nice. Let me add this to the ‘[Field of grass thread](https://forum.babylonjs.com/t/field-of-grass/29023)’ A post discussing about roads and buildings…oops, no, my bad…it’s about fields of grass…makes more sense, doesn’t it? 😂

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [November 19, 2023, 11:35am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/5 "2023-11-19T11:35:37Z")

</div>

Thank you very much 😂

---

<div class="post-metadata">

**Author:** ![zhangyahan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/zhangyahan/32/31789_2.png) [@zhangyahan](https://forum.babylonjs.com/u/zhangyahan)\
**Post date:** [July 1, 2024, 3:40am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/6 "2024-07-01T03:40:53Z")

</div>

I would like to ask you a question:  
I found that the control of the thin instance lod in the source code is fully variable, rather than changing individually based on the position of the thin instance, just like the effect of the instance lod. Is this the case?

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [July 1, 2024, 6:28am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/7 "2024-07-01T06:28:22Z")

</div>

Cool demo 🙂

Do you use animation ratio for equal timing on different FPSs?  
The grass is waving crazily fast on my machine.

> [@zhangyahan](#):
>
> I found that the control of the thin instance lod

Do we support LODs with thin instances? If so, I’ve must missed something very badly 🙂 LOD is supported with instances and you have to specify the distance from the camera when setting a LOD. Can you rephrase your question please because I don’t clearly understand what are you trying to get an answer for?

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [July 1, 2024, 7:20am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/8 "2024-07-01T07:20:41Z")

</div>

The LoD level is controlled by patch indeed. Thin instances can only have a single geometry model as far as I know so there is no easy way to change individual thin instances model. That’s why I have to change the entire patch.

Thankfully the matrix buffer is reused! A possible improvement would be to avoid sending again the matrices to the GPU but I don’t really know how to do that.

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [July 1, 2024, 7:23am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/9 "2024-07-01T07:23:40Z")

</div>

Thanks 😉

I am using the elapsed seconds from page loading to make the grass wave you see in the shader here:

> <https://github.com/BarthPaleologue/AssetScattering/blob/master/src/shaders/grassVertex.glsl>

I use `engine.getDeltaTime() / 1000` on every render to accumulate the seconds so I don’t really know what is causing the fast waving 🤔

Can you try this PG?

> **[Babylon.js Playground](https://playground.babylonjs.com/#VMA5LR%237)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

---

<div class="post-metadata">

**Author:** ![zhangyahan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/zhangyahan/32/31789_2.png) [@zhangyahan](https://forum.babylonjs.com/u/zhangyahan)\
**Post date:** [July 1, 2024, 7:24am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/10 "2024-07-01T07:24:39Z")

</div>

Yes, amazing demo, but do we support individual thin instances model LODs control? Not updating the entire patch，

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [July 1, 2024, 7:25am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/11 "2024-07-01T07:25:29Z")

</div>

> [@Thin instances with LOD Levels](https://forum.babylonjs.com/t/thin-instances-with-lod-levels/23872/2):
>
> No, a thin instance is really just a matrix that allows to draw a mesh at another location/with another rotation/scaling. To be fast, all the matrices are passed in a single draw call to the GPU and so no LOD is possible.

don’t think so

---

<div class="post-metadata">

**Author:** ![zhangyahan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/zhangyahan/32/31789_2.png) [@zhangyahan](https://forum.babylonjs.com/u/zhangyahan)\
**Post date:** [July 1, 2024, 7:29am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/12 "2024-07-01T07:29:08Z")

</div>

Is there a way to implement support individual thin instances model LODs control?

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [July 1, 2024, 7:35am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/13 "2024-07-01T07:35:07Z")

</div>

Basically thin instances are a base mesh + a matrix buffer for individual instances.

If you want per instance LoD, you must first have multiple base meshes (one for each LOD level).

Then the tricky part comes in: switching a thin instance from one LOD to another means either:

- Somehow you can take advantage of `thinInstanceCount` so that the instance you remove is the last of the buffer so you can increase by one for the new LOD and decrease by one for the old LOD

- Update the matrix buffer and send it back to the GPU (huge performance hit)

I won’t call this problem impossible, but we should probably analyze your use case before undertaking the impossible ^^

So what is your use case?

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [July 1, 2024, 7:48am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/14 "2024-07-01T07:48:38Z")

</div>

> [@CrashMaster](#):
>
> Can you try this PG?

seems to be ok, smooth slow motion…

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [July 1, 2024, 7:51am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/15 "2024-07-01T07:51:48Z")

</div>

Maybe a more accurate comparison would be with this recording:

[![](https://img.youtube.com/vi/0I5Kd784K6A/hqdefault.jpg "Millions of grass blades on the web") ](https://www.youtube.com/watch?v=0I5Kd784K6A)

Maybe crazy fast animation is just how I programmed it haha

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [July 1, 2024, 7:53am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/16 "2024-07-01T07:53:34Z")

</div>

For me it’s running at 120 FPS, so twice the speed.

---

<div class="post-metadata">

**Author:** ![zhangyahan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/zhangyahan/32/31789_2.png) [@zhangyahan](https://forum.babylonjs.com/u/zhangyahan)\
**Post date:** [July 1, 2024, 7:53am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/17 "2024-07-01T07:53:35Z")

</div>

My use case is vegetation, which includes model trees (with a small amount of vertex data) and alpha trees (just a plane). I want to optimize it by displaying model trees when they are close and switching to alpha trees or model trees with fewer vertices when they are far away. Updating the matrix buffer and sending it to the GPU would be quite performance-intensive. Can we use an approach similar to cascading shadows, setting up different levels of models and dynamically hiding and displaying thin instances in different levels based on distance?

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [July 1, 2024, 7:58am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/18 "2024-07-01T07:58:32Z")

</div>

That’s so weird my update loop for the grass material is just:

```ts
let elapsedSeconds = 0;
scene.onBeforeRenderObservable.add(() => {
        elapsedSeconds += scene.getEngine().getDeltaTime() / 1000;

        const playerPosition = player ? player.position : new Vector3(0, 500, 0); // high y to avoid interaction with grass
        const cameraPosition = scene.activeCamera ? scene.activeCamera.position : new Vector3(0, 0, 0);
        grassMaterial.setVector3("playerPosition", playerPosition);
        grassMaterial.setVector3("cameraPosition", cameraPosition);
        grassMaterial.setFloat("time", elapsedSeconds);
    });

```

I will have trouble reproducing the issue since all my screen are 60fps 😕

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [July 1, 2024, 8:00am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/19 "2024-07-01T08:00:44Z")

</div>

Interesting, I see multiple ways:

- Either go to simple instancing for trees if you don’t need thousands of them (regular instances are quite fast already)

- Use a custom shader material for your instances: there you will be able to control everything and you can use the vertex shader to remove unwanted instances (set all positions to 0)

---

<div class="post-metadata">

**Author:** ![zhangyahan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/zhangyahan/32/31789_2.png) [@zhangyahan](https://forum.babylonjs.com/u/zhangyahan)\
**Post date:** [July 1, 2024, 8:12am UTC](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646/20 "2024-07-01T08:12:17Z")

</div>

Unfortunately, there are a lot of trees in my scene. I will refer to the Babylon.js source code and try out the approach with custom shaders.

[Next page](https://forum.babylonjs.com/t/grass-butterflies-and-trees-with-instancing/45646.md?page=2)
