Detecting Shadow Pass in Godot Shader

Detecting Shadow Pass in Godot Shader

If you want a wall to be see-through from the player's perspective but still have the wall cast a shadow within the world, it is useful to be able to detect whether a shadow pass is being done in the material shader. If you are in a shadow pass stage, you would want to return 1.0 for opacity so that the wall casts a shadow, but in the normal rendering pass, you would want to return 0.0 for the opacity so that the wall is not actually rendered.

While there is a pending proposal at this time for Godot to add a flag to allow you to reliably check if the shader is rendering a shadow pass (https://github.com/godotengine/godot-proposals/issues/4443), I came up with a workaround to detect if a shadow pass is in progress. The near-z value for the clip plane is currently always set to 0 for the shadow passes which means the value for PROJECTION_MATRIX[3][2] will always be 0 (since the numerator for that position in a perspective projection matrix is multiplied by the near-z value). So, in your shader code (or an Expression block in your visual shader), you can do the following to detect a shadow pass:

bool is_shadow_pass = PROJECTION_MATRIX[3][2] == 0.0;

This should at least work for perspective projections. Another possible way to detect the shadow pass is based on the camera position. In the shadow passes, Godot sets the "camera_position_world" built-in to the position of the light. So, you could store the actual active camera position to a global shader parameter each frame, and in your shader, you could compare the value of that global uniform parameter to the value of the "camera_position_world" built-in. If they are the same, then you are not in a shadow pass (or you unluckily have your camera in the exact same position as the light).