Materials (Metroid Prime): Difference between revisions

>Aruki
No edit summary
>Aruki
 
(6 intermediate revisions by the same user not shown)
Line 122: Line 122:
| 0
| 0
| 0x1
| 0x1
| Unused, always set ''(always unset in Echoes)''
| Unused, always set ''(never set in Echoes)''
|-
|-
| 1
| 1
Line 130: Line 130:
| 2
| 2
| 0x4
| 0x4
| Unused, always unset
| Unused, never set
|-
|-
| 3
| 3
| 0x8
| 0x8
| Enable Konstant values
| Has Konst values
|-
|-
| 4
| 4
| 0x10
| 0x10
| Enable depth sorting for transparent materials
| Transparent
|-
|-
| 5
| 5
| 0x20
| 0x20
| Enable punchthrough alpha
| Masked alpha (compare threshold is hardcoded at 0.25)
|-
|-
| 6
| 6
Line 150: Line 150:
| 7
| 7
| 0x80
| 0x80
| Enable depth writing
| Enable Z-writes
|-
|-
| 8
| 8
Line 178: Line 178:
| 14
| 14
| 0x4000
| 0x4000
| Unused, never set ''(always set in Echoes)''
| {{unknown|In MP1, unused, never set; in Echoes, unknown}}
|-
|-
| 15
| 15
| 0x8000
| 0x8000
| Unused, never set
| {{unknown|In MP1, unused, never set; in Echoes, unknown}}
|-
|-
| 16-31
| 16-31
Line 191: Line 191:
==== Vertex Attribute Flags ====
==== Vertex Attribute Flags ====


These flags are generally toggled in pairs, with each pair corresponding to a vertex attribute; if a pair is set, then vertices using this material will have the corresponding attribute. This is vital for reading geometry. Starting in Echoes, each pair is used to indicate the size of the attribute indices in the geometry data, with 3 meaning a 16-bit index and 2 meaning an 8-bit index.
These flags are generally toggled in pairs, with each pair corresponding to a vertex attribute; if a pair is set, then vertices using this material will have the corresponding attribute. This is vital for reading geometry. Starting in Echoes, each pair is used to indicate the size of the attribute indices in the geometry data, with 3 meaning a 16-bit index and 2 meaning an 8-bit index. (This isn't actually used, though; the original game data always uses 16-bit indices.)


GX supports up to 8 texture coords per vertex, but the game doesn't seem to allow you to assign more than 7 (though this could do with some double-checking).
GX supports up to 8 texture coords per vertex, but the game doesn't seem to allow you to assign more than 7 (though this could do with some double-checking).
Line 643: Line 643:


=== UV Animations ===
=== UV Animations ===
'' See [[UV Animations]]''


The UV animations section immediately follows the texgen flags. Its purpose is to generate texture matrices and post-transform matrices, which are then used to transform UV coordinates. This is commonly used to animate textures via simple UV scrolls, but it's also often used to simulate reflective surfaces that move with the camera. Materials can have multiple UV animations; in that case, each animation generates a separate texture/post-transform matrix and are loaded into GX sequentially. Texgen is used to set which matrices are used by which UV coordinates (if any).
The UV animations section immediately follows the texgen flags. Its purpose is to generate texture matrices and post-transform matrices, which are then used to transform UV coordinates. This is commonly used to animate textures via simple UV scrolls, but it's also often used to simulate reflective surfaces that move with the camera. Materials can have multiple UV animations; in that case, each animation generates a separate texture/post-transform matrix and are loaded into GX sequentially. Texgen is used to set which matrices are used by which UV coordinates (if any).
Line 662: Line 664:
|}
|}


The structure of the animations themselves is somewhat simple. Each animation has a 32-bit ''mode'' setting, followed by a number of float parameters. The number and usage of these float parameters varies depending on what mode is set. There are 8 possible modes.
For info on how to read the animation data and how each animation mode works, see [[UV Animations]].
 
For all of the following modes, ''s'' refers to ''seconds mod 900''.
 
==== Mode 0: Inverse ModelView Matrix (No Translation) ====
 
This mode is commonly used with vertex normals to simulate reflective surfaces using spheremaps that move with the camera. It takes no parameters, and will generate both a texture matrix and a post-transform matrix. Translation is ignored.
 
The texture matrix is calculated like this. Note that the multiplication of the view matrix by the model matrix should be modified slightly rather than being a straight multiplication to ignore translation on the model matrix. (The game uses a function called MultiplyIgnoreTranslation for this.)
 
<pre>texmtx = inverse(ViewMatrix) * ModelMatrix;
texmtx[0][3] = texmtx[1][3] = texmtx[2][3] = 0;</pre>
 
The post-transform matrix is a constant value. [1][1] and [1][2] may need to be swapped around for correct playback.
 
<pre>0.5, 0.0, 0.0, 0.5,
0.0, 0.0, 0.5, 0.5,
0.0, 0.0, 0.0, 1.0</pre>
 
==== Mode 1: Inverse ModelView Matrix ====
 
This mode is nearly identical to mode 0; the only difference is that translation is left as-is. The multiplication of the view matrix by the model matrix actually is a straight multiplication in this mode, and the translation values on the texture matrix aren't set to 0.
 
==== Mode 2: UV Scroll ====
 
This mode is used to scroll both U and V at the same time. It will only generate a texture matrix. It has four float parameters: ''offsetA'', ''offsetB'', ''scaleA'', and ''scaleB''.
 
<pre>uOffset = (s * scaleA) + offsetA;
vOffset = (s * scaleB) + offsetB;</pre>
 
==== Mode 3: Rotation ====
 
This mode rotates the texture. It will only generate a texture matrix. It has two float parameters: ''offset'' and ''scale''.
 
<pre>float angle = (s * scale) + offset;
float acos = cos(angle);
float asin = sin(angle);
float translateX = (1.0 - (acos - asin)) * 0.5;
float translateY = (1.0 - (asin + acos)) * 0.5;</pre>
 
The resulting texture matrix is laid out as:
 
<pre>acos, -asin, 0.0, translateX,
asin,  acos, 0.0, translateY,
0.0,  0.0, 1.0,        0.0</pre>
 
==== Mode 4/5: Horizontal/Vertical Filmstrip ====
 
These modes can be used to create a filmstrip-like effect. The texture steps a set distance each animation frame, rather than the scroll being smoothly interpolated every game frame. The same calculation is done for both modes, with the only difference being whether the calculated offset is applied to the U or V coordinate. It will only generate a texture matrix. There are four float parameters: ''scale'', ''numFrames'', ''step'', and ''offset''.
 
The animation is made up of a number of pseudo-frames, where ''step'' controls the amount that the texture scrolls by each frame, and ''numFrames'' sets how many frames are iterated through before resetting back to 0. ''scale'' roughly controls animation playback speed, and ''offset'' modifies the time input value.
 
<pre>float value = step * scale * (offset + s);
float uv_offset = (float)(short)(float)(numFrames * fmod(value, 1.0f)) * step;</pre>
 
==== Mode 6: Model Matrix ====
 
This mode is similar to modes 0 and 1 in that it simulates reflective surfaces, but it only takes the model matrix into account, which means camera movement doesn't affect the reflection. It takes no parameters and it generates both a texture matrix and a post-transform matrix.
 
The texture matrix is simply the model matrix, with the translation values set to 0. The post-transform matrix is set to the following:
 
<pre>0.5, 0.0, 0.0, ModelMatrix[0][3] * 0.50000001,
0.0, 0.0, 0.5, ModelMatrix[1][3] * 0.50000001,
0.0, 0.0, 0.0, 1.0</pre>
 
==== Mode 7: Mode-Who-Must-Not-Be-Named ====
 
Mode 7 takes two parameters and generates both a texture matrix and a post-transform matrix. We don't know what to name it.
 
The texture matrix is generated the same way as in mode 0; translation is ignored.
 
<pre>texmtx = inverse(ViewMatrix) * ModelMatrix;
texmtx[0][3] = texmtx[1][3] = texmtx[2][3] = 0;</pre>
 
The post-transform matrix is where it gets a little complicated. A little math is required to calculate some values:
 
<pre>float xy = ((ViewMatrix[0][3] + ViewMatrix[1][3]) * 0.025f * ParamB;
xy = (xy - (int) xy); // This truncates the integer portion of the value, leaving only the fractional part (mantissa).
 
float z = ViewMatrix[2][3] * 0.05f * ParamB;
z = (z - (int) z);
 
float halfA = ParamA * 0.5f;</pre>
 
The post-transform matrix is then constructed as:
 
<pre>halfA, 0.0f,  0.0f,  xy,
0.0f, 0.0f, halfA,  z,
0.0f, 0.0f,  0.0f, 1.0f</pre>


[[Category:File Formats]]
[[Category:File Formats]]
[[Category:Metroid Prime]]
[[Category:Metroid Prime]]
[[Category:Metroid Prime 2: Echoes]]
[[Category:Metroid Prime 2: Echoes]]
Anonymous user