User Tools

Site Tools


CPU Side

Some management on the CPU side is necessary for the standard SpeedTree shaders to function correctly. In a nutshell, the CPU is used to compute and upload a series of constant buffers shared by the vertex and pixel shaders. In the shader source templates, these constant buffers are defined in Template_Uniforms.fx (this file contains multiple definitions to accomodate various platforms), and ShaderConstantBuffers.h in the C++ source. If the SpeedTree SDK is bypassed but the shaders are used, there are essentially four areas that need to be addressed (some of which can be skipped if the related system is bypassed) in the C++ code:

  • Geometric Behavior: In addition to the standard modelview/projection matrices, geometry is also affected by u_mCameraFacingMatrix which correctly orients the facing leaf geometry. Finally, per-instance, there are two floats that govern the LOD scalars in the 3D vertex shaders (e.g. control small branches scaling in/out as the camera moves): one that represents the overall LOD value of the instance, and another that represents the percentage between discrete LOD states. More on LOD and these two values here.
  • Wind: The CWind class, contained in the Core library, computes all the constants needed for wind behavior that accurately reproduces the wind effects shown in the SpeedTree Modeler application. It essentially encapsulates the wind state machine for a single SRT file. CForestRI::WindAdvance() and CTreeRI::UpdateWindConstantBuffer(), in the Render Interface library, details how these shader constants are queried from the CWind class and uploaded to the wind constant buffer.
  • Materials: The SRenderState structure, defined in the Core library, contains all of the materials and state definitions needed for the different tree geometries. Most of the values it houses are uploaded via a series of CRenderStateRI::Bind*() functions. Note that CRenderState is derived from SRenderState.
  • Billboards: Billboards primarily need a table of texcoords to be used per base tree. These texcoords, stored in u_avBillboardTexCoords, are used to extract the correct view of a given instance from the billboard atlas. The SBaseTreeCBLayout constant buffer contains other parameters needed to round out the billboard rendering system.

ShaderConstantBuffers.h

ShaderConstantBuffers.h, in the RenderInterface library, is the central database of uniform shader constants across all platforms. This header file defines a number of structures and platform-independent constant buffers shared by both the vertex and pixel shaders. These are the same constant buffers declared in the shaders, found in Include_Uniforms.fx and their precise agreement is critical.

In the SpeedTree SDK, structres like SFogAndSkyConstBuf are set up from a base class to handle synchronizing with the shader-side constant buffer (see CShaderConstantBufferRI in [SpeedTree SDK 7]\Include\RenderInterface\GraphicsApiAbstractionRI.h for full details). That is, users are free to assign values in the structure, but it will also handle syncing to the shaders. Functions that facilitate this, part of every constant buffer declaration in the SDK, include:

  • CShaderConstantBufferRI::Init(): Parameters include a register index, corresponding to the constant buffer index declared in the shader syntax. The preset register indices are declared at the top of ShaderConstantBuffers.h as macros ST_CONST_BUF_REGISTER_* and again at the top of Include_Uniforms.fx. These must remain in sync.
  • CShaderConstantBufferRI::Update(): Copies the CPU-side values to the GPU-side constant buffer.
  • CShaderConstantBufferRI::Bind(): Binds the current constant buffer to the register supplied to Init(). This is helpful and efficient when there are multiple constant buffers but only a single register. For example, every base tree has a set of shader values declared in struct SBaseTreeConstBuf (e.g. LOD values, etc). When a new base tree is being rendered, its local copy of SBaseTreeConstBuf is simply bound. No need to update or copy values from the CPU to GPU. This is the key to one of the optimizations made for 7.0.
  • CShaderConstantBufferRI::SetTexture(): The texture functions that were resident in CShaderConstantRI in 6.3.x are now housed in CShaderConstantBufferRI in 7.0.