Ue4 - Terrain Mesh Normal Blending with Virtual Textures Guide!

Offline / Send Message
Hey its my first post here. Hope this guide will help yall !
Couple of months ago when i started playing with Ue4 i was obsessed with terrain mesh blending. So i started searching but couldnt find any tutorial on how to do it. After some search time and experimenting i finally found a solution. It was already there but i couldnt get it to work properly. Since i found how to do it, im sharing it.
I used Unreal Engine 4.24 for this guide. For fastest testing i only used base color and normal map textures for both landscape and meshes. And constant 1 roughness. Since this method uses runtime virtual textures, at certain angles textures will stretch. Thats the downside of this method. I think it can be fixed with tri planar textures if you need to.

First let me show you how it looks. Lit, unlit and world normal.

1-)  First of all i enabled virtual texture and mesh distance fields from project settings. Neither of them are necessary but its the convenient way to do it. Distance field will mask closest meshes. It can be done with vertex color painting instead, which is perfectly fine and more optimized. Virtual texturing is for sampling normals and textures of terrain to blend. Optionally render target 2d can be used instead but i dont recommend it.

2-)  Next, i created a runtime virtual texture (You can tweak its values for higher res textures). Than i selected my landscape and choose my virtual texture from details panel. Than i added a runtime virtual texture volume to my leve. I selected my landscape from details panel and copied rotation and scale and selected my runtime virtual texture.

3-)  Landscape material. I used a simple material for landscape, it has 2 layers. Than added a runtime virtual texture output and plugged my base color and normal textures. The problem is normal output will give tangent space normals to other meshes. Which i dont want because i need to blend with terrains world space normals. For that i used transform vector node thats set to tangent to world space. But it gives an error. I dont know why, its working fine so i didnt mind but i will try to fix that in the future.

4-)  Blending mesh material. First of all, i disabled tangent space normals from details panel. Because it will sample world space normals from terrain so it shouldnt see it as a tangent normal. And for meshes normal map i used transform vector and convert it from tangent to world space which normally what happens when tangent space normal is enabled. I only need to blend edges so i used distance to nearest surface and created a material function for that. And then i added a runtime virtual texture sample node to get terrains textures, and i selected my virtual texture from details panel. And lerped meshes and terrains textures.

5-)  I added a mesh to my level, created an instance of blending material, select my meshes textures. I disabled "affect distance field lighting" from meshes details panel because when its enabled it gives inaccurate results.

And here is shader complexity.

I think thats pretty much it. I hope that was helpful. You can ask questions if you have any, or reccomendations.


  • Eichi
    Nice job there!

    I have been fiddling around with terrain mesh blending long time ago (before virtual texturing was a thing in UE4) and yes, there is not much information about it online at all. There are some basic attempts, but nobody seems to have nailed it so far. To blend properly, we basically need the complete material properties (albedo, roughness, world space normals etc.) to blend to, so things can get very complex.

    I have read your article and I wonder why you are doing things like this. Mesh Distance Fields are super expensive. I see you are using it to be able to blend the edges between mesh and terrain. It is enough to "know" the terrain height below every pixel in world space. Same goes for the terrain normal in world space. You can get that information in a much cheaper way!

    Did you know that UE4 uses a "normal height" float texture for each landscape internally? That is a texture where RG = Normal XY and B = Height (or so). This texture is not exposed to the editor, but with some small C++ magic here and there, you can sample it from within any material. This solves the issue that you need to know terrain height and normal in world space, but does not solve the color/albedo, roughness etc. channels. Maybe this is where virtual texturing makes sense (either engines do this as well).

    Maybe you can give that a shot as well? Mesh Distance Fields are really expensive and as said, the info you need to blend properly is already available at runtime.

    Besides that, our standards seem to be very high. Everyone seems to just dither the shit out of TAA and nobody has been complaining so far :smile:

  • squash
    Hey, thanks for your reply.
    I did it this way because it was the only way i knew. Yes distance field is expensive but i thought if i develop a game i would use vertex colors instead. I wanted to do this guide because i worked on it for some time so why not share my knowledge. I see that they added "world height" option to runtime virtual texture but i couldnt find any information on how to use it. Maybe that could be to replace distance field.

    I never heard of "normal height float texture" you mentioned before. Even though im done with this topic, it could be useful for later if you can give more info about this method? Thanks again

  • Obscura
    Offline / Send Message
    Obscura veteran polycounter
    the world height can be used together with the world position node in the mesh materials. It could fully replace the distance field sampling.
  • Eichi
    @Obscura You got the World Height virtual textures to work? I get the "normal" ones to work, but the world height ones just contain 0 all the time. Have had a look at the source code of UE4 and it seems to be implemented, but I have failed to get it to work.
  • eCstatic
    Offline / Send Message
    eCstatic polycounter lvl 10
    Going to play with this tonight, thank you!
Sign In or Register to comment.