How-To: Show Shader Precompile Progress (optional)
Goal: hold the loading screen while Unreal precompiles the bundled PSO cache after a game or driver update, and show an "Optimizing shaders 42%" progress bar while it happens.
bEnableShaderPrecompileGate off, nothing below changes existing behaviour.It also needs the project to actually ship a recorded
.upipelinecache. Step 1 covers that; without it the gate correctly does nothing.1. Enable the engine's PSO systems
Turn on Share Material Shader Code in Project Settings -> Packaging, then add this to DefaultEngine.ini:
[/Script/Engine.RendererSettings]r.ShaderPipelineCache.Enabled=1r.ShaderPipelineCache.StartupMode=0r.ShaderPipelineCache.ExcludePrecachePSO=1r.PSOPrecaching=1r.PSOPrecache.Components=1[DevOptions.Shaders]NeedsShaderStableKeys=true
StartupMode=1 the precompile can begin before this plugin exists and the batch total is lost, leaving the progress bar estimated. The plugin logs a warning to LogCrimsonLoadingScreen if it sees a non-zero value.Then record a cache: run a packaged build with -logPSO, play through representative content at each scalability level, expand the recording with the ShaderPipelineCacheTools commandlet, and place the result in Build/<Platform>/PipelineCaches/ before cooking. See the plugin README for the full command.
2. Choose a gate mode
Project Settings -> Crimson -> Loading Screen -> Shader Precompilation.
| Mode | Behaviour |
|---|---|
BlockUntilComplete (default) | Hold the loading screen until the batch finishes. |
BackgroundThenBlockOnPlay | Let shaders trickle behind an interactive menu; hold only when the game asks (step 4). |
NeverBlock | Never hold. Progress is still reported if you want your own corner indicator. |
3. Show progress in the widget
Reveal your shader panel only when the state is Precompiling. Warming means work is outstanding but still inside the grace period - most boots never leave it, and the player should see nothing.
Images/CrimsonLoadingScreen/howto-shader-progress-bp.pngPrefer events over polling? Bind On Shader Precompile Progress (Progress, Remaining, Total) and On Shader Precompile Complete on the manager - both are Blueprint-assignable, with C++ multicast mirrors.
4. Block on Play (BackgroundThenBlockOnPlay only)
With that mode the screen is not held automatically. Call this from your Play button so shaders compile behind the menu but are guaranteed complete before gameplay. It is a no-op once the precompile has finished.
Images/CrimsonLoadingScreen/howto-shader-blockonplay-bp.png5. Test it without packaging
PIE always reports zero work: PSO precaching is compiled out under WITH_EDITOR and the editor never opens a bundled cache. Drive the UI with a synthetic batch instead:
CrimsonLoadingScreen.ShaderPrecompile.SimulateSecs 20
SimulateSecs to 1 instead and the panel must never appear - that is the grace period doing its job. The CVar clears itself on completion.For a real end-to-end test you need a packaged build launched with -clearPSODriverCache and r.PSOPrecache.Validation=2, then stat PSOPrecache to check Missed and Too late counts.
6. Optional: drain runtime precache before a level shows
Separate from the boot-time batch, bHoldForRuntimePSOPrecache delays the end of a level load until outstanding runtime precache requests drain, reducing first-frame hitching and material pop-in.
RuntimePSOPrecacheMinPriority at High and above. Low-priority requests are issued continuously as components register, so waiting on all of them tends never to converge. MaxRuntimePSOPrecacheWaitSecs caps the wait regardless - do not set it to 0.See also: Concept: PSO Precaching & the Grace Period for why the plugin measures instead of predicting, and Concept: Lifecycle & Show Conditions for where these two checks sit among the other conditions.