Announcement

Collapse
No announcement yet.

How I made a landscape material.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [TUTORIAL] How I made a landscape material.

    Here's what I needed my landscape material to be:

    1. Procedurally paint itself (in my case - stone on the slopes, grass on the plains, and pebble on the shoreline).
    2. Still allow some handpainting (for riverbeds and around roads).
    3. Allow grass output.
    4. Deal with texture tiling.




    Disclaimer
    Though fully functional, this is a work in progress, subject to change. I'll try to keep posting updates in this topic for the improvements I make.
    I have extensively analyzed, modified and implemented methods used in the materials provided by Epic Games, namely - the tile elimination strategies. So all credit for tile elimination goes to them.
    The methods for blending the textures I used are not the only ones in Unreal Engine; actually, there's a function called WorldAlignedBlend which I used early in development and ditched because it used to misbehave and offered less control than the Dot Z vector method I used.
    The hand-painting support not functional yet as I am yet to decide how to use the external input to remove grass.



    Let's take a look at the result before we go on analyzing the material itself:

    Click image for larger version

Name:	triptychlandscape.jpg
Views:	1
Size:	292.1 KB
ID:	1162244

    Bird's eye view:

    Click image for larger version

Name:	triptychisland.jpg
Views:	1
Size:	106.8 KB
ID:	1162245

    Mind you, the material is pretty straightforward and how good it looks is going to depend on the heightmap you're using to generate terrain. I made mine in WorldMachine, rendered it at 4k+1 resolution (4097x4097), saved as R16 and imported to Unreal Engine.

    Next post - analysis of the material.
    Attached Files
    ------------
    Progress on Triptych

    #2
    When I said my material was pretty straightforward, I wasn't joking. I decided to mask the slopes (R), plains (G), shores (B), so I could reuse that information later (gives most control).

    I masked the slopes with the same method I used in the waterfall shader I'm working on:

    Click image for larger version

Name:	SlopeBlend.jpg
Views:	1
Size:	86.6 KB
ID:	1088578

    Used DOT function to compare the VertexNormalWS to the Z vector (Constant3Vector 0,0,1). This paints your vector in a gradient representing the angle of the vector compared to Z axis. So, the rest of the math is to confine the gradient to the transition from slope to plain (slope starts at .7). Lerp and clamp it (turns out I was right to clamp it in the end, as no clamp would add weird colors to your textures.) Oneminus node is to reverse the gradient (from "not exactly logical, but seems to work better that way" things).

    Now let's mask the height. It's even easier:

    Click image for larger version

Name:	HeightBlend.jpg
Views:	1
Size:	46.0 KB
ID:	1088579

    We take the Z (B) component from the AbsoluteWorldPosition, divide by a number I found to be working, 128 in my case, sharpen the transition with CheapContrast, invert the gradient and clamp it between 0 and 1 (weird colors).

    Now let's blend the masks together:

    Click image for larger version

Name:	LayerBlend.jpg
Views:	1
Size:	96.8 KB
ID:	1088580

    The order is important. See, the slopes on the shoreline should still be Rock. So first we blend the grass with pebble (G with B via HeightBlend), then blend the result with R (SlopeBlend).

    You can already plug the result of the final lerp to the BaseColor input of your material to see it colorize your landscape properly. Now let's extract the masks for easier usability:

    Click image for larger version

Name:	ExtractMasks.jpg
Views:	1
Size:	66.9 KB
ID:	1088581

    All the inputs are plugged to the output of the final lerp of the previous screenshot.

    At this point the material is already functional; the masks we got can be used to paint the material with your textures. Next post - fine-tuning the material.
    ------------
    Progress on Triptych

    Comment


      #3
      Before we move forward, here's a couple of things you should know about texturing a landscape. Landscapes do not use the common coordinate system we use for meshes (TextureCoordinates). So, to use a non-tiling texture on a landscape, we need the LandscapeCoordinates node. Set the mapping scale to the resolution of your texture, leave the rest of the controls alone.

      As for tiling textures, it's better to use WorldSpace coordinates. The node to achieve this is WorldAlignedTexture. It uses a Texture Object (can convert your texture samples to Texture Object right-clicking the TextureSample node and selecting Convert to TextureObject) as an input. Also, you need to use the TextureSize input to specify the size of your texture in WorldSpace units. And the Export Float4 input if you're using the texture Alpha channel for Roughness.

      To blend the normal maps, you'll need to use the WorldAlignedNormal node. It's similar to WorldAlignedTexture, except you only need the TextureObject and TextureSize inputs.

      To clean up my material, I used Material Functions for my textures. The function structure is similar for all 3 layers, so I'll post only one. The difference is - I divided the TextureSize inputs by 1.3 (LargeSize) and 2 (SmallSize) for Grass and Pebble materials, and didn't divide for the Rock, because I needed smaller textures for the first two. So I'll post only the grass Material Function. Here's the outputs for the texture:

      Click image for larger version

Name:	MaterialFunction1.jpg
Views:	1
Size:	116.2 KB
ID:	1088584

      And the normals:

      Click image for larger version

Name:	MaterialFunction2.jpg
Views:	1
Size:	73.9 KB
ID:	1088585

      I did not do the blending inside the material function, because the Macro Variation mask was the same for all of them and I did not want to add the material texture count.

      Next post - getting rid of the tiling.
      ------------
      Progress on Triptych

      Comment


        #4
        I learned the four methods used together to get rid of the tiling from the materials provided by Epic Games (starter content). First I'll show the macro variation mask I used in my material, then describe the methods:

        Click image for larger version

Name:	MacroVariation.jpg
Views:	1
Size:	148.9 KB
ID:	1088586

        So, the four methods are:
        1. Multiply BaseColor after blending the layers with lowered contrast MacroVariation mask.
        2. Blend LargeSize and SmallSize textures using the higher contrast MacroVariation mask.
        3. Fade to an average color in distance (the result of the first step is preserved, as it is done later)
        4. Fade the normal to a flat normal map (Constant3Vector 0,0,1) in the distance.


        For the last two steps, here's a gradient mask to fade the texture to flat color/normal map to flat normal:

        Click image for larger version

Name:	FadeDepth.jpg
Views:	1
Size:	135.8 KB
ID:	1088587

        The perlin noise texture is used not to get a too uniform fade.

        How do we get the flat color we need to fade into? Here's an online tool for that, you upload your texture and it analyzes the colors used in it, also gives you the average and medium colors for your texture in RGB:

        http://mkweb.bcgsc.ca/color_summarizer/

        Next step - implementing these methods and finalizing the material.
        ------------
        Progress on Triptych

        Comment


          #5
          Ok, there's some point at which a complex material's shader network starts looking really ugly. In our case, this is that point. Warning - the incoming screenshots will be VERY, VERY messy. I'll do my best to explain what's going on there - not really complicated, actually. I'll post the Grass layer again; we get the other layers in a similar way:

          Click image for larger version

Name:	GrassLayer.jpg
Views:	1
Size:	181.0 KB
ID:	1088589

          We had 6 outputs in our material function: Albedo Small/Large, Roughness Small/Large, Normal Small/Large. So we just lerp our Small/Large pairs together using the high contrast macro variation mask. Now we connect the Albedo's lerp output to another lerp node, connect the alpha to the distance fade mask, the B output - to the average color. I used the last lerp (and plugged the Base Color into Specular) to match the colors of the landscape and the grass. If you don't have the same problem, you can skip it.

          Repeat for the other two layers, reuse parametric nodes. We're not fading the normals here as, unlike the average color, the flat normal is the same for all of them and can be done after blending.

          Not to overburden the screenshot with text, I'll color code the inputs - R for Rock, G for Grass, B for Pebble:

          Click image for larger version

Name:	LayerBlendFinal.jpg
Views:	1
Size:	73.3 KB
ID:	1088590

          So, first we blend the Grass (G) maps with the Pebble (B) maps using the Dirt (B) mask we got in the beginning. Then, we blend the result with the Cliff (R) maps using the Cliff (R) mask. We still need the Grass (G) mask for grass output.

          Now, let's finalize the texture outputs and plug them into our material inputs:

          Click image for larger version

Name:	MaterialInputs.jpg
Views:	1
Size:	147.3 KB
ID:	1088591

          The LayerBlend nodes are not used right now; I'll write about using them when I learn how to remove foliage when painting, in our case, the Road layer. The Global Normal is a big 4k normal map I got from WorldMachine; I'm using it to make the HeightMap look nicer.

          So, all we have to do to wrap up our material is to get the grass output working!

          Click image for larger version

Name:	GrassOutput.jpg
Views:	1
Size:	33.0 KB
ID:	1088593

          You have to specify the Landscape Grass Type asset to be used with the Grass layer. It's easy to create and edit one - if you need a tutorial on that one too, ask in comments.

          Thanks for reading this tutorial, hope it helped you. If you have requests/comments/additions to the tutorial, you're welcome to add them in comments. If you use the material in your project, a screenshot added to this topic would be appreciated. Have fun.
          ------------
          Progress on Triptych

          Comment


            #6
            nice material. i make mine with 2/3 diffuse and normals. then connect them with landscape coords and landscape blend.

            Comment


              #7
              Care to share a screenshot?
              ------------
              Progress on Triptych

              Comment


                #8
                Hey I'm struggling a bit with finding some of these nodes, is there an upload to the finished file? especially the outside nodes that do the in/out from this section..Click image for larger version

Name:	Capture.PNG
Views:	1
Size:	339.8 KB
ID:	1088615
                Last edited by joplin66; 10-02-2015, 05:34 PM.

                Comment


                  #9
                  The nods you can't find are either Function Input of Function Output. I just named them.
                  ------------
                  Progress on Triptych

                  Comment


                    #10
                    Got it thanks dude, working great!

                    Comment


                      #11
                      Been making one of these myself lately. It's a lot of fun! Thanks for the share - will cross reference it with my own and see what I can improve on

                      Comment


                        #12
                        Me and joplin66 highly improved on the original idea, sadly I caught a cold. When I feel better, I'll update the tutorial with the new material.
                        ------------
                        Progress on Triptych

                        Comment


                          #13
                          Looking forward for the updated version! Hope you get better soon! @Rhayader. Going to look in to this from the start now

                          Comment


                            #14
                            This is very cool and exactly what I was trying to achieve. It took a while to put together; even reassembled your screenshots into one large image . Some things I have noticed though: all my textures have been washed out, more resembling the macro texture than the actual textures. Also, it seems the culling on the grass doesn't change regardless of adjustments. Maybe I still have something wrong. Really looking forward to an update on this!

                            Comment


                              #15
                              Very nice tutorial

                              Comment

                              Working...
                              X