Simple shadow catcher
A simple shadow catcher shader that can be used to add stylized shadows to a scene. You apply it to a mesh (typically a ground plane) and it will be fully transparent except for where there are shadows.
The shadows can be assigned any color, and an opacity multiplier. Multiple overlapping shadows will be added together, but you can set a maximum opacity to control how much (or at all) overlapping shadows will increase the opacity.
The shader uses the ATTENUATION property in the light calculation and applies it to the material ALPHA transparency. This which includes information on if a fragment is in shadow, but also falloff for sportlights and omnilights. So if you want to use this shader with shadows for those light types you need the sett the attenuation for the falloff very low and the range very high to avoid catching this light falloff as a shadow. Also, since the material becomes transparent you might need to take care with sorting if you render other transparent materials in the scene.
Shader code
shader_type spatial;
uniform vec3 shadow_color: source_color; //Color of the shadow
uniform float shadow_opacity: hint_range(0, 1); //Opacity multiplier of the shadow
uniform float shadow_max_opacity: hint_range(0, 1); //Maximum opacity of overlapping shadows
void fragment() {
// simple single color albedo.
ALBEDO = shadow_color;
// start with 0 alpha so we can add multiple light shadows together in light()
ALPHA = 0.0;
}
void light() {
// unshaded lighting
DIFFUSE_LIGHT = ALBEDO;
// add alpha based on attenuation, which includes if we're in shadow, cap at our max opacity
ALPHA = min(ALPHA + shadow_opacity*(1.0 - ATTENUATION), shadow_max_opacity);
}