How to Render MILLIONS of Blades of Grass Efficiently in Godot (godot 3.X)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] i don't know about you but when i saw 2018 game of the year the legend of zelda breath of the wild grass beautifully rendered on a device that fits into my hands the first thought that came to mind was how can that be done in godot in this video i'm going to go over everything you need to know about rendering dense and beautiful foliage in godot the first section goes over some of the techniques that other game engines and godot uses to render large amounts of grass and the second part goes over how to use some of the pre-made tools and plug-ins which you can use for grass and godot i even have my friend nakoto speak about his own techniques and plug-in for rendering grass so stick around for that also this isn't a shader tutorial but i will link the shaders and tools i use in the description so modern computers are great they can do literally billions of operations per second but they do have their limitations for each normal mesh on the screen the cpu must calculate the animations and physics of that object and then pass that through to the gpu so you can render it to your screen the process of passing that data from the cpu to the gpu is called a draw call and they are quite expensive luckily there is a workaround gpu instancing is when the entire process of instancing animating and rendering the grass is done on the gpu with no communication to the cpu this is super useful for rendering large amounts of the same objects such as grass as it means there's no bottleneck in the communication between the cpu and gpu usually just being one draw call for the entire lot this isn't a perfect solution however since the cpu isn't involved with the instancing of the objects it basically doesn't exist at least according to the cpu meaning things like adding physics collisions or other interactions and logic is impossible mostly i highly recommend the grass series by ace roller who goes over the details of gpu instancing frustum culling draw distance and other techniques to render dense fields of grass ace roller does this in unity but the concepts are mostly the same and the videos are very entertaining anyway so how can we reduce our draw calls godot uses something called a multi-mesh instance a multi-mesh instance is a single object that can render up to millions of a single mesh or objects in one go and all in one draw call multi-mesh instances have many of the benefits of gpu instancing since it all counts as one object it only takes one draw call making it very efficient unfortunately it has a few extra drawbacks one of these is that while frosting culling which is stopping the rendering of objects outside the field of view of your camera does work it only works when all of the objects in the instance are out of view meaning you could have only one blade of grass in view but the entire patch of one million blades will still be rendered a workaround for this would be to use multiple smaller multi-mesh instances to balance draw calls with the number of polygons drawn similar to a chunking system secondly the multi-mesh instances also require you to place each mesh using your cpu so the position buffer which is where the transforms for each blade of grass is stored is technically not on the gpu at all however multi-mesh instances can also execute logic through shaders which is handy for faking interaction for example you can use your player's coordinates to implement interactive graphs in the vertex shader okay so that's how godot renders millions of meshes at once but i hear you asking leon that's not helpful at all how do i create grass like in the 2018 game of the year legend of zelda breath of the wild using the goddamn game engine luckily there are a few tools and handy plugins to help make beautiful patches of grass the first tool i'm going to show you is scatter scatter is a plug-in made by hungry proton linked in the description and is the go-to for beautiful grass in small to medium scenes scatter uses multi-mesh instances and can create very dense and custom patches of grass using its 3d curve editor and an array of modifiers such as removing from a path projecting on the floor or randomizing transform modifiers to install scatter download the github repository and extract it to your add-on folder [Music] make sure to change the file name to scatter and activate the plugin in your project settings you can then go ahead and add the scatter node to the scene you will need to add a scatter item node as a child and then assign your grass in the item path parameter in my case it's this simple five vertex grasp blade model as well as this you will need to add some modifiers which in my case i'm using a distributing side grid to distribute the grass evenly a randomized scale modifier to give some height variation and a project on floor modifier to snap the grass to my mesh finally you can draw the area you want your grass scatter can get slow to edit with lots of 3d curve points and when you've got lots of grass so i recommend turning your instance count down while you edit a short side note on shaders is the built-in shaders and grass models in scatter are really nice with some nice wavy movements i'm using this grass shader which i've also linked in the description to add some player interaction and deformation add this script to your grass which is again linked in the description then assign your player in the script and it will deform the grass around the player's coordinates for any mesh using this shader material which includes all of the grass instanced by the scatter plugin notice how i only need to apply the material to one grass blade and it updates all of the grass in my scene and voila a beautiful dense patch of grass there is a slight problem however if we make our patch super big it becomes much less efficient since frosting culling will only work when all blades of grass are out of view from the camera a simple solution to this would be to make multiple smaller patches or chunks of grass i find a nice balance is to make them around 10 to 30 meters squared per chunk as well as this we don't need to be rendering any grass super far away from the player so we can add another basic chunking system to keep this under control to do this i have added a spatial node and made each chunk of grass a child of that node i then added the following script this script will make an array of our grass patches and cull them if they're further than our maximum render distance remember this can't cull individual blades of grass it can only cull entire chunks so there isn't a smooth edge where the grass ends rather it's quite a blocky edge also this chunking system can be quite expensive when you have lots of patches of grass so i recommend setting the for loop to a timer as it doesn't need to run every single frame so that's the scatter tool it's brilliant for small scenes and i also explored a few options for medium sized scenes however due to its slow performance especially around editing the 3d curves and the chunking system i wouldn't recommend using this system for really large scenes there are just many more systems that would need to be in place to keep performance under control which godot just isn't built for as well as this my good friend nakoto has been working on their own grass system fork dough which i will allow them to explain how about a particle system for your grass particles are really good at drawing the same mesh thousands of times over and over again in video the instancing of particles is handled by a special type of shader called a particle shader which runs on the gpu itself this is actually one of the closest ways you can get the true gpu instancing in guiteau i mean just take a look at the number of grass blades rendered in this scene we can also use chunking similar to how we did for the multi-mesh instance and use less detailed meshes on the chunks that are further away from the camera however there is a humongous problem with this method the particle shader cannot change the number of instances drawn so if there is a region where the grass shouldn't be drawn the only thing you can do is move the grass to somewhere the camera can't see it since the gpu has to keep rendering the particles for the rest of the game we cannot make use of the active variable in the particle shader either which means that unless the entire particle emitter gets frustum called the gpu will render every single particle regardless and there you have it i hope you enjoyed my rundown of how grass systems work in godot and how you too can make dense patches of grass in a somewhat performant manner we are all finally one step closer to breath of the wild in godot if you enjoyed this video feel free to subscribe and like it really means a lot as i just can't function without constant approval from strangers
Info
Channel: Leon Stansfield
Views: 49,499
Rating: undefined out of 5
Keywords: easy grass in blender 2.91, blender grass, blender realistic grass, blender, grass shader, blender software, blender tutorials for beginners, blender animations, blender for beginners, level of deatail, blender 2.9, blender 2.83, blender 2.91, blender 2.92, blender guru, grass, godot, indiedev, compute shader, onlineservice, computer science, gregory toussaint, shader, Godot shader, Godot grass shader, Godot, BOTW Godot, Breath of the wild grass, breath of the wild
Id: z_Q0sA3wE10
Channel Id: undefined
Length: 10min 6sec (606 seconds)
Published: Wed Jun 22 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.