The SpeedTree SDK employs a bank of pre-compiled shaders, generated and compiled by the SpeedTree Compiler application. Using the Compiler, users import a series of tree & grass models and, by settting various LOD and effects parameters, generate a bank of shaders shared by the imported trees. Because each group of geometry and/or LOD may be unique, it's not uncommon for six to twelve shaders to be associated with a single tree model: one for each material for each LOD. This ensures that the minimal number of shader instructions are always being used to render the tree at any LOD stage. Our measurements shows that, generally, this outweighs the shader switch cost, though there are shader generation modes in the Compiler that favor fewer, longer shaders.
The shader source is firmly rooted in HLSL/Cg syntax, which is portable across the DX11, DX9, PlayStation 4, Xbox One, PlayStation 3, Xbox 360, and platforms. The source also successfully compiles using a GLSL compiler (although some extra macros are needed [and provided]), which is better suited for OpenGL-based platforms (Mac, Linux, and Windows).
The SpeedTree Compiler application will generate tree models and assets for use in a real-time environment. These assets can include:
Details on the controls and settings available in the SRT Exporter are here.
Depending on the compilation mode, the filenames of the generated shaders are like string hash keys, they're based on the render state that drove the shader generation (e.g. whether specular was enabled, LOD smoothing, transmission, per-pixel lighting, etc). It's nearly impossible for a user to read the shader filename and determine what the render state was, but if the Compiler option “Leave source” is enabled, users can open the corresponding FX shader source file and examine the #defines at the top of the file to determine the render state.