Lights (Metroid Prime)
The lights section in Metroid Prime areas defines several different types of lights: local ambient, directional, spot, and custom. Every light type has the same structure in the file; however, different types are utilized in different ways by the engine.
This file format is almost completely documented Lights are mostly figured out; the remaining unknowns are very likely unused, because the game's code never accesses them or passes them to the main light class, but it would be good to have some double-checking. There's also more unknowns in the Prime 3 lights format that probably -are- used. |
Format
The header for the light section is extremely simple and consists of the magic value 0xBABEDEAD
. It's then followed by two arrays of lights, each preceded by a light count.
Metroid Prime 1/2
Each light is a 0x41-byte struct. Note that the same structure is used for every light type, but not every value is used by every type; in fact, some of them aren't used by any of them.
Offset | Type | Description | Notes |
---|---|---|---|
0x0 | long | Light Type | |
0x4 | float3 | Light Color | There is no alpha component. |
0x10 | float3 | Position | |
0x1C | float3 | Direction | |
0x28 | float | Multiplier | Color multiplier for local ambient, used to calculate attenuation coefficients for spot/custom |
0x2C | float | Spot Cutoff | |
0x30 | float | Unknown | Possibly unused |
0x34 | bool | Unknown | Possibly unused |
0x35 | float | Unknown | Possibly unused |
0x39 | long | Falloff Type | Possible values: 0 - Constant; 1 - Linear; 2 - Quadratic |
0x3D | float | Unknown | Possibly unused |
0x41 | End of light |
Metroid Prime 3
Prime 3's light format is very similar, but there's a number of new fields introduced (most of which are currently unknown).
Offset | Type | Description | Notes |
---|---|---|---|
0x0 | long | Light Type | |
0x4 | float4 | Light Color | This color does have an alpha component, unlike Prime 1 lights. |
0x14 | float3 | Position | |
0x20 | float3 | Direction | |
0x2C | float3 | Codirection | The light's up vector |
0x38 | float | Multiplier | Color multiplier for local ambient, used to calculate attenuation coefficients for spot/custom |
0x3C | float | Spot Cutoff | |
0x40 | float | Unknown | |
0x44 | bool | Unknown | |
0x45 | float | Unknown | |
0x49 | u32 | Falloff Type | |
0x4D | float | Unknown | |
0x51 | float | Unknown | |
0x55 | float | Unknown | |
0x59 | float | Unknown | |
0x5D | float | Unknown | |
0x61 | u32 | Unknown | |
0x65 | End of light |
Light Types
The first value in each light is a type value. These are the possible values:
Type | Name |
---|---|
0x0 | Local Ambient |
0x1 | Directional |
0x3 | Spot |
Other | Custom |
Note that although the game supports point lights, those can't be set through the MREA files; custom lights are used for omnidirectional lights.
Light Functionality
Local Ambient
Ambient lights represent the brightness/color of an area in the absence of any regular lights. There's typically one of these per area; it's not known how they interact if there's more than one. For ambient lights, the color is not used directly; it's multiplied by the Multiplier value and then clamped between 0 and 1, and the result is used as the ambient color.
Directional
Directional lights are lights that have a constant direction for every vertex in the scene. Since GX doesn't have any built-in functions for handling directional lights, the way the game implements this is by taking the light's direction, inverting it, and then multiplying it by 1048576; the result is used as the light's position.
Spot
Spot lights shine in a specific direction from a specific position. Distance attenuation is calculated the same way as with custom lights. For angular attenuation, this is calculated using the spot cutoff parameter. The cutoff value from the file is halved and converted from degrees to radians, and the cosine of the result is calculated. Then the angular attenuation coefficients are calculated as:
(0.0, -CosCutoff / (1.0 - CosCutoff), 1.0 / (1.0 - CosCutoff))
Custom
While the other light types only use a couple of the value to generate lights out of what's essentially a preset setup, custom lights allow for much greater control and customization of the light properties. They're commonly used to represent omnidirectional lights; as such they're by far the most common light type in the game. For attenuation, angular attenuation is set to (1.0, 0.0, 0.0). Distance attenuation is calculated differently depending on the falloff type.
Each falloff type will set one distance attenuation coefficient, with the other two set to 0. For each type:
- 0: Constant: Coefficient A is set to
2.0 / Multiplier
- 1: Linear: Coefficient B is set to
250 / Multiplier
- 2: Quadratic: Coefficient C is set to
25000 / Multiplier