Z-Axis Oriented Material Issues

So I am working on a moss shader for a project I’m working on.
The purpose is that have the moss show up on the Z-Axis in world-space, so that when I rotate my mesh, the moss only appears on the very top of the mesh. The problem I am having is adjusting the falloff.

The following screenshot shows the current falloff that I am able to set up in the engine. As you can see, the blend goes from top to middle in a perfect gradient.

That results in the shittiness that is this:

Because my rocks are at a slight angle, they show up as completely covered in moss. I need to find a way to tighten that falloff, to something similar as the following screenshot. I want the moss to show up only at the very tip of the top of the mesh.

Ideally, I’m after a result similar to this paintover I did:

How do you think I could go about doing something like that?

You might be able to get away with a ratio of how close it is to the ‘top’ of the mesh, using something like (AbsoluteWorldPosition - ObjectPosition) / ObjectBounds. Vertex painting is going to be cheaper and have better controllability, but having something that is fully automated/‘just works’ is quite nice too.

Michael Noland

To tighten the falloff add a power node (instead of multiplying by a scalar like you did). Just make sure to clamp the dot product to 0-1 range before you do so.

Detecting the top of a mesh like michael noland suggested is also a good idea since it would allow the moss to run across sharp angles. This will only work properly though if all of these rocks are individual meshes.

I love you so much. This is exactly what I was looking for, you are all awesome.

Glad we could help. Please throw up a pic when you’re done with the scene, I’d love to see your results.

Michael Noland

this is amazing, im doing this with 4.9 right now!

The easiest way to get that is to use a node like “cheap contrast”. You could also do your own bias (subtract a scalar param) and multiply to control the bias and sharpness. You may want to instead use the normal map (or simply pixelnormalWS.z) to get your normal map in the response.

FWIW their is actually a material function in the engine that does all of that already called World Aligned Blend. It has various options such as whether to use the pixel or vertex normal.