Landscape material solutions

I want to create a large map with a city in it. When i look at other games i see many different types of road painted on the landscape.
I end up with wanting at least 9 materials for my landscapematerial, which i think is way too much! Especially with many functions within the material itself. I have also looked at how studios solve this problem with different methods, like creating combined material LODS and other very fancy solutions.

Whats a good way to solve this with out programmnig? Or if anyone has some general guidelines for world creating with cities and villages in unreal.

I dont know about guidelines, but for your avarage map 9 materials is nothing.
Even in a forest map you very easily exceed that.

Map wise, the more layers you have, the smaller the component size you want to use - technically you can’t have more then 18? samples per tile.
Usually, that’s diffuse+normal+displacement per layer, plus at least 3 macro textures, so you end up using the samples up in around 3 to 4 layers painted on the single tile.
Making tiles smaller sort of mitigates this problem.
The shared wrap textures do fix it for the rest of the cases as well, but might pose compatibility issues.

Either way, in a city or even in a forest example you set up roadways via splines.
Splines can have a material assigned to it, generally dirt, as well as a mesh.
A well made mesh can add extra layers and colors without having to touch layers on a landscape.

You can overwrite materials assigned to the mesh based on the spline instance, so you can technically create material instances of the asphalt, tweak them, and randomly set them on spline segments to create variations, just like real roads. Patches of bad/new asphalt sort of thing.

Generally speaking, the lower the cost of rendering the landscape material (less calculations) the better it goes. More fps, less load. But you should not be afraid of creating complex shaders. Just have a look at the kite demo…

Also, wanted to add.
90% of landscape variety comes from multiple proc. Grass layers. Or procedural rocks/pebbles.
Merging the colors of a base grass mesh to the color of the grass landscape layer really helps sell the overall grassy areas.
You just have to completely desaturated the textures and multiply the same base color into the 2 materials to achieve an approximately correct look, where you can’t really tell where your grass ends and where the texture takes over.

Thank you so much, this was just what i was looking for!

I wanted to share some of my latest hacks to improve performance on landscape materials.

I did away with any and all layer blends and replaced them by manually controlling the layer samples.

The setup is a bit harsh, but I ended up gaining upwards of 30fps.

Playing with the layers is a bit complicated, but as a general rule of thumb you start with a “nothing” and invert it so it’s full. Then mix it with a grass layer (add). this is usually the base, from here on, you subtract nothing layer again as the last step of every new layer you add, and you play with subtracting chains to obtain the masks, the material blends, and, most importantly, the procedural grass.

This also allows to arbitrarily paint grass types without having to paint textures.
Which means you could overlay different custom types of grass, or make them exclusive however you see fit…

[USER=“3140864”]MostHost LA[/USER] - Looking to improve landscape performance myself. Do you happen to have a picture of the basic setup you are describing? Trying to visualize but I don’t think I’m getting-it to the point where I’d be wiring such a thing up correctly. I get the concept I think, an empty do-not-use layer, 1-minus it and then instead of adding, you can diff/subtract?

So, the screenshot is useless. but here you go.

Basically, the long/short of it is:
Custom Auto Material -> grass channel out of it, added to the “grass” layer.

at the end of the daisy chain you subtract the “no procedurlas” layer

  • and this gets feed into the “Grass Sample”

The node just before is instead used as an alpha mask to paint the landscape with the appropriate layer blend.

One more update for performance though. Instead of starting off merging the Grass (or whatever layer) to an Auto Landscape layer, merge to a base color 0,0,0 material.
Use the same parameters as the Auto Material to derive the starting point of each layer that gets painted on top.
I gained another 5 FPS…

So, I think this might be my white-whale… I’m just not visualizing it - lol :stuck_out_tongue:

Here’s my very basic setup: For TheMost... - Album on Imgur

I have an auto-material that is a world-aligned material for vertical walls/rocks, etc and a separate network for a world-space XY grass texture. They get blended along a mask (VertexNormalWS dot-product against WS-up normal, 0,0,1) by the blend-material attributes node, which feeds into the auto-layer in the landscape blend node… Weight-blended between auto and a deco layer (paintable details/rocks) and a height-paintable dirt/path layer. All works, looks great. Tanks my FPS a bit tho - lol

I DID try using a heightblend between all layers using the slopemask-alpha between the stone/grass as the ‘height’ and that did net the same visual results but it didn’t seem to net me any instruction reduction or apparent reduced rendering-cost.

I’m sorry for being thick, I think this is just one of those things we hit where we ‘just don’t get it right away’, for me…

Do I start with an empty layer, just blank? Or above when you stated a base 0,0,0 material, do you mean a material that is literally a 0,0,0 vector fed into basecolor?

For my auto-layer, do I break out those two networks into distinct landscape layers? How…?

Up front, if you care to reply, anything you clue me in on would be appreciated… I don’t wanna ask for screenshots b/c I know some things you might not want to share/reveal, and that’s ok, just not really getting where to start, do 1-2 iterations to get it, at that point I could run w/it.

I would suggest starting a whole new material and assigning the instance to the landscape.
Then, create the “layer” nodes without the node you call “magic”.(Type in landscape, it should give you a one pin entry that you can rename to match the layer name).

At first, since your layers on the landscape are already painted, you can try just using the Layer as the alpha mask of a Lerp and plug the lerp directly in the base color output.

This should effectively color the landscape in black and white depending on the weight paint of the layer you picked.

You can say daisy chain the lerps (out pin goes to A, color pin goes to B) to get the rest of the layers to paint on screen.
This gives you an idea of how to play with the masks and what the layers do.

Now that you know, you simply replace the lerp with a layer blend and blend materials instead of a single color, change the output to a material node and plug the last blend in.

I’m absolutely unsure why, doing this cost less then the layer blend node. I have red several Epic employees here in the forums stating it should never be so since the 2 processes essentially do the same exact thing.
However, this was the same for me in 4.22 as it is in 4.23, I dont believe it to be a bug, I just believe that the math to add/remove layers in the blend layers node is what takes more time.

I need to go and see what the code for the node actually does, but technically it should subtract the layers from one another before blending.

With my way, this isn’t being done unless you do it explicitly for every single layer. The result being that the material renders out faster (but ends up Maybe costing more if you layer 10 layers together instead of just a few, within the same tile).

Hope that makes sense. I’ll be reviewing the shader code later on as I’m interested in understanding exactly what or why this is happening.

My alternate solution is to limit the landscape mat to just 1 output of layer blends. I used to have a few sets to deal with tessellation and normals, I’m willing to bet that was the original extra overhead I was fighting against.

Hello and thanks. I’ll try that. I get what you mean by daisy-chaining LERPs, do it all the time; my favorite lil’ operator :smiley: I always look for a way to make an entire material out of LERPs…

I think(?) I already do what you mean but for aggregating layer-weights that I use to drive how wet each part is, etc. If I follow your logic, something like the pic below but for the actual material networks and not just my wetness-attribute?

For my part, I have displacement/tessellation, but they are the very last things I put into the network. Curious to see if they would have a different impact in the new setup…
Well, ****… :smiley:

So I am going to explore this; I think I can consolidate a few ops for a greater gain, but… In going from the above layer-blend I posted to just the below I managed to gain ~7-10 FPS.

ref the new (quick) setup:

I went from this (original)


to this:


It’s hard to see on the graph but it’s a measurable tick to the left. At least I can get an accurate count on my super-expensive setup in the editor…

Thanks for the tip, this does really help.