Billboard and shadow

I was asked to help with a Unreal project. That project has an issue with shadows from any tree. When the player is close to the shadow from that tree and moves around the shadow will change its shape. It becomes bigger or smaller depending on the direction you are looking.

Let me explain how trees are implemented. Each tree consists of a static mesh that represents branches and a static mesh that represents the canopy of the tree. Static mesh for the canopy has a material that replaces static mesh with many billboards that are leaves of the tree. It looks nice and easy to change because by changing the static mesh of the canopy you are changing the volume and shape of the leaves.

The billboard is something that has a normal that always points (looks) towards the camera. Typical examples of billboards are foliage, text that shows damage to an enemy, any UI, etc.

I think some of you already understand why a shadow is moving. When you move the camera, all leaves will rotate and will change their position relative to the light source. As a result, their shadow will also change.

Imagine you are looking parallel to the light source rays. In this case, a billboard will be perpendicular to the light source rays, it will block light and create shadow. But if you are looking perpendicular to the light source rays then billboards will be parallel to the light source rays and will not block light because they have no depth.

Ok, now we know what happened and we need to think about the solution. I’m not an expert in the Unreal Engine and perhaps there are better solutions but let me explain what I found.

The simplest way to fix that problem is to create another static mesh and place it in the same position as the static mesh for the canopy. Then disable casting shadows for the canopy.

This is a very simple solution but it has many drawbacks. Firstly, you need to create a duplicate static mesh and keep it in sync with the static mesh for the canopy. If you change one, then you need to change another. Secondly, it increases the amount of work. That project has a lot of trees and this fix will require a lot of work.

Lastly, the material for the canopy allows to change the position of the leaves. For example, it allows changing the distance of each leave from the canopy static mesh by changing a parameter. So the shadow static mesh needs to replicate all of this and it is quite labor intensive task.

After some time I found a nice and I would say elegant solution. I changed only the canopy material and there is no need to change any tree. The idea is that for the shadow pass we do not rotate billboards.

That material is the Shader Graph and all you need is to place the “Shadow Pass Switch” node close to the code that rotates a billboard. The “Shadow Pass Switch” has 2 inputs: “Shadow” and “Default”. The “Default” input is your regular input and the “Shadow” is the input when Unreal creates the shadow.

Take the output before the rotation code and connect it to the “Shadow” input of the “Shadow Pass Switch” node. Then connect the output of the rotation code to the “Default” input of the “Shadow Pass Switch” node. Then connect the output of the “Shadow Pass Switch” node to the place that the output of the rotation code was connected to.

Let me explain it slightly differently. Imagine you have A -> Rotate -> Result. You need to add another connection A -> “Shadow” of the “Shadow Pass Switch”. Then A -> Rotate -> “Default” of “Shadow Pass Switch”. Then connect the “Shadow Pass Switch” output to the input of the Result node.

A -> Rotate -> “Default”

A -> “Shadow”

“Shadow Pass Switch” -> Result

So, the shader will not rotate anything during shadow creation and all leaves will keep a static rotation and position, and as a result, the shadow will not change when the camera changes its direction. But all other code, for example, the code that increases the distance of each leave will still run and the shadow will reflect this.

I hope it helps someone.

Comments

Post comment