Why handpainting terrain does not support slopes?

Hey everyone,

I’m spent quite some time with Unreal (unprofessionally) and I’m coming back from the times of CryEngine. I remember quite well that the editor supported handpainting by specifying altitude (height) and slope degrees in the range from 0 to 90.

image

I’ve been wondering why is this missing in Unreal? By no means I’m complaining about that. I’m just wondering why is this not a common feature in most engines (even outside of Unreal - Unity, Godot, etc)

I see that the trend is to try and make “auto material” with the option of hand painting on top of that. Which is fine, but I personally have a huge problem with this. The main problem being that we get a very complicated shader, and not enough “Clear” control of the painting. What I mean is, when using auto material, you generally have 2 parameters for the World Aligned Blend node - Blend Bias and Sharpness - which doesn’t make sense at all, you have to play around with those values until you get the result that you want.

Now, I think it would make a lot more sense, if you could “specify” a height and slope for your layer. I’ve tried many many different solutions on YouTube and google, on how to setup that, but none of those resulted in the perfect solution that I’m looking for.

The interesting thing is, that I can definitely see it available in the editor, but not for painting landscape , but for painting foliage.

Now, I’m trying to figure out, why we don’t have that for Painting landscape, and is it possible to “enable” this somehow?

Or event better, what professional developers do about this problem?

You can use SlopeMask for slope blending, and the Z component of Absolute World Position to mask for height and get the same results.

Dont listen to that guy. He’s more than clueless.

The reason no one really supports it is that its a completely useless overhead cost when you do it at runtime.

All you have to do is access any GIS program and print out a slope map to use as the layer paint.
Then you get 0 runtime processing cost and the same exact result.

Cryengine is simply better made than unreal (and most other engines). They limit your paint tool and get you to produce an artist driven final material.

Unreal landscape on the other hand is like a thing made by sh*t flinging monkeys after feeding them a banana… no really.
Its stuck at least 15 years in the past, and has a ton of core flaws. I cluding the way you paint landacape layers.
More layers = less performance.

Instead of fixing anything, they tried to claim tha Nanite would be their saviour.
On paper it does do enerything that you would expect, from stripping useless vertex to unifying the textures. In practice, its made by slightly different monkeys and as far as I have seen it does not work.

So, in short, if you want to woek in unreal and make videogames, dont use the landscape. Start setting up things to make meshes yourself.
Texture and prepare them in their entierty in a 3d editor, and then import them into the engone for usage.
The only thing you miss out on is the landscape grass, which really isnt that big of a loss.

I suggest cutting up the landscape in blocks of 250m^2. Then HLODing them togeter in aggregates of up to 1km^2, and doubled up to 4km^2.

In practice however the HLOD system is also a dud made by monkeys. So you kind of are better off breaking out a c++ class and creating your own merge manager that handles this too.

Generally, simply setting the mesh to not render will avoid the drawcall and get you where you need to be load wise. So the manager doesn’t need to be overly elaborate necessarily.
You can duplicate meshes, actor merge them, set them as hidden, and then have the manager just toggle on/off to reduce loads.

When making meshes, the Engine Equivalente is 1 vert per meter.
Thats usually a huge waste of tris when you optimize your mesh, so if you want better performance you can start out with that same density, and reduce it drastically by using analytical functions.

That should more or less sort out all you need to get a project that’s somewhat performant enough to release before 2026…

So, what you are saying is, build your own landscape system? Is that perhaps the reason why it is so hard to access the terrain data even with C++?

While you make a lot of points here, the conclusion I can make is only that I have to build the tools that I need myself in order for them to work as I want them to?

Given that literally nothing MostHost said came anywhere near addressing your actual question, which was about slope based masking (except, I guess, ‘bake out a slope map in an external program,’ which isn’t super useful advice), can I ask what issues you’ve had with whatever youtuber solutions you’ve tried are?

I knocked together a pretty basic auto slope mask that takes a Degrees input in a few minutes:


It’s slightly more expensive than a SlopeMask, with 209 (208 if I drop the Rad2Deg conversion) instructions vs a SlopeMask’s 207, but if two shader instructions is the difference between a playable game and not, then you’ve got much bigger problems.

There’s also no transition softening with this setup, but again, knocked it together in a few minutes. There are a few possible options to blur it, but they come with different expenses.

Hey thanks for another response, but I also tried the solution you are proposing. But using IF node creates a very hard edge for the slope mask.

And I never found out a way how to introduce more “breakage” on the transition. Let’s say for example you want to mask the cliffs. Well, this works up until you have a very hard transition between the cliff and the “other layer” it transitions into.

And the problem is that I can’t find any solution to this, I’ve tried contrast node but it also doesn’t give me full control over what I wanted.

If there was a way to "introduce noise on the “edge of transition” then that would be much better.

Have you found any solution to this? Btw while talking to you about this, I might got an idea how to fight this. What if after I got the mask, I multiplied it by some noise texture, where the white multiplied by white of the noise, would most likely give me the result I want?

Yeah, multiplying a noise texture is one of the easier ways to blur the transition. Or instead of using the mask directly you could pipe it into a Runtime Virtual Texture and then do something like a Sobel blur when you sample it (you might even be able to get away with just sampling a lower mip of the RVT, since RVT compression will tend to add some blur anyway).

[edit] You could also just subtract the SlopeDegrees parameter from the RadiansToDegrees and throw a Saturate after it to get a fuzzier border than the If gives. Also use ArccosineFast instead of Arccosine. And if you’re really fussed about the shader cost, you can put in a VertexInterpolator, but that’ll only work on Nanite Landscape, not normal landscape.

If you want to make a videogame, yes.

If you need to make cinematics or whatver, no. You can use the engine stuff since Performance doesn’t matter.

The code you were given above is trash.
You dont do arcosine or any expensive operation on each vertex
Just do dot. And manually tweak a map range clamped value.
If you really have to use a bad runtime solution…

Further, IF used that way doesn’t support branching.
So its essentially pointless (and creates a hard edge line).
Probably just output of maprangeclamped into a lerp alpha in which A and B are 0 to 1.
Preview that on a landscape to determine if the value ranges appear Ok enough or if they need further refinment.
If you still get a hard edge regardless. That’s because of the map range clamped values.
Alterning those would make the transition into the slope value you want harder or softer.

As a general rule of thumb, to lessen the hard lines that the landscape gives you due to the fact that 1 pixel is a meter, you use another texture to blend the layers - somethimes called a height lerp when not done manually.

Again, put your heightmap into a GIS program.
Get a PNG of the slope and change it up artistically however you think you need to
(The output is a regular png, does not need to be 16bit).

Use that peoduct as the Paint Layer for the material that you want the slope to be covered with.

And then you can mess with the material’s layers however you think you need to.
Once its pre-defined you dont really have to worry about anything.

And PS:
No, if you want to set a degree value you still dont do the calculations on every vertex and complain about performance, unless you are mentally ill…
Make a BP that does the value conversion once and feeds it to the material as radians by altering a MPC (material parameter collection), if you want to be “sophisticated” about a pointless system.
Again, its completely pointless. Landscapes cannot be changed at runtime. Having runtime calculations is silly.