Get Landscape height in material applied to a static mesh

first off let me clarify that I didn’t assume anything from what you posted, but based from my own experience with using the feature. what you showed indeed looked like a blend but as I said since the beginning I didn’t really understand what was going on :smiley:
secondly I assumed DBuffer decals based on the documentation guide, but the results I’ve gotten myself were always the same either using Deferred Decals or DBuffer Decals (the documentation just now led me to think that DBuffer decals were required for mesh decals to work)

now, this is the result of me applying a decal material (Domain: Deferred Decal, Blend: Translucent, Decal Blend: Translucent) to the engine sphere StaticMesh and putting it aside my rock and landscape
(excuse the low framerate, the forum is really limiting in terms of filesize)

meshdecal.jpg

the sphere acts as a translucent material (with its own UVs and everything, absolutely no projection going on) with the only difference that it seems to “inherit” shadows from underlying geometry (i.e. shadows from underneath render on top), see the following picture:

either I’m doing something terribly wrong with the mesh decal setup (mind you, I just followed the usage guide), or you have access to some special magic that I don’t :slight_smile:

the mesh decal clipping is evident even in the documentation as well btw

ok I think I figured out what you’re doing

I used WorldPositionBehindTranslucency instead of WorldPos as my mesh decal UVs, then disabled TangentSpaceNormal. this is indeed projecting to the world behind.
I actually wish I knew this kind of usage before. it never occurred to me to use it like this, the documentation doesn’t mention it anywhere and I never saw it described here in the forums :frowning:
anyway this adds yet another option that I can experiment with :slight_smile:

Yeah well, mesh decals in UE4 is something different, so it ended up in a bit of miscommunication from my side.
We are dealing with deferred decal, just substituting decal actor projection box for a mesh.

I’m working in a custom engine build, but what we are discussing does not rely on any features, that are not part of stock 4.19

Sphere just gives you something, to draw on. Does not need to be sphere at all. Just needs to be mesh, suitable for foliage tool, but sphere works better, when reconstructing worldpos behind translucency.
For projection, you would be relying only on world space center of sphere, and whatever is behind the sphere(world position behind translucency).
Opacity can be obtain by sphere masking world space sphere center against worldspace pos behind translucency.
WorldPos behind translucency also serves as UVs.

For each landscape layer, there is a foliage type, that is the same sphere, but different material instance with appropriate textures.
Painting is restricted to layer weight threshold.

Fundamental problem of whole this approach, which conventional decal actor is depraved of, is translucency sorting. Spheres, that belong to different layers, will occasionally fight, when overlayed.
It is somewhat slower, GPU wise, than decal actors.
It is also less accurate, due to world pos reconstruction.

But if translucency sorting can be reasonably addressed, It can be used right away.

As for the stretch issue, needs some thinking. Storing normals additional time for decal rendering or normal pre-pass is not the thing one might do. Depth and Pos gradients to rely on is the only candidates so far.

yeah the rest just unfolded in front of my eyes when I used WorldPositionBehindTranslucency :slight_smile:

while I apreciate the value of this approach, I think I prefer going for the classic decals. after trying it out a bit more, these things push me back from this approach:

  • lots of polygons used (one quad is not enough), lots of meshes needed
  • material gets more complex (reconstruct worldpos, blending based on depth with min threshold, max threshold also needed to avoid blending to infinity on grazing angles, the rest of the things you mentioned to achieve proper opacity). accuracy is okay though
  • decal sorting does get problematic ocasionally

maybe if I manage from one box per mesh (in the case of a single layer underneath) and if I figure out all the details of the shader it would be good enough, but then it just comes to level with decal actor in terms of features (ending up in pretty much a direct “drawcall vs material complexity” tradeoff)
I’ll keep playing with it, maybe it ends up convincing me

even if I don’t use it for mesh-landscape blending it’s still very good knowledge, I might never would have stumbled upon it had you not shown it in this thread. this will most likely prove useful when I get to attempt a spline decals experiment :slight_smile:

Gotta agree on all of the following, but it is sorting mostly.

It is exactly draw vs shader load tradeoff.
But not worth investing any time into it, unless sorting is dealt with.

Yep. Can be used that way.
Other use is… well… a terrain decal system.
Replace a sphere with a quad and off you go.
Yeah, it is pixel shader heavy, but with decal actors one can’t boast having 5k decals in frame, rendered in 20~ batches with out-of-the box atlasing support.

Really appreciate all the feedback and discussion on alternative techniques.

Thanks for this, seems like a very useful tool for special situations.

I’m unfamiliar with the ‘pivot painter’ mentioned earlier but have refactored the heightmap lookup to offset every vertex to the terrain, using local space offsets scaled to maintain mesh geometry except were it intersects the terrain. Those vertices get squashed and blended out based on distance from height field.
No more vertex colors, like suggested by Deathrey.

This material locks the mesh to the terrain, easy placement on shallow slopes. Could maybe work on steep slopes if transform is account for in heightmap lookup and vertex local offset projection.

My level requires some repainting of Landscape Layers so touching up around a few trees or rocks is no issue. The discussion on this thread got me thinking, so I added an extra Texture sample to the material to help with the blending. The Texture/Normal/PBR is blended on the mesh at terrain intersection same as masking is calculated but with its own contrast. The ‘Scree002’ asset I am using from Kite Demo UV’s worked for this demo but for production may want to add a second UV channel for the texture used for blending at terrain intersection.


Mesh stretching and sharp angles were present in the asset I am using and not introduced by the heightmap projection… on shallow slopes.
Parallax is also significantly reduced with this new blend.

As for blending a decal, that could work and might be the best option in some situations, but at the moment I am only researching this for rocks and trees that are procedural placed and limited to shallow terrain slopes. Touching up Landscape layer paint and changing the texture this material uses per-instance to help blending should do.

The extra cost of this material is the heigtmap and texture/normal/PBR for blending samples. The material can be limited to closer LOD’s so the heightmap could be cut up into a grid so sampling size is reduced. Heightmap grid seems could overlap to avoid multiple sampling.

If TemporalAA is disabled you get a hard edge but the blending area texture and landscape layer touch up makes it acceptable imo.

I have to do more testing and get this applied and working on trees to understand the overall hit on performance and visuals.

The problem I have now is that collision simulating this mesh shape is invalidated by this material.
My first thought is to wrap these assets in a blueprint and calculate collision on creation.
Not sure I can do this in a blueprint, if so I have 2 initial ideas.

  1. Use several collision shapes authored and provided in the FBX, each could be dynamically placed on terrain to roughly simulate the distorted shape.
  2. Use a copy of the distorted mesh per-instance as ‘Complex To Simple’ collision.

Anyone see a problem with these ideas or have a better solution the Unreal Engine can provide ?

Thanks.

I’d probably just author rock collision mesh with due allowance for vertex movement.

Probably the only solution, I’ve looked into adding blueprint wrapped static mesh to the foliage tool and from what I see its not supported.

Feel like I “jumped the shark” a little with offsetting the mesh vertices to height field unconstrained. should use min/max bounds to maintain valid collision simulation.
The way I am blending with the Landscape material looks ugly because using UV’s from the mesh so textures don’t map-align to the landscape. Also I only support single material so fails when mesh covers multiple Landscape layers.

My original intent was to just cleanup intersection of instanced mesh with height field, my allowance for going back and painting around instances actually is not good when there could be thousands of instances, like with trees. To truly maintain procedural solution and also include material blending from mesh-to-landscape I think decal ‘automatic placement’ (link) is a good start. But like points out that can become draw-call heavy.

Could add ‘decals as ISMs’ to blend mesh to the Landscape as suggested by Deathrey (link) but how can this be done procedural since the foliage tool is needed ?

All Foliage ISMs can be iterated over at game start to procedural implement a mesh-to-Landscape blend solution, see this post Iterate over foliage ISMs. If InstancedStaticMesh class can be extended to support unique custom UVs per-instance then could get Landscape Layer and store weights per-vertex to blend into height field. World UVs can be calculated to get clean mapping of Landscape material to mesh. This would be trade off from heavy draw-calls with decals to a heavy material but imo the later is the better solution.

So I got my answer on how to sample height field from a static mesh, learned some new UE4 decal/ISM stuff and I’ve challenged myself to extend my Material to include material-blend-to-landscape. Overall fantastic first experience on forums, thanks everyone :slight_smile:

You can add supportive collision shapes, but it is not exactly the most sustainable thing.

When you get to point of getting landscape layer textures, you are down to vertex painting solution basically. No way to make it automatic and reliable.

All these are just our speculations, not readily deployable approaches.

I doubt it is possible in stock config, but pretty sure there might be plugins. Otherwise you will need to dive into code a bit.

But passing weights per instance vertex is still not sustainable in full scale either. You would need to generate all possible variants of instanced mesh shader, depending on what landscape layers it needs.
This approach would rely on using texture atlases/arrays.

Depending on your goal( game, demo, or a still beauty shot), you might just keep the most visually appealing approach.

you can make them match by using world-aligned textures both in your landscape and in the 'blended' texture that's used in your rock mesh (just be weary of steep slopes, as I showed earlier).
alternatively, you could ditch the idea of "blending the landscape textures into the mesh" and rather go for "blending an intermediate texture both in the landscape and the mesh".
for example if you look at [this screenshot of BF1's Monte Grappa](https://cdnb.artstation.com/p/assets/images/images/004/162/205/large/simon-barle-simonbarle-04.jpg?1480952513)on the bottom-left corner you can see a rock mesh, some rock-gravel texture on the terrain and then some grass around it. now imagine if the rock-gravel texture would be just a decal to transition between the rock mesh and the grass on the terrain. [this is not how BF1 does it but] it could fit my Decal method perfectly, and you could completely ignore the landscape layer underneath if the texture is fitting enough, which also gives you the advantage of ignoring multi-layered areas underneath your rock.

This is the method I’m leaning to atm (since I want an automatic method as well). assembling a patchwork of decals around the mesh to match multiple underlying layers is not only tricky to do right, but also would quickly explode drawcalls (while just 1 decal per mesh is manageable)

I’ve never tried it, but it’s my understanding that you can add ISM’s from code/blueprint

thank you as well, this post pushed me to experiment with this topic (which I’ve been meaning to do for quite a while), and I’m glad you have welcomed the topic derivating from “how to adapt my mesh geometry to snap to my landscape” into “different ways to blend meshes and landscape”


if you can get the layer underneath via traces (and have a way to “get the textures” out of the layer and inject them back to the mesh/decal/whatever, which I’ve done already), why can’t it be automatic and reliable? it comes down to granularity but I think it’s possible

when using my decal approach, if it is reduced it to one decal per mesh (and blend an intermediate texture decal-[C] into landscape-[A] and mesh-** as I described above, instead of blending landscape-[A] into mesh-**), in your opinion why wouldn’t this be a readily deployable approach?

This is an approach that I have used in the past, I’ve found that a nice solution is to render a top down custom depth pass of the level with all of the meshes that you wish to blend and then use that in your shader as a mask to specify where to place material layers to use. This is more limited than decals perhaps due to the fact that it will inflate your material complexity, and you wont be able to have as many different blends. But often I am only looking to blend one or two kinds of meshes. Of course another downside is that you then need to maintain the landscape material and the material applied to the mesh so that they match, rather than one decal material.

This is totally possible in blueprints, you can add and reposition foliage instances too! The only issue is that they can be a little bit buggy, as the foliage instance transform widget will not get positioned correctly, and if you then try to manually move the instance created via blueprints in the foliage panel, it will snap that instance back to the foliage actor origin. Come to to think of it, I should probably submit a bug report as using blueprints to modify foliage is pretty useful (reducing clipping, more advanced procedural distribution etc)

If you have 16 terrain layers, it is already 256 shader permutations. Possible, but not sustainable, reliable, or practicable.

One decal per mesh, following a philosophy of blending into a single intermediate texture, is scaleable and sustainable.

You don’t always want that kind of thing visually, but that still remains the most favorable approach, as applied to UE4.

Anybody managed to do this efficiently with RVT yet? I can’t seem to get it to work generally, you’d think that subtracting absolute world position with the RVT height would get you pretty close to what you need but its not really working as intended for me.

OMG , What the LandScape Document , this is the way What the companies Do To Make BIG LandScape ,GJ