Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sr2echa/TF2-Source-Code/llms.txt

Use this file to discover all available pages before exploring further.

The Source Engine rendering pipeline in TF2 spans multiple subsystems coordinated by the view render system (view.cpp, viewrender.cpp). Each frame, the engine traverses BSP leaves for visibility, draws world geometry and decals, renders studio models with bone transforms, applies lightmaps and dynamic lights, and composites shadows and post-process effects before presenting the final image.

Render loop overview

The client-side render entry point is CViewRender::RenderView() in game/client/viewrender.cpp. It coordinates the full draw sequence each frame.
1

Visibility determination

The engine walks the BSP tree from the current camera leaf, collecting all visible leaves via the PVS (Potentially Visible Set) stored in the .bsp file. CClientLeafSystem tracks which renderable entities are in which leaves.
2

World geometry

BSP surfaces and displacement meshes are drawn via gl_rsurf.cpp. Lightmaps baked into the BSP are blended with dynamic light contributions from gl_lightmap.cpp.
3

Studio model rendering

CStudioRender (studiorender/) draws all animated models. Bone matrices are computed per-frame from the animation system in baseanimating.cpp / bone_setup.cpp.
4

Shadow rendering

CShadowMgr (engine/shadowmgr.cpp) manages projected texture shadows and blob shadows. Dynamic shadows are rendered as projected decals onto world surfaces.
5

Particle systems

The particle system (particles/) draws all active particle effects after opaque geometry, sorted by depth for correct blending.
6

Post-processing

DoEnginePostProcessing() in viewpostprocess.cpp applies bloom, color correction (via CColorCorrection), and tone mapping before the final blit.

BSP world geometry

TF2 maps compile to .bsp files using the BSP format defined in public/bspfile.h. Key structures:
// public/bspfile.h
struct dface_t
{
    unsigned short  planenum;       // the plane the face is on
    byte            side;           // faces opposite to the node's plane direction
    byte            onNode;         // 1 if on node, 0 if in leaf
    int             firstedge;      // index into surfedges
    short           numedges;
    short           texinfo;        // texture info index
    short           dispinfo;       // displacement info, or -1
    short           surfaceFogVolumeID;
    byte            styles[MAXLIGHTMAPS];   // lightmap styles
    int             lightofs;       // start of [numstyles*surfsize] samples
    float           area;
    int             m_LightmapTextureMinsInLuxels[2];
    int             m_LightmapTextureSizeInLuxels[2];
    int             origFace;
    unsigned short  m_NumPrims;
    unsigned short  firstPrimID;
    unsigned int    smoothingGroups;
};
Displacement surfaces (disp_defs.h, disp.cpp) extend flat BSP faces into terrain-like meshes used for ramps and hillsides across TF2 maps.

Studio model system

Studio models (.mdl) are rendered by IStudioRender. Bone setup is handled in public/bone_setup.cpp, which evaluates animation sequences, blends layers, and outputs a matrix3x4_t array for each bone.
// public/bone_setup.h
void BuildBoneChain(
    const CStudioHdr *pStudioHdr,
    const matrix3x4_t &rootxform,
    const BoneVector pos[],
    const BoneQuaternion q[],
    int	iBone,
    matrix3x4_t *pBoneToWorld,
    CBoneBitList &boneComputed );

Lighting and lightmaps

Baked during map compilation by VRAD. Stored in the BSP’s lighting lump and streamed into GPU textures by gl_lightmap.cpp. TF2 uses HDR lightmaps (RGBE format) where available.
Temporary point lights created via engine/dynamiclight.cpp. Used for muzzle flashes, explosions, and rocket trails. Limited to MAX_DLIGHTS (32) active at once — defined in public/dlight.h.
CProjectedTextureSystem (env_projectedtexture.cpp) renders shadow maps for dynamic shadow-casting entities. Used by the Spy’s flashlight and certain environmental effects.

Color correction and post-process

Color correction volumes (colorcorrectionvolume.cpp) blend color lookup tables (LUTs) as the player moves through map areas. The CColorCorrection system (engine/colorcorrectionpanel.cpp) applies the blended LUT in the final post-process pass.
TF2 uses the mat_hdr_level convar (0 = LDR, 1 = HDR bloom only, 2 = full HDR) to control tone mapping and HDR rendering. The default for most hardware is level 2.

Build docs developers (and LLMs) love