Precompiling shaders – ShiVa Engine

Precompiling shaders

Usually, the engine is generating shaders (either vertex or pixel/fragment) on the fly, depending on the materials your are using, the dynamic lights count, and many other factors. Each time a shader is generated, depending on the driver (and the shader complexity), that can produce a slight (or bigger) stall.
When your game seems to stutter and you can see something like

[o Message ] {Rendering }Created generic fragment program : 0x0000000200000100 (ALUIns:17, TEXIns:0, TEXInd:1, Par:5, Att:2, Tmp:5)
[o Message ] {Rendering }Created generic vertex program 7 : 0x0000000000000100 (Ins:20, Par:8, Tmp:4, Mat:0)

in the console window, you should think about precompiling your shaders.
When targeting some platforms with fixed hardware (eg. consoles), this can be done offline, using the UAT. But when targeting any other platforms (eg. mobiles/desktops), you have to do that at loading time.

How to “pre-build” shaders

There are 2 types of shaders: vertex shaders, and fragment/pixel shaders
There are 2 categories of shaders: “generic” shaders, and “special” shaders
Each vertex or fragment/pixel shader the engine creates has a unique 64bits ID
Let’s take the example from above: We want to avoid the runtime stalls resulting from the generation of:
– a generic fragment program with the ID 0x0000000200000100
– a generic vertex program with the ID 0x0000000000000100
We can fix that by putting the following line in some onInit handler at game start:

debug.compileShaderList ( "G0000000200000100.fps G0000000000000100.vps" )

This will force the engine to generate the shaders. The syntax is the following:

  • the separator is the space
  • each shader starts with either ‘G’ (for ‘generic’) or ‘S’ (for ‘special’)
  • each shader then has the hexadecimal ID, without the ‘0x’
  • each shader finally has the extension ‘.vps’ (for vertex shaders) or ‘.fps’ (for fragment shaders)

Recommended Procedure

  • Play the game on the target device, trying to launch every effect/model/power/option.
  • Once done – but in the same ‘session’ – call debug.getCompiledShaderList (put the call under a debug button).
  • Store the resulting string in an XML file, or just log it.
  • Finally, re-inject this list in your game sources, generating for instance 10 shaders per frame during the startup sequence

Need more answers?

  • slackBanner