This is how you can mask out any normals that were up or down. To mask out anything perpendicular to the projection angle requires creating a blueprint container for your decal and creating a Material Instance Dynamic and setting the decals X rotation to be the value of a VectorParameter. Then in the material, just plug in that new vector value to one of the pins on the dot product.
I’ve got a similar problem regarding decals. I was trying to implement your solution RyanB but I think I didn’t understand everything correctly and it won’t work the way it should. Is it possible you post screens of full material and bluprint to show the final versions of both? It will be a huge help!
I’ve tried deciphering what RyanB has said… creating the blueprint for the decal to get the normals, pass them through as a vector parameter on a dynamic material instance.
In the material, trying to dot to compare the pixel world space normal with the decal normal, but it’s just not working.
The goal is to obviously “backface cull” decals that are projecting through when they shouldn’t. The pics I’ve attached show why simply scaling the box volume doesn’t work, it’s projecting onto the inside of a curved thin suface of a pipe.
I’ve tried to make this in as simple of an isolated case as possible. If anyone (or the almighty RyanB himself) can chime in with some insight that’d be awesome.
what does your rotvector from your blueprint look like?
and I’m not sure how you’re accessing the scene texture world normal through a deferred decal. That gave a material sm5 error for me.
I tried your method, it required changing the decal material to translucent blend mode, which got rid of a bunch of rendering options I’d need (accessible through the dbuffer blend modes). It also didn’t render the decals in shadows which was weird.
I’ve attached pics of another hacky method I’ve tried, I’m not happy with it and it has artifacts at glancing angles
Really it does need to be able to access the underlying normal surface normal, like how the scenetexture world normal node does, but the PixelNormalWS doesn’t work the same way, it’s not culling it.
Is this method RyanB spoke of not actually technically possible?
It’s not working because in deferred decals, the PixelNormalWS node returns the decal projection direction, not the normal of the pixel receiving the decal. The only way to access that is by reading the WorldNormal SceneTexture (as long as you don’t plug anything into the Normal output: a decal cannot read and write to the normal buffer).
Thanks for the update, that’s a great solution and worked really well, but the only issue is you lose the ability to have any normal information in your decal. Any way you know of that will allow you to add the normal map back in while still using SceneTexture:WorldNormal.
Yeah that is the main caveat. To do this, Unreal Engine would have to implement a decal layer system similar to what Unity has in HDRP, which would also mean that you can blend the surface normal. This solution is best for things like blood splatters, puddles etc that don’t require normal detail.