Difference between revisions of "Lights (Metroid Prime)"

From Retro Modding Wiki
Jump to: navigation, search
(Metroid Prime 3)
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
The '''Lights''' section in Metroid Prime areas defines several different types of lights: spot, point, directional, and custom. The exact behavior for each type of light is not entirely known, however they all use the same struct. The only difference is how they're utilized by the engine.
+
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.
  
{{research|3|Need to research meaning behind remaining unknowns}}
+
{{research|minor|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.}}
  
 
__TOC__
 
__TOC__
  
 
==Format==
 
==Format==
The header for the light section is extremely simple and consists of the magic, <code>0xBABEDEAD</code>, followed by two arrays of lights, preceded by their count.
+
 
===Light===
+
The lights section has a very brief header consisting of the magic value <code>0xBABEDEAD</code>. It's then followed by a number of '''light layers'''. Each light layer consists of a count value, then an array of lights. Each layer represents a separate set of lights; actors can choose with set they're lit with through an object property in LightParameters. The number of light layers is static, but it varies from game to game; Prime 1 and 2 can have up to two light layers, while Prime 3 can have four.
Lights are a 0x41 byte long struct and consists of the following:
+
 
 +
=== 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.
 +
 
 
{| class="wikitable"
 
{| class="wikitable"
 
! Offset
 
! Offset
 
! Type
 
! Type
 
! Description
 
! Description
 +
! Notes
 
|-
 
|-
 
| 0x0
 
| 0x0
 
| long
 
| long
 
| '''Light Type'''
 
| '''Light Type'''
 +
|
 
|-
 
|-
 
| 0x4
 
| 0x4
 
| float3
 
| float3
| '''Light Color'''
+
| '''Color'''
 +
| There is no alpha component.
 
|-
 
|-
 
| 0x10
 
| 0x10
 
| float3
 
| float3
 
| '''Position'''
 
| '''Position'''
 +
|
 
|-
 
|-
 
| 0x1C
 
| 0x1C
 
| float3
 
| float3
 
| '''Direction'''
 
| '''Direction'''
 +
|
 
|-
 
|-
 
| 0x28
 
| 0x28
 
| float
 
| float
| '''Reference Distance'''
+
| '''Brightness'''
 +
| Multiplied by color for local ambient, used to calculate distance attenuation coefficients for spot/custom
 
|-
 
|-
 
| 0x2C
 
| 0x2C
 
| float
 
| float
| '''Spot Cutoff
+
| '''Spot Cutoff'''
 +
| Used to calculate angle attenuation coefficients for spotlights
 
|-
 
|-
 
| 0x30
 
| 0x30
 
| float
 
| float
| {{unknown|Unknown}}
+
| {{unknown|'''Unknown'''}}
 +
| Possibly unused
 
|-
 
|-
 
| 0x34
 
| 0x34
| byte
+
| bool
| '''Quadratic Cutoff'''
+
| {{unknown|'''Unknown'''}}
 +
| Possibly unused
 
|-
 
|-
 
| 0x35
 
| 0x35
 
| float
 
| float
| '''Light Factor
+
| {{unknown|'''Unknown'''}}
 +
| Possibly unused
 
|-
 
|-
 
| 0x39
 
| 0x39
 
| long
 
| long
| '''Distance Cutoff (bool)'''
+
| '''Falloff Type'''
 +
| Possible values: 0 - Constant; 1 - Linear; 2 - Quadratic
 
|-
 
|-
 
| 0x3D
 
| 0x3D
 
| float
 
| float
| {{unknown|Unknown}}
+
| {{unknown|'''Unknown'''}}
 +
| Possibly unused
 
|-
 
|-
 
| 0x41
 
| 0x41
| colspan=2 {{unknown|End of light}}
+
| colspan=3 {{unknown|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).
 +
 +
{| class="wikitable"
 +
! Offset
 +
! Type
 +
! Description
 +
! Notes
 +
|-
 +
| 0x0
 +
| long
 +
| '''Light Type'''
 +
|
 +
|-
 +
| 0x4
 +
| float4
 +
| '''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
 +
| '''Brightness'''
 +
| Multiplied by color for local ambient, used to calculate distance attenuation coefficients for spot/custom
 +
|-
 +
| 0x3C
 +
| float
 +
| '''Spot Cutoff'''
 +
| Used to calculate angle attenuation coefficients for spotlights
 +
|-
 +
| 0x40
 +
| float
 +
| {{unknown|'''Unknown'''}}
 +
|
 +
|-
 +
| 0x44
 +
| bool
 +
| {{unknown|'''Unknown'''}}
 +
|
 +
|-
 +
| 0x45
 +
| float
 +
| {{unknown|'''Unknown'''}}
 +
|
 +
|-
 +
| 0x49
 +
| u32
 +
| '''Falloff Type'''
 +
|
 +
|-
 +
| 0x4D
 +
| float
 +
| {{unknown|'''Unknown'''}}
 +
|
 +
|-
 +
| 0x51
 +
| float
 +
| {{unknown|'''Unknown'''}}
 +
|
 +
|-
 +
| 0x55
 +
| float
 +
| {{unknown|'''Unknown'''}}
 +
|
 +
|-
 +
| 0x59
 +
| float
 +
| {{unknown|'''Unknown'''}}
 +
|
 +
|-
 +
| 0x5D
 +
| float
 +
| {{unknown|'''Unknown'''}}
 +
|
 +
|-
 +
| 0x61
 +
| u32
 +
| {{unknown|'''Unknown'''}}
 +
|
 +
|-
 +
| 0x65
 +
| colspan=3 {{unknown|End of light}}
 +
|}
 +
 +
=== Light Types ===
 +
 +
The first value in each light is a type value. These are the possible values:
 +
 +
{| class="wikitable"
 +
! 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:
 +
 +
<pre>(0.0, -CosCutoff / (1.0 - CosCutoff), 1.0 / (1.0 - CosCutoff))</pre>
 +
 +
=== 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 <code>2.0 / Brightness</code>
 +
* 1: '''Linear''': Coefficient B is set to <code>250 / Brightness</code>
 +
* 2: '''Quadratic''': Coefficient C is set to <code>25000 / Brightness</code>
  
 
[[Category:File Formats]]
 
[[Category:File Formats]]
 
[[Category:Metroid Prime]]
 
[[Category:Metroid Prime]]
 
[[Category:Metroid Prime 2: Echoes]]
 
[[Category:Metroid Prime 2: Echoes]]
[[Category:Major research needed]]
 

Latest revision as of 22:30, 26 March 2019

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.


Morphball render.png 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 lights section has a very brief header consisting of the magic value 0xBABEDEAD. It's then followed by a number of light layers. Each light layer consists of a count value, then an array of lights. Each layer represents a separate set of lights; actors can choose with set they're lit with through an object property in LightParameters. The number of light layers is static, but it varies from game to game; Prime 1 and 2 can have up to two light layers, while Prime 3 can have four.

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 Color There is no alpha component.
0x10 float3 Position
0x1C float3 Direction
0x28 float Brightness Multiplied by color for local ambient, used to calculate distance attenuation coefficients for spot/custom
0x2C float Spot Cutoff Used to calculate angle attenuation coefficients for spotlights
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 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 Brightness Multiplied by color for local ambient, used to calculate distance attenuation coefficients for spot/custom
0x3C float Spot Cutoff Used to calculate angle attenuation coefficients for spotlights
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 / Brightness
  • 1: Linear: Coefficient B is set to 250 / Brightness
  • 2: Quadratic: Coefficient C is set to 25000 / Brightness