I thought it might be a good idea to start documenting things properly. So here's SR2 material format, or what I know at least. This is based on what I've been doing with chunkfiles, but considering how similar the cmesh/smesh format looks at a quick glance, this may be useful there too. It's got the basic structure, but there's still a lot unknowns.
Layout:
Structs:
Layout:
C#:
// Texture list as it appears in SR2 chunk_pc.
UInt32 numTextures
// (4 * numTextures) bytes zero
String[] textures // times numTexture
// Material library as it appears in SR2 chunk_pc.
// Every struct except ShaderTextureProps belongs to a particular material.
UInt32 numMaterials
// 12 bytes zero or align 16 bytes
UInt32 numMatShaderConstants // Total number counting all materials
// 8 bytes zero
UInt32 numShaderTextureProp // Total number counting all shaders
// 4 bytes zero
Material[] materials // times numMaterials
MatUnknown2[] matUnknown2s // times numMaterials
ShaderConstDesc[] // times numMaterials
// align 16 bytes
Single[] ShaderConstBlock // times numMatShaderConstants
Texture[] MatTextures // times 16 * numMaterials. 16 slots per material.
ShaderTextureProp[] ShaderTex // times numShaderTextureProp
UInt32[] ShaderTexData // Times numShaderTexturePropData in each ShaderTextureProp
Structs:
C#:
// 4x floats. Can be RGBA values, or whatever else that's passed to shader.
// Looks like often less than all four floats are used, leaving unused ones at 0.
struct ShaderConst
{
Single x
Single y
Single z
Single w
}
// 2 different streams of constants per material
struct ShaderConstDesc
{
UInt32 numConstants0 // Total number of floats used. Always divisible by 4, as would make sense when looking at above.
UInt32 idxConstants0 // Starting index of this stream in constant block
UInt32 numConstants1
UInt32 idxConstants1
}
struct MatUnknown2
{
UInt16 x
UInt16 y
UInt16 z
}
// Both values are -1 if this texture slot is not used.
struct Texture
{
Int16 idx // Index in texture list.
Int16 flags
}
struct Material
{
UInt32 unknown0
UInt32 shader // Probably.
UInt32 unknown1
Uint16 numUnknown2
Uint16 numTextures
UInt32 flags
Int32 unknown3
}
// These are probably texture properties for a particular shader.
struct ShaderTextureProp
{
UInt32 unknown0 // Texture?
UInt32 shader // You should always be able to find one or more materials with matching shader
UInt16 numShaderTexturePropData
UInt16 unknown3
UInt32 unknown4 // always -1
}
YAML:
meta:
id: sr2_matlib
file-extension: matlib
license: CC0-1.0
encoding: utf-8
endian: le
doc: |
Material library extracted from chunk_pc file.
seq:
- id: num_materials
type: u4
- type: align(16)
- id: num_mat_shader_constants
type: u4
doc: Total number counting all materials
- contents: [0, 0, 0, 0, 0, 0, 0, 0]
- id: num_shader_texture_prop
type: u4
doc: Total number counting all shaders
- contents: [0, 0, 0, 0]
- id: materials
type: material
repeat: expr
repeat-expr: num_materials
- id: mat_unknown2s
type: mat_unknown2_cont(materials[_index].num_unknown2)
repeat: expr
repeat-expr: num_materials
- id: shader_const_descs
type: shader_const_desc
repeat: expr
repeat-expr: num_materials
- type: align(16)
- id: shader_const_block
type: f4
repeat: expr
repeat-expr: num_mat_shader_constants
- id: mat_textures
type: mat_tex_cont
repeat: expr
repeat-expr: num_materials
- id: shader_texture_props
type: shader_texture_prop
repeat: expr
repeat-expr: num_shader_texture_prop
- id: shader_texture_prop_datas
type: shader_texture_prop_data(shader_texture_props[_index].num_data)
repeat: expr
repeat-expr: num_shader_texture_prop
types:
align:
params:
- id: size
type: u4
seq:
- size: (size - _io.pos) % size
material:
seq:
- id: unknown0
type: u4
- id: shader
type: u4
doc: Probably.
- id: unknown1
type: u4
- id: num_unknown2
type: u2
- id: num_textures
type: u2
- id: flags
type: u4
- id: unknown3
type: s4
mat_unknown2_cont:
params:
- id: num_data
type: u2
seq:
- id: data
type: mat_unknown2
repeat: expr
repeat-expr: num_data
- type: align(4)
mat_unknown2:
seq:
- id: x
type: u2
- id: y
type: u2
- id: z
type: u2
mat_tex_cont:
seq:
- id: tex_data
type: mat_tex
repeat: expr
repeat-expr: 16
mat_tex:
seq:
- id: tex_idx
type: u2
- id: tex_flag
type: u2
shader_const_desc:
doc: |
Two streams of shader constants. Floats are seemingly in bundled vector4s. Something
like this was also mentioned in [V] docs for SRIV:
https://www.saintsrowmods.com/forum/threads/crunched-mesh-formats.15962/
The values for both are number of floats (divisible by 4), and starting index.
seq:
- id: num_constants0
type: u4
- id: idx_constants0
type: u4
- id: num_constants1
type: u4
- id: idx_constants1
type: u4
shader_texture_prop:
doc: |
These are probably texture properties for a particular shader.
seq:
- id: unknown0
type: u4
doc: Texture?
- id: shader
type: u4
doc: |
You should always be able to find one or more materials with matching
shader
- id: num_data
type: u2
- id: unknown3
type: u2
- contents: [-1, -1, -1, -1]
shader_texture_prop_data:
params:
- id: num_data
type: u2
seq:
- id: data
type: u4
repeat: expr
repeat-expr: num_data
Last edited: