The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates. | Twitter

0 votes

In the 3d game that I am working on I followed a tutorial about how to create grass, but the worlds that I am making are fairly big, and I can't imagine that rendering every single grass blade across a big landmass in a game is good for performance. There is also a limit of how many grass blades that can be rendered with one multimesh so it looks kind of ugly with the grass so spread out. In other games that I have played I have seen grass only being rendered when it is in close proximity to the player. What would be the best way to go about doing this?

Would you have multimeshes around the world and only show them based off of where the player is, or is there a better system to do this?

Would you somehow get a multimesh to populate the surface but only in proximity to the player?

I know this is a big topic but I couldn't find any tutorial or anything about this anywhere. Thank you in advance!

Godot version 3.4.4
in Engine by (40 points)

1 Answer

+2 votes
Best answer

The way I do it is by maintaining a grid of grass chunks around the camera, within a limited area. When a chunk gets too far, I remove it. When the area has empty spots for a chunk, I add them. This can be in a circle or a square. Chunks allow to do a bit of frustrum culling and manage "infinite" presence of grass.

Then each chunk contains a multimesh, and here there are a few options: either generate each instance position using raycasts and procedural formulas with a script, or precalculate one with full density, share it on all multimeshes and rather decimate instances from a vertex shader according to a density map or splatmap (commonly seen with heightmap terrain). If the world is too big to fit in a single heightmap, they could be easily chunked themselves on a larger scale.

Finally, to smooth out the "popping" effect when chunks load/unload, I fade grass using a fragment shader based on distance. The distance is choosen in such a way chunks that get loaded or unload should be almost invisible as all grass inside has faded away.
Properly choosing colors for ground and grass also helps to make it blend in.

Here is how my version looks like with some debug drawing:

by (29,360 points)
selected by

Dang this is exactly what I was thinking Brilliant answer

Thank you so much! I'll definitely be trying this!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.