DirectX 5.0: How Transformed and Lit Vertices Changed Direct3D

The release of DirectX 5.0 marked a turning point for PC 3D graphics by replacing the cumbersome Direct3D Execute Buffer architecture with the streamlined DrawPrimitive API, anchored by the introduction of Transformed and Lit (TL) vertices. By providing a standardized structure for geometry that had already undergone coordinate transformation and lighting calculations, DirectX 5.0 allowed developers to bypass Direct3D's internal geometry pipeline. This architectural shift gave programmers the flexibility to write high-performance, custom CPU transformation routines, drastically reduced API overhead, and created a clean division between geometry processing and rasterization that set the foundation for the 3D accelerator revolution.

The Problem with Early Direct3D: Execute Buffers

Prior to DirectX 5.0, Direct3D Immediate Mode relied on Execute Buffers. Introduced in DirectX 2.0 and 3.0, Execute Buffers required developers to bundle vertex data, render states, and primitive instructions into a single, complex memory block before passing it to the runtime.

This model proved unpopular among game developers. Constructing and parsing Execute Buffers introduced massive CPU overhead, required difficult memory management, and made it tedious to update dynamic geometry. Most developers favored proprietary APIs like 3dfx Glide or the cleaner paradigm of OpenGL, both of which allowed more direct control over vertex submission.

The Introduction of D3DTLVERTEX and DrawPrimitive

DirectX 5.0 solved these pain points by overhauling Direct3D with the DrawPrimitive and DrawIndexedPrimitive APIs, accompanied by flexible vertex formats. At the center of this update was the D3DTLVERTEX (Transformed and Lit Vertex) structure.

In standard 3D math, a 3D point begins in local object space, undergoes matrix multiplication to transform into world, view, and screen-space coordinates, and then receives lighting calculations based on virtual light sources.

A transformed and lit vertex represented data that had already completed this entire stage:

  • Screen-Space Coordinates (\(X, Y, Z\)): The 2D viewport coordinates combined with depth information for the Z-buffer.
  • Reciprocal of Homogeneous W (\(RHW\)): A value used by hardware rasterizers for perspective-correct texture mapping.
  • Pre-Calculated Lighting: Diffuse and specular color components stored directly in the vertex, removing the need for runtime lighting computation.
  • Texture Coordinates (\(U, V\)): Mapping data ready for sampling.

Empowering Custom CPU Pipelines

During the late 1990s, dedicated 3D graphics cards handled rasterization, texture mapping, and depth buffering, but lacked hardware-level geometry processing. Transformation and lighting were handled exclusively by the host CPU.

The introduction of TL vertices meant Direct3D no longer forced developers to use Microsoft's internal matrix math and lighting algorithms. Developers could build highly optimized transformation and lighting engines on the CPU, leveraging instruction sets like Intel's MMX and later AMD's 3DNow! to manipulate vertex data at peak speeds. Once processed, the application fed the resulting array of D3DTLVERTEX structs directly into DrawPrimitive, allowing the graphics card to focus entirely on rasterization.

Architectural Legacy

By separating geometry processing from triangle rasterization, DirectX 5.0 established Direct3D as a viable, modern competitor to Glide and OpenGL. Decoupling these phases not only accelerated rendering in late-90s PC gaming, but it also defined the pipeline stages that Microsoft later formalized when hardware-based transformation and lighting arrived with DirectX 7.0 and the launch of the Nvidia GeForce 256.