Unity: Aimers shader

Hello friends, this will be the first slightly more technical blog. I will show you a simple shader trick you can use for your world space GUI elements. This blog is very basic and meant for people that have little to no experience with writing Unity shaders.

oldshaderSome days ago I noticed that our in game aimers (picture on the right) have a few problems. Noticeably that they get hidden by things that are in front or above them, because of this I also had to position them a bit above the ground to prevent them from being hidden by the floor. That meant that there was also a slight offset between where the aimer was at and your exact aim position, which is unacceptable.

We want our aimers to show the exact aim position, which means they need to be at the same height as the floor. We also want our aimers to be rendered on top of everything so that we can always see exactly where we are aiming.

How to do this? After some Google searching and testing I made the folowing shader:

newshaderYou can see the same picture as before with the new shader on the right. The shader is very basic. It only renders the object with a texture on top of everything. But that is exactly what we needed.

Lets go through the important bits. The base for my shader was the Unitys default new unlit shader, which gives us preety much all of the code above. We only had to change a few settings, namely the ZTest, the Queue tag and the Blend option.

Line 48: The Queue is the order in which an object should be rendered. Queue can be any positive integer number, but there are some predefined “layers”.

  • Background (1000): background and skyboxes
  • Geometry (2000): default for normal solid objects
  • Transparent (3000): transparent materials (glass, fire, water, …)
  • Overlay (4000): image effects and GUI objects.

For our shader we used “Overlay+100” which means 4100, or in other words, after pretty much everything.

Line 54: ZTesting is done by the GPU to determine which object is the closest to our camera at that pixel, so that it doesn’t need to render everything that is below. ZTest Always means that this object should always be rendered.

So combining these two settings. We will ALWAYS render our aimers (even if they are obscured) AFTER rendering everything else, which in the end means that we will always see our aimers. We can now also place them exactly on the floor without any occlusion problems.

Line 55: A simple alpha blend to add transparency to our aimers.

Hope this trick will be helpful to someone and as always feel free to ask questions, comment or give suggestions below.



Leave a Reply

Your email address will not be published. Required fields are marked *