.LMP -- Terrain Grayscale Lightmap

1. Architectural Role & Engine Purpose

The LMP (Lightmap File) format stores precomputed static lighting intensity and building shadow masks for outdoor terrain in Project I.G.I. 1.

LMP files encode pre-baked sunlight illumination and mountain cast shadows as an 8-bit grayscale grid. This allowed the year-2000 engine to render realistic sunlight transitions and shadowed forest valleys without requiring any runtime dynamic shadow casting from the GPU.

2. Binary File Layout & Memory Map Diagram

An LMP file contains lightmap dimensions and sun vector metadata, followed by an 8-bit intensity raster:

LMP LIGHTMAP — 8-BIT TERRAIN SHADOW MASK LAYOUT 0x00: Lightmap Header & Sunlight Vector (28 Bytes) 28 BYTES Magic "LMP " | Width, Height | World Scale (meters/pixel) | Sun Direction Vector XYZ | Ambient Base Light magic[4], width, height, world_scale, sun_dir[3], ambient_base 8-Bit Grayscale Shadow Intensity Buffer (Width * Height Bytes) 8-BIT GRAYSCALE Contiguous byte array of illumination intensities: 0x00 = Full Shadow, 0x80 = Neutral, 0xFF = Direct Sunlight Precomputed radiosity & mountain shadow attenuation masks without dynamic shadow overhead

3. Multi-Texture Terrain Shading Pipeline Diagram

During terrain rendering, the engine binds the LMP buffer to Direct3D Texture Stage 1 for multiplicative modulation:

LMP LIGHTING — MULTI-TEXTURE MODULATE2X PIPELINE 1. TERRAIN SETUP • Load Terrain Quad • Bind Diffuse Surface • Prepare D3D7 Pipeline 2. STAGE 0: COLOR • SetTexture(0, Diffuse) • Grass / Dirt / Rock • ColorOp: SELECTARG1 3. STAGE 1: LIGHTMAP • SetTexture(1, Lightmap) • ColorOp: MODULATE2X • Diffuse * Lightmap * 2 4. FRAMEBUFFER • Realistic Shadows • Sunlit Highlights • Zero Runtime GPU Rays

4. Architectural Mechanics & Engine Implementation Details

The 8-bit LMP lightmap format solved the harsh lighting limitations of early Direct3D hardware:

  • D3DTOP_MODULATE2X: By using the 2X multiply blending stage, the lightmap value of 128 represented neutral lighting, values below 128 represented shadowed terrain, and values above 128 represented bright specular highlights.
  • Zero Memory Waste: Because color was already supplied by the diffuse terrain textures, storing lightmaps in 8-bit grayscale reduced VRAM consumption by 75% compared to 32-bit RGBA lightmaps.

5. C++ Struct Definitions

#pragma pack(push, 1)
struct LmpHeader {
    char     magic[4];       // "LMP "
    uint16_t width;          // Lightmap horizontal resolution
    uint16_t height;         // Lightmap vertical resolution
    float    world_scale;    // Meters per lightmap texel
    float    sun_dir[3];     // Sun direction vector
    float    ambient_base;   // Minimum ambient illumination (0.0 - 1.0)
};
static_assert(sizeof(LmpHeader) == 28, "LmpHeader must be 28 bytes");
#pragma pack(pop)