Optimization of Dynamic Shadows for Mobile Devices
We often see projects where a mobile GPU with Shadow Map at 2048×2048 resolution without cascades is a direct path to 18 ms on the framebuffer for the shadow pass alone. On Adreno 640, this consumes the thermal budget before the main geometry is even processed. Shadows on mobile are not "set and forget" — it's a constant trade-off between visual quality and thermal limits. We evaluate your project and offer a turnkey solution in 2–4 days.
Why default Unity Shadow Distance settings kill performance on mobile
The most common mistake is leaving Shadow Distance at the default (150 m) and using Hard Shadows in URP without cascading. The GPU then renders a shadow map for all visible geometry in the scene, including objects 80 meters away that the player will never get close enough to appreciate the shadow.
A second classic case is using Realtime GI with Enlighten on mobile together with dynamic shadows. Enlighten recalculates lightmaps every time a light source moves, which on Mali-G72 with 4 cores causes constant drops to 24 FPS during lighting zone transitions. The solution is to move all static objects to Mixed Lighting with Subtractive Mode and keep Realtime only on characters.
Cascaded shadows (Cascade Shadow Maps) on mobile also require care. Two cascades instead of four at distances 8/40 m instead of 10/30/60/150 m give a noticeable performance gain. Shadow Bias must be set manually per scene — URP's automatic value often causes Peter Panning on flat surfaces due to the mobile depth buffer (16-bit on many devices).
What stack we use for shadow optimization
We work in Unity URP with Custom Renderer Feature. Main tools — Frame Debugger, GPU Profiler module in Unity Profiler, Snapdragon Profiler, and Mali Graphics Debugger for device data capture. Proper configuration of shadow cascades can reduce GPU load by up to 60%.
The process starts with capturing a baseline: FPS, GPU time, Shadow Caster Draw Call count. On a typical project with 300+ objects in the scene, the Shadow Caster Pass yields 180–220 draw calls — half the recommended budget for mobile (400 total).
Further work:
- Move small static objects (rocks, curbs, decorations) to Shadow Static — they go into the static Shadow Atlas and are not redrawn each frame.
- For characters and dynamic objects, use Screen Space Shadows instead of Shadow Map where scene depth allows (works on Vulkan/Metal).
- Configure Shadow Fade Distance with a smooth transition to Blob Shadow (projected texture shadow) beyond 15 m — visually imperceptible, minimal cost.
- On tile-based GPUs (Adreno, Mali), enable Early-Z Culling through correct Render Queue sorting: opaque geometry first, transparent last.
For VR projects on Quest 2/3, there's a separate story — Multiview Rendering (single-pass stereo) renders the Shadow Map once for both eyes. But if the scene has Shadow Caster objects with different Culling Masks for the left/right eye, the Shadow Pass splits into two independent passes, immediately adding +8–12 ms. This is a bug trap invisible in Editor. Solution — unify Culling Masks for shadows.
How to configure Shadow Map for stable 30 FPS on mobile
Step-by-step plan for a typical project:
- Create a new URP Asset for mobile: disable Soft Shadows, reduce Shadow Resolution to 1024.
- Set Shadow Distance to 30–50 m, use 2 cascades with 60/40 distribution.
- For static objects, apply Baked Lightmap via Mixed Lighting.
- For dynamic objects, enable Screen Space Shadows. If the device doesn't support it (OpenGL ES 3.0), manually implement Blob Shadow for objects farther than 15 m.
- Check
Render Queue: opaque objects (Geometry) should render before semi-transparent (Transparent). This activates Early-Z Culling.
This method saves up to 60% GPU time compared to full Shadow Map — the difference is visible in tests: regular shadow map on Quest 2 gives 62 FPS, while Screen Space + Blob gives 71 FPS with less heat generation.
What is included in the work: stages and deliverables
Scene audit. Collect data from the target device via ADB + Unity Profiler: Shadow Caster Count, GPU Shadow Pass Time, thermal throttling over 5 minutes of load. Includes: a report with baseline measurements and recommendations.
Technical specification. Based on audit results, determine what can be converted to Baked, what stays Mixed, and what Shadow Distance is realistic for that project's gameplay. You receive a work plan document.
Implementation. Configure URP Asset, Renderer Feature, Culling Groups for LOD shadows, write a custom Shadow Caster Pass if the standard one doesn't cover needs (e.g., for vegetation with Alpha Cutout). Includes: project configuration, custom pass code, integration into your pipeline.
Hardware testing. Run on at least three devices from the target matrix: low-end (Snapdragon 665), mid (Snapdragon 778G), high-end (Snapdragon 8 Gen 2). Thermal throttling test — 15 minutes of continuous game session. Includes: test report.
Profiling and final iteration. Compare with baseline, additional Blob Shadow fallback pass if needed. Get in touch to evaluate your project in 1 day. Our experience: 5+ years in mobile graphics, 50+ successful projects with Unity URP.
How to optimize shadows on VR devices?
For VR (Quest 2/3), we use single-pass stereoscopic rendering, which halves the Shadow Pass. But the key is to avoid Shadow Pass duplication due to different Culling Masks. We also apply Screen Space Shadows for the near plane (up to 10 m) and Blob Shadows for distance. This yields stable 72 FPS without thermal throttling.
Comparison of approaches:
| Method | FPS on Quest 2 | GPU Time | Quality |
|---|---|---|---|
| Cascade Shadow Maps (4 cascades) | 58–62 | 16–18 ms | High |
| Cascade Shadow Maps (2 cascades) | 68–71 | 10–12 ms | Medium |
| Screen Space + Blob Shadow | 71–72 | 6–8 ms | Acceptable |
Our engineers configure the optimal balance for your specific project. Contact us for a consultation.
How to check Shadow Pass time on the device
1. Launch Unity Profiler connected to the device via ADB. 2. Enable the GPU Profiler module. 3. Filter by "Shadow" or "ShadowCaster". 4. Compare GPU time against budget (16.6 ms for 60 FPS).| Task Scale | Estimated Timeline |
|---|---|
| Audit + basic URP setup (1 scene) | 2–4 days |
| Full shadow optimization (3–5 scenes) | 1–2 weeks |
| VR project with Multiview + custom Renderer Feature | 2–4 weeks |
Cost is calculated individually after project audit and requirements analysis.
Typical mistakes we see in projects
Not setting Render Shadow Maps per-object — all objects render Shadow Map regardless of distance from camera, even though distant objects can be removed via ShadowCastingMode.Off at LOD2 level.
Using Light.shadowCustomResolution = 4096 in a script without checking SystemInfo.graphicsMemorySize — on budget phones with 2 GB RAM, this guarantees a crash on low memory.
Mixing MSAA x4 with Dynamic Shadows on the same Render Target on older Mali — the driver falls back to software, FPS drops 2–3 times. On those devices, you must force MSAA x2 or disable via QualitySettings.antiAliasing.
Get a consultation — we will analyze your project and provide solutions. Order a free audit.





