SR2 Material doc

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:
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:
Back
Top