aboutsummaryrefslogtreecommitdiff
path: root/docs/tomes/05-render.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tomes/05-render.md')
-rw-r--r--docs/tomes/05-render.md45
1 files changed, 37 insertions, 8 deletions
diff --git a/docs/tomes/05-render.md b/docs/tomes/05-render.md
index 610491b..034e255 100644
--- a/docs/tomes/05-render.md
+++ b/docs/tomes/05-render.md
@@ -1030,11 +1030,39 @@ Node38, а диапазоны граней — в 68-байтовых Slot68. В
проверяются на единственное назначение, а выходящий за массив, повторный или
неподдерживаемый диапазон считается ошибкой загрузки.
-Первый рендер карты, terrain-запросы высоты и пересечения, receiver-ы теней и
-обрезка контуром зданий используют только LOD0. Отбор сохраняет порядок
-исходных граней, а контурный проход отдельно переводит индекс спроецированной
-грани обратно в исходный. LOD1 пока не подставляется по расстоянию: такой
-переход не реализован.
+Рисуемый уровень выбирается по ячейкам, а не по расстоянию до отдельного
+треугольника. Начало сетки находится в первых двух float заголовка Slot68,
+размер ячейки — в границах первого слота LOD0. Атрибут 2 потока Node38 задаёт
+число ячеек по X; индекс ячейки равен `x * count_y + y`. Приложение проверяет,
+что границы всех слотов образуют эту регулярную сетку. Все 33 карты GOG
+проходят такую проверку, включая вырожденные грани на общей границе ячеек:
+принадлежность грани берётся из слота, а не угадывается по её центру.
+
+Координаты камеры переводятся в целые координаты сетки округлением вниз.
+Если `dx * dx + dy * dy >= 9` и горизонтальный FOV не меньше 0,5 радиана,
+выбирается LOD1. При увеличении масштаба, отсутствии дальнего слота или
+наличии геометрического patch остаётся LOD0. Камера за границей карты не
+прижимается к крайней ячейке для этого расчёта. Правило восстановлено по
+GOG `Terrain.dll` ([сборка и SHA-256](../reference/original-binaries.md)):
+`CLandscape::Render`, RVA `0x11340`, выбор уровня `0x11878–0x11A03`.
+Исполнение оригинала подтверждает выбор дальнего слота, а getter камеры
+`Ngi32.dll` RVA `0x4D960` возвращает именно FOV.
+
+Основания строений сохраняют подробную геометрию. Нативная регистрация
+patch (`Terrain.dll` RVA `0x12E20`) проверяет его треугольники против каждой
+ячейки через `mrnParaIntersectsPoly`. Поэтому учитываются и соседние ячейки,
+которых касается край треугольника. Перед проверкой координаты нормализуются
+в `f32` относительно центра ячейки; замена этой операции сравнением мировых
+границ меняет результат на общих рёбрах. На «Конструкторе» игнорируемый
+ресурсный тест сверяет все 22 ячейки с принудительным LOD0 с набором,
+полученным в живом оригинале.
+
+Vulkan получает оба уровня один раз. Диапазоны индексов разделены по
+материалу и исходной ячейке; на каждом кадре включается только выбранный
+уровень. Сгенерированные отмостки остаются включены. Terrain-запросы высоты
+и пересечения, receiver-ы теней и обрезка контуром зданий используют
+канонический LOD0. Отбор сохраняет порядок исходных граней, а контурный проход
+отдельно переводит индекс спроецированной грани обратно в исходный.
```rust
let assignments = mesh.face_lod_assignments()?;
@@ -1052,9 +1080,10 @@ for (face, assignment) in mesh.faces.iter().zip(assignments.iter()) {
исходные фрагменты рельефа вместе с треугольниками отмостки в одном наборе.
`TerrainWorld::with_basement_foundation` принимает этот набор во владение и
устанавливает те же координаты и маски в BVH высотных запросов и пересечений.
-Предпросмотр миссии на Vulkan пока строит только LOD0: связывание BAS-записей
-с этой подготовкой ещё не подключено, поэтому наличие API не означает, что
-геометрия миссии уже обрезана.
+Предпросмотр миссии связывает BAS-записи с этой подготовкой до загрузки
+материалов. Полученная поверхность общая для изображения, теней и запросов;
+поправка размещения основания один раз применяется к корню строения и его
+присоединённым компонентам.
Внешнее кольцо должно лежать на области LOD0, а каждый его сегмент — оставаться
покрытым текущей поверхностью. Непокрытый сегмент или пересекающиеся контуры