How to 'heighblend' two different fully triplanar displaced worldDisplacment

Hi there!
So, I am having two different fully triplanar displaced worlddisplacement in my material. One for cliffs, and one for sand. They go all crazy directions and I would love to proper blend them, but feel I am stuck here. It is possible to somehow perform something like a boolean union operation inside a material? So I can bury these cliffs partly inside sand while other pieces stick out?
The closest thing I got so far is to break the final Worlddisplacement for the cliffs into 3 floats and max them each. Then I got one single map then I can heightblend with just some simple constant. Kind of works but surely not bulletproof. Hopefully this short brief makes sense.
All the best! T

It’d probably help posting a picture of the current result, and a screenshot or two of the material graph (or a part of it that’s most pertinent).

“Heightblend” means nothing here, since we don’t know how you are controlling what the height is - nor what you are actually doing.

Best case scenario. Make a black/white image, load it in as a texture. Feed it as the alpha of a lerp. Use the 2 triplanar textures as A and B.

What height blend actually implies is that the 2 materials are blended together based on the Z (or B) channel of the mask that sits on top.
A being 0 the second material. B being the same material as the top material, so that its high points use that texture.

This makes it possible to pull off effects like having Moss only on high points for instance. Or filling holes with sand.

Again, all it is is a Lerp between A or B driven by a black/white texture.

It doesn’t seem like a heightblend is enough to get cliffs jutting out of the sand. That sounds more terrain sculpting based. Perhaps it depends on the other nodes used though.

hi all!
Thnx for getting back! I do know the concept of heightblend. Sculpting is for me no go. I have setup everything through my shader and I get the look right, just not the transition. Let me show you my stripped down graph. This is my basic setup to create some cool looking cliffs. The problem of ‘moving cliffs’ appears when variable ‘Displace’ nr 1 and 2, are having different settings. In this setup, you can easily make it work by making sure they both share the same values, but my graph is way more complex. I use several triplanar setups to mix and compose cliffs and it looks cool! They all got their different displace settings and I just stack them.
For example: cliff type 1 with large patterns + cliff type 2 with smaller patterns + cliff type 3 cross bedding = totaal mix of cliffs. And all these cliffs have their own displace settings.

But at the end, when I want to add sand to it, I cannot get it to transition nicely. The heighblend is nothing more then a max node. The issue is that the max node just takes all channels separately and not taking it as a whole single value. It is also more of a perception problem, because the math not wrong. I just don’t like the result and would like to know to right math to get it right. All the best! T
ps: try setting Displace for cliff to 100, 100, 10, 1 and sand to 100, 100, 10, 1. Then it works. Try setting like: cliff: 100, 100, 0, 1 and sand to 100, 100, 50, 1.
Doesn’t work anymore. The cliff will get lifted by the sand, instead of just clip through it.

oh ps:
here is a short video.
It did not capture the material editor, but in this video I am tweaking the Z component of the Displace variable as seen in the screenshot above. When the settings are the same, the cliff does stick out and not move.

I’m confused. You said you understand the concept, yet there is no Lerp within your material graph?


What’s that part doing, with reference to the video? It seems like it might be a problem for the cliffs sticking out when pushing the sand in (or is it the sand is sticking out when pushing the cliffs in?). What I’m getting at is the operation I highlighted is taking XY, masking the X channel, and then making a float3 vector that’s multiplied by the Displace float3 of the triplanar cliff 1. It seems it removes the X vector of the whole float3, causing it to constrain the change (in video) along the XY axis. It would be expected based on the WorldAlignedTexture node to get constrained based on the XY world coordinates. Yet, in effect, it appears the shelving that’s occurring is somehow from the XY > Mask X > MakeFloat3.

I will pull a mask out of the difference from the max node and what happens before. There are a few ways to do a heightblend. It is worth noting that I am a bit away from the ‘normal and casual’ way to blend layers together. I am not too far away from the end result, just looking for the math to nail it 100%. See image below for how my cliff stuff actually does look. I think the way I perform the blend does show up the nice organic exposed cliffs in a natural way. No painting of any landscape layer has been done. Cliff textures at different sizes and displaces are added. Gaps and strokes are filled with sand.

Did you post an image? It shows blank.

Anyways, appreciate the feedback, see this image of my 99% solution to have a better understanding. I am aware that I a bit offroad using my method, but I like to believe that my current approach is promising. (and less timeconsuming to start painting and tweaking 20KM2 of landscape) c33ff7d990b6362bc70771b0a1694419016e65c3.jpeg

I’m not questioning it based on the ‘normal / standard’ method that’s usually used. I’m simply trying to understand how it works, and help if I’m able. The result looks great, though could be inaccurate in terms of realism on a finer scale…not sure though. I don’t know exactly what you’re going for in terms of realism and the final result. The image I posted is of the material graph, and I highlighted the XY output from WA-complex node > mask (R) > break float3. It seemed like the sequence there is constraining the sand accumulation / degeneration to the horizontal plane moreso, thus limiting the result and causing the cliff edges to jut out at particular heights. But it could be an intended result.

no problem! Again appreciate all feedback.
Here is another image, trying to explain what I am looking for. 1. We have a landscape, 2 displace through XY, 3, adding sand, displace through Z (upwards ) and maybe a bit through XY. This is what I cannot get to work bulletproof. The image from my ingame version is more less a approximation.

Look, it may look OK, but if you are working on 20KM squared of a landscape, or even just 20km it doesn’t matter at all how good it looks when your performance is down to 5FPS.

Use meshes. make them stick out. blend them to the terrain.

that said, I don’t get your question.

IF you want to displace only on Z you isolate the B channel and scale it up by a custom factor.

IF you are looking to add the two effects together, you need to ADD, not max.
Max just picks the highest value given.

IF you need to Isolate the 2 masks, and have a composit result, then you need to first Subtract, then add back.

A is the cliffs height, B is the sand height.

IF I want the sand to raise on Z then, B -> Mask B * scalar. = C
IF I want the cliff to move on X/Y then, A -> Mas RG * scalar. = D
In this case, I can Append the results to get the final output with all channels: D append C - order matters.

IF The cliffs also displace Z
B -> Mask B * scalar. = C
A -> Mas R * scalar /G * scalar / (B * scalar) - C) > make rgb = D
result = (0,0 append C) + D

These options should produce the mask to use as the Alpha (and the input for displacement).

All of that is expensive if you use WorldAligned modes / WPO based stuff.
Even WPO for something as simple as Z height is expensive compared to just painting the layer and relying on the paint.
Again, you are better off using meshes and paint for performance.

One of the problems could be the use of VertexNormalWS in a simplified way, which is to say, the vertex normals are not getting interpolated for more freedom of displacing the sand relative to the cliffs. Why is VertexNormalWS preferable to PixelNormalWS, which would apply that displacing to every pixel rather than basing it on the vertices of the landscape alone?

I agree with [USER=“3140864”]MostHost LA[/USER] that the Max node is limiting it or wrong to use somehow, and is probably part of how the sand is merely extended or contracted along XY horizontal and not yielding an optimal result, or is not flexible enough. It goes with what you were saying that the Max node takes each value of RGB separately and compares the sand to cliffs RGB values, then displaces the one maximum value of the two. That in itself is going to limit flexibility of the sand-adding mechanism.

Observation: There’s also a few holes occurring in the landscape in the video (to the left), which is probably geometry splitting due to the VertexNormalWS being ‘expanded’ or ‘contracted’ on the UVs.

ola! Performance is not my bottleneck. This is not a realtime game in the most classic way. Adding models is just not an option. Thanks for the math. I will re-evaluate the max part.

I am not sure, but I think using pixelnormal node is problematic. This is a very heavy tessellated project. Those pixels don’t exists before tessellation. Seen it failing years ago on shader compile.

@all Anyways, yes there is some mislogic here. Let’s leave it with this. This is an abstract project, no realtime thing and removed all constraint that goes with realtime projects. So, proberly didn’t make sense to put this question over here in the first place. Thnx for all input!! :slight_smile:

Still. Let us know if the math helps.

Imho you can easily make the cliff mesh in blender using the displaced image and a custom level of tessellation that is far superior to what you can do in the material - remember that unless you unlock the limit, tessellation does have a vertex limit.

VertexNormalWS is preferable to AbsoluteWorldPosition, and usually it is part of the chain. You multiply It (vnws) * the displacement you want before feeding into the world displacement. Typically.

You know what else you can do?
Quixel mixer.

You could refine the look there to get a baseline math of what works visually. Its sometimes helpful even to see what the different blend modes would do without having to recompile materials ad libitum…