Decal Texture Alpha based on object normals

Hello guys, I searched the Forum and tried to work on this subject focusing on the “display normals” shader inside the official Unity Manual, buy I couldn’t yet reach the desired result.
It would be great if someone could address my doubts :slight_smile:

Basically my problem is this one:
I wrote a vertex shader, for which -among other things- I have an object with its main texture (in the image below, the black color represents the main texture). This shader has also a decal texture (in green above). To achieve the result shown, decal texture owns its “alpha channel”. That would be good, except that I have hundreds of these objects, and not all of them are spheres. This means that, with the current method based on alpha channel, I should create hundreds of textures with proper alpha channel.
I think that this alpha value could be extrapolated from the objects normals: no matter the shape, infacts, what I want is decal value to be max when normals points in the upward direction, and to be 0 when it points on the bottomward direction. (Well, I also see that the sphere on the left should have a -1:1 range instead of the depicted 1:0 range :hushed:).
My question is: is there a way to pick the normalized vertical component of each normal in my object, and assign an alpha value to decal texture based on its value, in a vertex shader?
I am grateful to you for your help, as always :smile:
Thank you in advance to whom will even just read these lines :slight_smile:

The answer to your question is … yes?

I have the question mark there because what you want to accomplish is relatively trivial, but the way you’re describing it isn’t quite how it works.

The simple version is you can pass the world normal of the object from the vertex shader to the fragment shader, and use that value to adjust the alpha. I don’t really understand how you’re applying the decal though. Are you using projectors, deferred decals of some kind, or a surface shader with a decal texture property? Exactly how you’d accomplish this (ie: how you get world space normals) differs slightly for each of these.

In the end though it’s going to be simply:
fixed decalAlpha = saturate(worldNormal.y);

1 Like

OMG! Thank you very very much Bgolus. What I wanted to achieve is the very thing you described. It’s amazing how uneducated I am when it comes to shader.
Well what I have is exactly what you described. Following your example, In vert shader I grab world normals, and in the fragment shader use that line of code you wrote and… puf I obtained what I needed!
I owe you a cup of coffee, mate :smile: <3