Light records and attenuation
Drawables and fragments carry authored light lists. Records distinguish point (1), spot (2) and capsule (4) lights and store position, colour, intensity, range, time flags, direction, cone angles and additional shadow/volume/corona parameters. Observed
The proven light-record fields below are read for every light list in the accepted version-159 YDR/YDD and version-171 YFT corpus. The whole-resource census rejects unknown light kinds, non-finite values and unexpected reserved words and reports no such failures; fifteen other-version YDR copies are excluded. Runtime placement, hour examples and CPU-to-shader mappings have separate evidence scopes. Proven · all accepted drawable resources
Light positions and directions are in the space of the bone named by bone_id. A fragment can supply its own bone
pose; otherwise the skeleton’s composed rest pose places the light in drawable space before the entity transform.
Observed
| Offset | Size | Type | Field | Confidence | Notes |
|---|---|---|---|---|---|
| 0x0 | 8 | bytes | unknown zero words | Unknown | zero in inspected records |
| 0x8 | 12 | vec3 | position | Proven | |
| 0x14 | 4 | u32 | unknown zero word | Unknown | |
| 0x18 | 3 | RGB8 | colour | Proven | |
| 0x1B | 1 | u8 | flashiness | Sourced | |
| 0x1C | 4 | f32 | intensity | Proven | |
| 0x20 | 4 | u32 | flags | Sourced | |
| 0x24 | 2 | u16 | bone tag | Proven | |
| 0x26 | 1 | u8 | kind | Proven | |
| 0x27 | 1 | u8 | group ID | Sourced | |
| 0x28 | 4 | u32 | time flags | Proven | |
| 0x2C | 4 | f32 | falloff range | Proven | |
| 0x30 | 4 | f32 | falloff exponent | Sourced | CPU mapping to shader attenuation k is unknown |
| 0x34 | 16 | vec4 | culling plane | Sourced | |
| 0x44 | 1 | u8 | shadow blur | Sourced | |
| 0x45 | 7 | bytes | unknown zero bytes | Unknown | |
| 0x4C | 4 | f32 | volume intensity | Sourced | |
| 0x50 | 4 | f32 | volume size scale | Sourced | |
| 0x54 | 3 | RGB8 | volume outer colour | Sourced | |
| 0x57 | 1 | u8 | light hash | Sourced | |
| 0x58 | 4 | f32 | volume outer intensity | Sourced | |
| 0x5C | 4 | f32 | corona size | Sourced | |
| 0x60 | 4 | f32 | volume outer exponent | Sourced | |
| 0x64 | 4 | u8[4] | light-shadow-specular-volume fade distances | Sourced | |
| 0x68 | 4 | f32 | shadow near clip | Sourced | |
| 0x6C | 4 | f32 | corona intensity | Sourced | |
| 0x70 | 4 | f32 | corona Z bias | Sourced | |
| 0x74 | 12 | vec3 | direction | Proven | |
| 0x80 | 12 | vec3 | tangent | Proven | |
| 0x8C | 4 | f32 | inner cone angle | Sourced | |
| 0x90 | 4 | f32 | outer cone angle | Sourced | |
| 0x94 | 12 | vec3 | capsule extent | Sourced | |
| 0xA0 | 4 | u32 | projected texture hash | Sourced | |
| 0xA4 | 4 | u32 | unknown zero word | Unknown |
The low 24 time-flag bits select hours; a zero hour mask means always on in the documented light interpretation.
Sampled street lamps carry 0xF0003F, selecting 00–05 and 20–23. Their emissivenight lamp-head materials are also
dark by day; Prop_StreetLight_head has EmissiveMultiplier 16. Observed
Night therefore has three hour-keyed parts: light records by their time flags, emissive night materials, and night-only geometry that its vertex shader collapses by day. Observed
Shader window
Section titled “Shader window”Executing the sampled point-light and directional-light pixel programs under Microsoft WARP confirms that their
diffuse terms share a global scale G: point lighting uses G * colour * intensity * window * albedo * NdotL,
while sunlight uses G * sun * albedo * NdotL. The point-light radial window is s / ((1-k)*s + k), with
s = saturate(1 - d²/R²). This is evidence for these compiled programs and tested inputs. Proven · WARP execution
The programs are PS_pointCM_standard_6a549d93 (variant 0) and PS_directional_just_dir_789981ad. Over 112 point
and 20 sun cases, the formulas match the executed programs to a relative error of at most 1.5e-7. Neither has a
1/π, a factor of two or an exposure term; the albedo they read is the square root stored in the
G-buffer, squared. Proven · WARP execution
| Constant | Meaning in the point-light program | Confidence |
|---|---|---|
lighting_locals (cb9, space 1) row 3 xyz |
Light colour | Proven |
lighting_locals row 3 w |
Intensity I |
Proven |
lighting_locals row 4 z |
1/R² |
Proven |
lighting_locals row 7 x |
Falloff scalar k |
Proven |
misc_globals row 14 z |
Global scale G, shared with the sun program |
Proven |
The shader window is not inverse-square attenuation. CodeWalker’s renderer uses a different curve,
(1-d)/(1+k*d²), which does not establish the game’s compiled shader response. Observed · shader disassembly
The CPU mapping from falloff_exponent to shader k, the absolute photometric units and any CPU intensity scale
are unresolved. Shader execution establishes the constant-to-pixel equation, not those upstream mappings. Unknown
The stored exponents range from 8 to 256 over the 107 lights of the Legion Square area. Observed The mapping
matters: at half the radius the window is 0.75 / (0.75 + 0.25k), so with k equal to the exponent, lights of
exponent 8, 32 and 64 are 2.75, 8.75 and 16.75 times dimmer there than with k = 1. Inferred