aboutsummaryrefslogtreecommitdiff
path: root/docs/reference/materials.md
blob: 8146a2c38d7997d11c96f4217d22ef8550762fb2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# WEAR и MAT0

MSH batch хранит только `material_index`. WEAR переводит этот индекс в имя
материала, а MAT0 по этому имени описывает phases, parameters и texture
references.

```text
Batch20.material_index
  -> WEAR row
  -> MAT0 entry
  -> active phase
  -> textureName
```

## WEAR

WEAR -- текстовый ресурс type ID `0x52414557`, обычно `*.wea` рядом с моделью.

```text
<wearCount>
<legacyId> <materialName>
...

[empty line]
[LIGHTMAPS
<lightmapCount>
<legacyId> <lightmapName>
...]
```

`legacyId` сохраняется, но выбор выполняется по позиции строки и имени. Между
основной таблицей и `LIGHTMAPS` нужен пустой разделитель.

## MAT0

MAT0 имеет type ID `0x3054414D`, обычно расположен в `Material.lib`. `attr1`
содержит runtime flags, `attr2` -- версию payload.

```c
#pragma pack(push, 1)
struct Mat0PrefixV4Plus {
    uint16_t phase_count;
    uint16_t animation_block_count;
    uint8_t  metadata_a;
    uint8_t  metadata_b;
    uint32_t metadata_c_raw;
    uint32_t metadata_d_raw;
};

struct Phase34 {
    uint8_t parameters[18];
    char texture_name[16];
};
#pragma pack(pop)
```

Versioned fields читаются только если версия их содержит. Для старых версий
используются runtime defaults, а raw values сохраняются.

## Fallback

Material resolve:

1. имя из WEAR;
2. `DEFAULT`;
3. entry с индексом 0.

Пустое texture name означает намеренно нетекстурированную поверхность. Lightmap
fallback отдельный: отсутствующий lightmap даёт slot `-1`.