Home Unreal Engine

Ue4 - Terrain Mesh Normal Blending with Virtual Textures Guide!

polycounter lvl 3
Offline / Send Message
Pinned
squash polycounter lvl 3
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.

Replies

  • 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
    Offline / Send Message
    squash polycounter lvl 3
    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 grand marshal 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 14
    Going to play with this tonight, thank you!
  • Darkimage
    Offline / Send Message
    Darkimage polycounter lvl 11
    the world height seems not functional at all even if you plug in a scalar the output is always zero (Unreal 4.24.3) anybody got it working? is this a know bug?
  • elec²ron
    Offline / Send Message
    elec²ron polycounter lvl 12
    Not had any luck with the world height either. Would love to get this working because there are some big problems with landscape distance fields on certain computers. It looks like it just wont work on many windows 7 machines.

    The results on my windows 10 machine are really great so thank you for this write up. 
  • elec²ron
    Offline / Send Message
    elec²ron polycounter lvl 12
    Nevermind, I got it working following this tut.

    https://quixel.com/blog/2020/1/22/blending-megascans-assets-in-ue4

    The only thing I did differently was to use a second VT for the world height and put the virtual texture num LODs up to 7. 

    Results are as good as the distance field. :)
  • Ronweforall
    Hi,
    RVT blending is very interesting with posibility of auto texture color blending from the landscape. Do you know is it possible also blending with RVT between meshes/assets? Under is an example of blending landscape-sphere and landscape-megascans asset. But how to blend between sphere and asset?
  • C86G
    Offline / Send Message
    C86G greentooth
    Do I need a separate material for EVERY mesh I w ant to get blended?
    Lets say  I piut a stone on my landscape and ajdust the parameters to make it blend nicely. Now I take the same stone and ut in somewhere else, but higher or lower coordinate-wise. That means this same stone need a unique maetrial  with adjusted parameters?
  • jayfield1979
    C86G said:
    Do I need a separate material for EVERY mesh I w ant to get blended?
    Lets say  I put a stone on my landscape and adjust the parameters to make it blend nicely. Now I take the same stone and ut in somewhere else, but higher or lower coordinate-wise. That means this same stone need a unique material  with adjusted parameters?
    No... create a master material as found in this tutorial video and you'll be golden:

    https://www.youtube.com/watch?v=_u-HdkJ3woE

    You can get results similar to that found from the OP but without having to switch Distance Fields on. TBH, if you're working on a large open world, then you'll probably have DF's on to help with distance-based AO but you won't need to call them explicitly in your materials - which is a killer for performance.

    However, whilst this method seems to be reasonably performant, I am really struggling to get the VT to work with any kind of triplanar projection. The issue at the moment is that the projection onto the intersecting meshes only happens along the Z axis (which is mostly what you want), but for steeper parts of the intersecting mesh, it would be good to have projection from X and Y too. 

    It seems that once the VT is written, when you sample it, it's just a float 3 so I can't plug this into a texture sample node to apply triplanar UV's. 

    Anyone have any clues?


    EDIT

    Maybe I shouldn't be trying to map the ground surface onto X and Y projections of the mesh anyway... maybe a better, and more realistic option, would be to mask out angles above 35 degrees.... If you think about it, the ground material wouldn't accumulate on steep aspects of an object anyway and it would give the added benefit of a more broken-up mask around the level of the height blend. I'll give it a go....

    UPDATE

    Yeah, subtracting steep angled faces (via Vertex Normal WS of the mesh) worked and looked more natural. Triplanar projected VT's would have been overkill and hit performance anyway.
  • jayfield1979
Sign In or Register to comment.