From 26370126f92241ccfb76899634bb52a8cb44b6f1 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Sun, 18 Oct 2026 12:18:30 +0400 Subject: fix(render): honor terrain base-only face flags --- docs/tomes/04-world.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'docs') diff --git a/docs/tomes/04-world.md b/docs/tomes/04-world.md index f9c0e67..e486e18 100644 --- a/docs/tomes/04-world.md +++ b/docs/tomes/04-world.md @@ -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`. -- cgit v1.2.3