fix(render): honor terrain base-only face flags
Docs Deploy / Build and Deploy MkDocs (push) Successful in 33s

This commit is contained in:
Valentin Popov committed 2026-10-18 12:18:30 +04:00
1 parent e7b02c879a
commit 26370126f9
7 files changed
+96 -23

No files matched your search

+24
View File
@@ -430,6 +430,30 @@ full 00000040 -> compact 2000
full 00200000 -> compact 8000
```
Бит `0x400` в маске грани рельефа управляет detail-текстурой. В `Terrain.dll`
метод `CShade` по смещению `+0x10` таблицы `0x10065108` ведёт к `0x10028A50`:
он читает `flags` по смещению `+0x3C` и проверяет бит в `0x10029191`. Ветка для
очищенного бита обнуляет указатель detail-текстуры в `0x10029427`. Затем
`Ngi32` применяет режим 1 или 7: для RGB stage 0 умножает текстуру на diffuse-
цвет, а stage 1 отключён. Alpha режима 1 берётся из texture, режима 7 — из
diffuse; на проверенных непрозрачных полосах основания это различие не меняет
цвет фрагмента. Текущий код сохраняет выбор в каждой полосе отрисовки рельефа:
```rust
let terrain_base_only = first_face.flags.0 & 0x400 == 0;
```
Фрагментный шейдер пропускает умножение на detail-текстуру:
```glsl
bool terrain_base_only = (mode & 16) != 0;
vec3 base_rgb = terrain_base_only ? base.rgb : 2.0 * base.rgb * detail.rgb;
```
В исходных картах бит установлен у всех 275 882 граней рельефа. У полос
основания, которые создаются процедурно при загрузке миссии, бит очищен;
именно поэтому им нужен этот вариант без detail-текстуры.
Для шестибитного material-поля используются full-биты `0x100`, `0x8000`,
`0x10000`, `0x40000`, `0x80000` и `0x80`; они переходят соответственно в
compact-биты `1`, `2`, `4`, `8`, `0x10`, `0x20`.