Occlusion Masking

This will be a dev-focused post after some requests were made over how I implemented this.

A few videos of the feature are below:

The idea is to occlude foliage such as trees or leaves when the player passes behind them. This means the player never loses sight of their character and gameplay is not disrupted.

I will outline roughly how I achieved this effect. I am making the game with UE4 and as such will use specific terms, but the concept should translate to Unity or wherever else. The idea is fairly simple: to have a material function that creates a cylindrical mask at a starting point of the camera position, and extending forwards to N point.

Here is an image of the material function:

Bits of this may not be applicable to your specific scenario, so I will roughly explain which parts do what.

In the top left we have two inputs, one is the world position of the material we are applying this to, and another is the current camera position. Each of these are transformed into two dimensions and inserted into a Sphere mask, which is then inverted to ensure we have a “cutout” rather than the opposite. This alone would achieve a cutout effect and you could insert that into the output and be done with it.

In my game, I only wanted this cutout to extend so far. I only wanted it to take effect on things that were between my player and the camera, and not extend forever forwards. As a result, I have added a few extra nodes. You can see I get the distance between the two inputs by subtracting and using abs, getting the length of the vector, and inserting this into an if statement. I then have a global parameter collection that contains the distance between the player and the camera.

Again, this may not be necessary depending on usecase. However, the player in my game is able to zoom the camera in and out, and I want to make sure that doesn’t break this effect. So, the if statement on the right simply checks to see if the distance between our two points exceeds our preset value, and then either applies the mask or returns a fully white mask to ensure no opacity is applied if the object in question is “behind” the character.

The bottom nodes are me adding a noise effect to make the circle a little more interesting and “melted” looking, as you can see in the second gif. This isn’t required and again, you can apply at leisure or pile on other effects and multiply your eventual mask by them to see differing results.

The last thing that needs to be done is to simply open your desired material and apply this material function for the “opacity mask” node. You will need to set the shader type to “masked” if you haven’t already for this to take effect.

Let me know if this has been helpful or if you require any help, and please show off anything interesting you make using this effect!

Disclaimer: I am not a shader expert, so if there are more efficient ways of achieving this effect, please alert me as soon as possible 🙂