Distance Field Data to remove grass

Would it be possible to use distance field data to remove grass?

Currently my foliage intersects a ton of meshes and will poke through things like rocks which looks terrible.
I saw a blueprint that used distance field data to create flow maps for water so I was wondering if it could be used to remove landscape grass.

Has anyone tried something like this? I’m pretty swamped with work at the moment so I havent had a chance to figure out how to approach this if its even possible.

Sounds like a good idea. There are some limitations what stuff work for with grass output but it should be quite easy to test this. You probably want to offset sample position z to bit upward to avoid intersections with landscape.

Edit: Another way to mask grass would be new ambient occlusion mask from lightmass.

After some testing I have confirmed that I have absolutely no idea what Im doing. I figured I would take the layer sample and subtract from that the distance field data but the grass either disappears altogether or just doesn’t do anything.

Show your material then? It should be fairly easy.

Pseudo code:
grassWeigth = clamp(GetDistanceToClosestSurface() * 0.02 - 0.5 ,0.0, 1.0);

This would spawn grass to places where there are none surface in 0.5m radius with soft gradient to 1m.

This is what I had.

I plugged the result into emissive color and it shows up properly as far as I can tell. The grass should spawn in the white areas but It doesnt.

most likely, the distance to nearest surface node cannot be evaluated properly by the grassmap rendering system. The issue is probably that the distance to nearest surface uses the global distance fields which use cascading resolution away from the camera. during grassmap rendering the camera is probably either undefined or defined to be way high in the air or something like that, which causes invalid results from the clipmap lookups. It may be possible to make this work by always using the lowest resolution clipmap for grassmap baking, but the only engineer capable of working on this (DanielW) is out on vacation right now. I will bring this up when I see him next.

1 Like

Thanks for explaining! Any changes to the landscape grass output that give artists more control are welcomed.

I agree something like this would be really useful. I was going to try something similar for baking flowmap data.

One way to test if any distance field data is read by the grass system would be to add a movable static mesh to the world. Those still use their individual high resolution distance fields and do not get composited into the global fields. I forgot about that in my reply yesterday. It may be a different issue preventing it from working if that doesn’t work.

I made some of the rocks moveable and it didn’t make a difference. I tried everything I can think of and nothing has worked. There are several ways of spawning grass (landscape grass output, foliage painting, and the procedural foliage spawner) is there any way to leverage the functionality of those other tools to refine the results of the landscape grass? Can any of the distance field information be baked down to a texture?

Any information how grass baking is actually working would help. Is it done on gpu?

For every grass type in the material editor, the engine renders a density map into a 2D texture that is then used on CPU to spawn individual instances. So the part where the distance field would have to be used is the rendering of “grass” density map into a texture, which is the step that Ryan thinks wouldn’t work correctly at the moment.

Did anything ever come of this? Did DanielW have anything to say about it?

No luck with this in 4.26 unfortunately. The masking looks correct but no grass appears there.

Works just fine.
Simply subtract the desatured distance field gradient from the grass layer(s) of the landscape.

Alternatively if you have a system that creates trails and what not you use a render target and get something like this.

That uses what is essentially the same as a distance field gradient to properly displace the grass. (On the grass itself).

Also, on the grass itself, you can set it’s opacity to 0 on specific points. Like those covered by other items, without having to rely on the landscape.

And additionally, you can write at runtime to a rendertarget used on the landscape to remove the grass as well.
You use the rendertarget on both the landscape for whatever effect you want like scorching, and you use the same texture on the grass to make it fade away.

These are interesting options, though I was specifically looking for a way to not generate grass via the distance field. Your examples seem more to modify the shape or visibility of the grass after it’s generated. Grass generation must take place before distance fields, because it doesn’t register the data at all.

The rendertarget method might work, but it feels like a waste of a large texture when we already have distance fields enabled.

Thanks :slight_smile:

The first option is what you are looking for to have the actual grassmap initialize without grass in engine.

The other stuff is more runtime based.
Areas can have or not have grass…

Something ARK players have asked for, for however many years the game has been running, for instance.

In cases like that you cannot cook grass maps due to the fact that every game instance can be different, so you have to waste away with textures and other systems/ideas to remove the grass.
(Because octree based filters would be too much to ask for from those who make the engine :roll_eyes:)

1 Like