Godot’s dynamic lighting system produces real-time shadows that update as lights, objects, or cameras move, using shadow mapping to calculate which surfaces are in shadow. You enable them by setting a Light node’s shadow_enabled property to true and configuring the shadow filter mode on the Project Settings or the light itself. This article explains how dynamic shadows work in Godot 4, how to configure them, common pitfalls, and how they compare to baked lighting.
Formula
The calculator above is unrelated to Godot; it’s a pace calculator for runners. The formula for average pace is pace = total_time / distance, where total_time is in minutes and distance is in kilometers. The average speed is speed = distance / (total_time / 60), giving kilometers per hour.
Worked Example
Enter a finish time of 50 minutes and a distance of 10 km. The pace is 50 / 10 = 5.00 min/km. The speed is 10 / (50/60) = 12.00 km/h. The calculator outputs these values with two decimal places.
How Dynamic Shadows Work in Godot
Dynamic shadows in Godot are generated by rendering the scene from the light’s perspective into a depth texture (shadow map). Each texel stores the distance to the nearest surface. When rendering the main view, each fragment is projected into the light’s space and compared to the depth map; if the fragment is farther away than the stored depth, it’s in shadow. This happens every frame, which is why dynamic shadows are more expensive than baked lighting.
Godot 4 supports two shadow mapping techniques: PSSM (Parallel Split Shadow Maps) for directional lights and dual-paraboloid or cube map for omni and spot lights. PSSM splits the camera frustum into multiple depth ranges, each with its own shadow map, improving quality for large outdoor scenes.
Enabling and Configuring Shadows
To enable shadows on a light node (e.g., DirectionalLight3D, OmniLight3D, SpotLight3D):
- Select the light node in the Scene dock.
- In the Inspector, find the
Shadowsection and checkEnabled. - Adjust
Shadow Filter(PCF5, PCF13, etc.) for softer or sharper edges. - For directional lights, set
Directional Shadowproperties:Max Distance,Split 1,Split 2,Split 3to control the PSSM splits.
You can also set the default shadow filter globally in Project Settings under Rendering > Lights & Shadows > Shadows. The default is PCF5, which gives a moderate soft edge. PCF13 is higher quality but slower.
Performance Considerations
Dynamic shadows are GPU-intensive. Key factors that affect performance:
- Shadow map size: Larger maps (e.g., 4096) give sharper shadows but use more memory and fill rate.
- Number of lights with shadows: Each shadow-casting light requires an extra render pass.
- Shadow distance: For directional lights, reducing
Max Distancelimits the area that receives shadows, improving quality and speed. - Filter quality: Higher PCF levels blur more but cost more.
For mobile or low-end devices, you may need to reduce shadow map sizes or disable shadows on distant lights.
Common Problems and Solutions
Here are frequent issues with dynamic shadows in Godot:
- Shadow acne: Dark spots or stripes on surfaces. Fix by increasing
Bias(e.g., 0.1) or enablingNormal Bias. - Peter-panning: Shadows that detach from the object. Reduce
Biasor adjustNormal Bias. - Shadows flickering: Often caused by Z-fighting or too low shadow map resolution. Increase map size or adjust near/far planes.
- Shadows not appearing: Ensure the light has
Shadow Enabled, the material shader supports shadows, and the object is in the shadow distance.
For directional lights, if shadows disappear when the camera moves, check the Max Distance – objects beyond that distance won’t cast or receive shadows.
Dynamic vs. Baked Shadows
Dynamic shadows are real-time and adapt to moving lights and objects, but they cost performance. Baked shadows (via lightmaps or baked GI) are precomputed and look static, but are much cheaper at runtime. Use dynamic shadows for moving characters, interactive lights, or day-night cycles. Use baked shadows for static environments to improve performance.
Godot 4 supports both, and you can mix them: bake lightmaps for static geometry and keep dynamic shadows for dynamic objects. This hybrid approach is common in games.
Frequently Asked Questions
How do I make shadows softer in Godot?
Increase the Shadow Filter quality on the light (e.g., from PCF5 to PCF13) or increase the shadow map size. Softer shadows can also be achieved by increasing the filter size, but this costs performance.
Why are my shadows blocky or pixelated?
Blocky shadows are due to a low shadow map resolution. Increase the Shadow Map Size (e.g., from 1024 to 2048 or 4096) on the light. For directional lights, also reduce the Max Distance to concentrate the map on a smaller area.
Can I have shadows on only some objects?
Yes. Set the Cast Shadow property on a GeometryInstance3D (like MeshInstance3D) to Off to disable shadow casting, or Shadow Only to make it cast shadows but not be visible. Also, Receive Shadow can be disabled per object.
Do dynamic shadows work with Shader Materials?
Yes, but the shader must include the shadow calculation. The standard spatial shader handles it automatically. If you write a custom shader, you need to use the shadow() function or include the SHADOW_ATTENUATION built-in.
What is the best shadow filter setting for performance?
PCF5 is a good balance between quality and speed. PCF13 looks better but is slower. For the best performance, you can disable filtering entirely (Hard) but that gives jagged edges.