In this tutorial, you will learn how to create
a realistic landscape material that will automatically paint textures on the landscape, so you can
save time when creating environments! We will go from a basic setup to materials
with multiple automated layers, but more on that later. If that sounds interesting, let's get into
it! First, let's go over exactly what we want
to achieve: that is a material that automatically changes textures such as albedo and normal
when the angle of the slope between the surface's normal and up vector is too big. So let's take this slope as an example. What we are aiming for is having this part
automatically painted for us with a specific texture, for instance rocks, while still supporting
manual painting over here. We can go even further and add another layer,
so that these parts of the slope will use a different texture than this segment. Now let's hop into Unreal and start creating
right away! So we're starting things off with a basic
landscape material just so I will be able to show you how painting the landscape will
behave. Basically, what I got here is two materials,
grass and soil, that I can paint using this layer blend node. So first of all, let's bring in the rock textures. So I'm just going to go in my content browser,
select all of these and drag them in here. Now, we can't simply use these textures, we
will need to world align them. You will see in just a bit what that means
if you have never seen that before! So first, let's go to our normal and convert
this to a texture object and let's do the same for the diffuse texture. So for the normal, we simply need to get WorldAlignedNormal
and for the diffuse texture we need to get WorldAlignedTexture. Then we will have to get vertex normals in
world space which we will multiply with a vector that has 1 on all the three axis. So let's get a vector 3 and then go to red
and put 1, green 1 and blue 1, then just plug this in B and from here we're going to normalize
so we're only going to keep the direction. Then this is going to be plugged in the world
space normals. Now these textures are going to be very small,
so we need to bring in a scalar parameter and call this tiling. And because these are SO small, this needs
to be a pretty big number like 1500. And then we can just plug this in the texture
size of both of these. And we can also plug this in UVs. Now in order to combine everything we just
created, we will need a node called MakeMaterialAttributes. And if you closely look at this node, you
can see just how similar it is to the main material node, because we're basically creating
a material inside a material. So let's go on and plug everything we need
in here. And also make sure that you're going to plug
the right textures in the right pins. So now let me show you what world aligned
textures do. If I'm going to move this cube, the texture
is not going to move with it, instead it is going to look like we're scrolling through
the texture. And this is very useful for us, because this
way we can easily avoid problems on the landscape. So now how is exactly do we automatically
paint these textures on the landscape. For that, first we will need to get the up
vector. And to do that we need to get a constant 3
vector with the blue value 1 and the others 0. And keep in mind that red, green and blue
actually translate to X, Y and Z. So by doing this we're basically getting a
vector with X 0, Y 0 and Z 1, which is upwards. Now we will want to transform this vector
and we want to go from tangent space to world space. This node here is going to transform the up
vector of the tangent space to world space. From here, we will want to normalize this,
because we only care about the direction. And now between the normalized output and
this vector we are going to do the dot product. So plug in A the normlized output and in B
the vector. And we're going to use this dot product to
compare the difference in directions. So let's preview this real quick. You can see how on top we have 1 and in the
middle we have 0. What's below 0 is not 0, it is actually negative
numbers, but we cannot display that. So imagine this: at the top we have 1, in
the middle 0 and at the bottom -1. That is because when two vectors are perpendicular
on each other, the dot product is going to be 0. When the angle between the vectors is 180,
then the dot product is going to be negative. But when the angle is between 0 and 90, the
dot is going to return a positive value. So what we can do from here is get a linear
interpolation and plug this in alpha. And then let's get a scalar parameter and
call this Height Min. Then we can copy this and rename this to Height
Max and this is going to be plugged in B and the first one in A. And let's set the value
for the minimum to -5 and the value of maximum to 3. If we're going to preview this, we will basically
see the same thing, the only difference is that the negative numbers start much earlier. So now we can easily control how big the angle
difference has to be until the rocks start being painted. So if I will change the minimum from -3 to
-1 this is going to be much closer to the middle. But by going back to -5, the angle difference
threshold is going to be much lower. Now from here we can get a CheapContrast and
we can get a scalar parameter called contrast and set the default value to 3 and then plug
this in contrast. Now, what this is going to control is how
sudden the change between grass and rocks is going to be. So now essentially black is going to represent
where rocks are going to appear while white represents how grass is going to appear. You can quite literally think of it as "slapping"
grass on rocks. Now the final step is going to be getting
a layer blend standard. This is going to allow us to blend between
this MakeMaterialAttributes and the layer blend. So plug the result in alpha, then in the base
material plug the MakeMaterialAttributes for the rocks and then, for the top material,
plug in the layer blend. And now the actual last step is to break the
material attributes, which is the reverse function of making material attributes. And now we just have to plug in all of these. And now after applying everything, we can
see how this looks in the preview. After tweaking some of the parameters we set
up, this is how the material looks on a landscape. While this is good, we are not yet done. There are two things we can still improve
on: a more realistic blend between the materials as well as a secondary material for smoother
slopes. So let's see how that is done! Firstly, we need to bring in a new set of
textures and apply the same process of world aligning and combining them into a material. Now that we did that, what we can also do
is copy this part right here, because we're going to reuse 95% (a bit too specific) of
it. So to remind you what we're getting right
now, it is a black sphere with a white top. But instead of this, let's do the following:
let's go to our up vector and from here get a linear interpolation, then in the alpha
plug 0.1 and then in B we should plug our normal. And now you can see just how much different
this looks. Instead of having that smooth transition like
a gradient, we're going to get this based on the normal. Now, this might be just a bit too much, so
we can go to Height Max and set this to three. And this is the way we're going to transition
between grass, to smaller rocks and to our big rocks. Obviously, you can also use the normal for
the big rocks, but I decided not to. But if you decide to do that, just apply the
same process using the linear interpolation and the normal. Now, in order to combine our three layers
we have to go and cut this StandardBlend from here. Instead of firstly combining the bigger rocks
with the grass, we have to combine the grass with the smaller rocks. So for that, let's go to the layer blend and
right here paste the material LayerBlendStandard. Then plug in the top material the layer blend. Then for the base material, go to your small
rocks, go to the MakeMaterialAttributes node and plug that in here. And for the alpha, it is the same thing, we
have to plug in here this CheapContrast. So now if we're going to preview this we will
still see that blend between the grass and the rocks, but it is going to be much more
natural. Now what we need to do is to combine this
with the big rocks. So let's copy the node and paste it again. Then in the alpha, plug the CheapContrast. Then in the top material, we will plug the
result from our previous blend and then in the base material we will plug the MakeMaterialAttributes
from the big rocks. And now all of this is going to go into the
BreakMaterialAttributes. Now you might notice that there is no difference
between this and the previous material. That is because we need to change these parameters
right here and give them different names. So I'm going to call this "Height Min 1" and
then I will call this "Height Max 1". As well, let's also change the contrast from
"Contrast" to "Contrast 1". Before playing around with the material instance
and its parameters, let me explain exactly what is happening. First of all, image that we have a sphere
with a grass material. Now, we're going to keep the light area as
it is and change everything that is dark to rocks - in the end getting to something like
this. Now imagine that we have a sphere with this
result, we're going to keep everything that is in the light area as it is and change everything
in the dark area with even bigger rocks, getting to a result where we're going to have grass
at the top, small rocks in the middle and big rocks at the bottom. So now let's apply everything and play around
with the parameters we set up. So let's say that we want to have more small
rocks. What we can do is go to "Height Max" and then
increase it. And as you can see, now the small rocks are
even more visible. Now let's say that want to have more grass,
what we can do is go to "Height Min 1" and increase it. And as you can see, now we're going to have
even more grass. Besides the awful landscape, I would say that
this looks pretty good, especially now that we have normal blending for gentle slopes
as well as a second set of textures to help with the transition between grass and rocks. And all of these can be adjusted from these
parameters. If you want to stay up to date with other
tutorials like this one, be sure to subscribe and hit that bell so you won't miss anything. As well, consider supporting my work over
on Patreon like these kind folks: Aviram Ifm, Bader AlQahtani, Giovanni Pena, Golden Glow
Master, Leonardo Pereira, Luc Schurgers, Realitätsverlust and Taman Gerring! Let me know in the comments: do you prefer
automated or manual materials? Personally, I think a mix of both is the right
way to go. Can't wait to hear your answers! Now make sure to go and watch this tutorial
to learn more about procedural stuff for environments! Thank you for watching and I'll catch you
in the next video!