The Great Grass Dilemma

This thread is a very interesting read! Thanks for sharing and good luck with your project.

So if I want to make cool grass with unity and render decent framerates im fucked? or…?

There’s Nature Renderer, which is pretty cool.

Wow! This is a really interesting topic. I’m glad someone bumped it up.

I agree.

There’s the Critias Foliage System too, which is free.

Never heard of that, but it sounds interesting and may be worth a try.

You can follow the workflow I’ve discovered and explained in my above posts. In summary: I found that the “tree” method for grass was too slow because there was no mesh combining, and each grass mesh required LOD calculations. Billboard grass looked too fake in its rendering, and did not have the correct densitites required even when maxing out the detail slider in the terrain settings.

So my solution was to use the “detail mesh” system which is an option for terrains. That way I could make my own grass meshes, and each mesh could have more blade “billboards” within them to show much higher densities than previous. Detail meshes are also combined into patches, which massively improves performance, and you can customize the draw distance within the terrain options. The downside is you cannot modify the shader used and are stuck with what they give you. There are also little inconsistencies with how the painting tool works (if you make a change to a detail and paint over to another terrain it makes a duplicate of that detail even if it already existed on the other terrain… it becomes a mess really quickly because now they are “unlinked” and cannot be painted smoothly from one to the other). But the grass shader does support wind, you can get it working by painting the vertex colors and modifying them with a script using the methods I described above.

There are other hiccups, such as the locked target strength slider in 2019.3. I managed to fix it by building my own painting tool which I posted above. Or the fact that if you put down rocks under the same system, the rock texture can sometimes leak into your grass due to the textures being atlased together internally. The solution I found was to make the rocks have an alpha channel in PS and set it to alpha 0, in order to stop the texture from appearing on random grass meshes elsewhere. Asides from this, the detail mesh system is well equipped to handle lots of vegetation that looks pretty good provided you follow the steps to make everything play nice. You won’t have control over rendering though, so if you’re unhappy with the features Unity provides you may want to look into a custom system. Be mindful though, that much of how your grass looks depends on the art assets and design you incorporate–getting a new system to render your grass may improve the look but it won’t fundamentally change the quality of your vegetation assets. That’s a big tip that I’ve learned from all this–it’s crucial to tweak your ground textures and grass objects/textures until they match, and you can use extra tricks like painting the bottom with black for shadowing, or making extra vegetation inbetween for more variety, etc. The way you craft your grass meshes/textures is just as important, if not more, than the system you use to paint and render them, at least when it comes to looks, ignoring performance.

Looks neat! I’ll have to look into it for a future project, if it combines/instances meshes and renders nicely while also adhering to the terrain height dynamically, it would be great to have a system that can fade multiple grass types differently to hide the transition better. That’s something that is definitely lacking from Unity’s detail mesh system.

Also just to show my progress, I’ve been finalizing the look of my game using everything I’ve learned from this thread. Here’s a bit of how I got my terrain grass to look:

https://i.imgur.com/NrFmcox.png

https://i.imgur.com/7tEJUnA.png

I’m pretty happy with this result. I’ll definitely explore more for future projects but I’ve got a handle on my workflow for now. Thanks to everyone who has helped out and given suggestions, I’ve definitely put that knowledge to good use!

2 Likes

Hi, you can look at this grass gpu rendering :

Gpu instancing
Frustum Culling
Grass have custom material : One Substance Material for Diffuse and normal, one perlin map for Wind Animation rendering, one color map for terrain blending, and one height map for noise variation and blending between two terrain texture. The grass is 6 CrossQuad for LOD0, 4 CrossQuad for LOD1 simple Cross for LOD2 and Billboard. Run on one Unity3D Terrain 500*500. Grass Deformation use simple per vertex modification

1 Like

Here is our solution for dense grass rendering in Unity:

Showcase

Tutorial

1 Like

I’ve just encountered The Great Grass Dilemma myself. I am making a city-builder game, so I have the additional issue of needing to know where vegetation is, and to cull it if a structure is placed by the player that overlaps the structure, and then to check if a structure has been removed, and “re-grow” the vegetation there, as to not leave large dead patches of land, if the player removed structures. I got either 4kmx4km or 8kmx8km of land to cover, so my grass isn’t gonna be as dense, but needs to be “serviceable” for a city-builder.

I’m still in the early phases of concepting/brainstorming ideas. I have one solution I came up with that may work out, and I’ll be sure to post the outcome here, good or bad, and share it with this community effort in finding solutions to The Great Grass Dilemma.

Also, thank you for making this post/thread, I know it’s helped me out a lot, and I’m sure it’s helped a lot of others.

2 Likes

I am encountering the bug mentioned above with the weird brush strengths. Can we get it fixed?

Using Unity v2020.2.1f1

It’s not a bug, I got a response to my bug report and it turns out the brush strength is like that on purpose. See here:

So they have intentionally clamped the slider to specific values and supposedly also upped the base strength when it comes to detail painting. There’s a few reasons why it worked better the old way, here’s what I wrote in response as thoughts on the matter:

But I don’t claim to know anything behind the curtain as to what the Unity devs may want here, probably just a way to streamline the tool and make it more accessible somehow? Regardless, it’s not up to us sadly and that’s the change they went for so it is what it is for now.

There is a workaround though, I posted it earlier up in the thread. To solve this issue, I was able to recreate the entire detail paint tool using the Experimental Terrain API, and with it an unclamped target strength value to paint at lower densities. I posted the code publicly on this thread which also documents the detail paint issue. Just put the script into an Editor folder and you should be able to use the tool as listed underneath the “paint” options for terrain. Be aware of the drawbacks though. Hope that helps!

Reducing detail resolution on the terrain settings also seems to help when the minimum brush target is still too strong:

That’s true, however it would limit the maximum amount of details to be placed down and you’d end up with sparse grass placement even if you were trying to fill it with multiple variants. If you wanted a high number of objects while still being able to paint at precise lower densities, you’d have to utilize opacity or use the script I linked above.

1 Like

@SomeGuy22 Unfortunately for me opacity is a no go as I like to paint details by holding the mouse down and moving the cursor around, which even at the minimum opacity quickly reaches the maximum.

A bit out in the future.
But based on my experience you may be looking at the wrong aspect your grass dilemma. Your grass mesh doesn’t look bad at all in my opinion, but you may rather look into grass shadows and other graphical adjustments. When I changed to HDRP I realized how big of a deal something like Ambient occlusion and also as one of thing you pointed out, the background(Surface texture in this case) also changes how your grass fit to the ground and will look less harsh on the edges. These adjustment might be what you’re looking for, but can’t make any promises :slight_smile:

I also used a few techniques while working with my grass which seems to help with density issues like overlapping multiple grass planes and texturing the fade the bottom part to a darker texture
while not as realistic rotating the grass slightly to cover more of the surface also seem to give a more dense feeling

Hope you find any of this helpful if you haven’t already found your solution :smile:

Thank you for the suggestions! But actually as you said I already incorporated all of those ideas about halfway through my grass journey. Ambient occlusion was always on for all of those screenshots though I’m not sure if Unity’s detail mesh grass shader is actually compatible with that post processing so I’m not sure what difference it made. But regardless, for my project I found that I actually didn’t want to shadow the bottom too much as it looked more pleasing to have it match the terrain closely. I guess it really depends on the style and level of realism but to me it seemed to matter that the grass matches the terrain in hue/saturation/brightness more than anything else.

Adjusting the grass patch to cover more ground with “flattened” planes is a great way to cover more surface as you mentioned! I’ve seen it done in several tutorials in my research and I think it’s a big part of making the grass varied. Using Unity’s default grass option unfortunately leaves you with individual squares which is why I discovered that I had more control with patches using the detail system.

If you want to see the final result of my efforts you can check out Iron Reckoning on Steam! The vegetation was extremely important for the look of my levels and I show it off a bit in the trailers and screenshots.


3 Likes

GPU instancer works perfect for us.

I’m not sure if you’ve considered it or not, but you could break your terrain up in to multiple ‘tiles’, which could individually have the same ‘detail resolution’ you are using now, but it would be much denser since your tiles are smaller.

My terrain tiles are only 100x100, and i dont need much resolution at all to get very high amounts of grass:

My batches are still pretty high with this amount of grass because I havent found a way to share the same material with the grass and the rest of my stuff yet. I dont even really want this much, and just turned the resolution up to 512 for this screenshot. I could go even higher…

Here’s 2048… but i can’t even tell a difference

And this is the material problem manifested:

Here I have 2 different grass types rendering on screen (dark in foreground, lighter in bg), so the batches are even worse because its an additional material.

If I could just get a shared material with instanced shader properties working between different detail mesh prototypes, I would have no batching problems at all, and could have as many types of grasses/flowers/rocks as I wanted essentially.

I might end up just generating my own meshes at runtime for each detail layer and uv map the textures on to the quads manually.

And there are still ways to render far away terrain, even though you are using tiles for nearby terrain: