feat(render): integrate Control effects and animated world scene
Docs Deploy / Build and Deploy MkDocs (push) Successful in 37s

This commit is contained in:
Valentin Popov committed 2026-10-31 17:18:47 +04:00
1 parent 4a589f42fc
commit 09fcd35023
7 files changed
+8364 -2601

No files matched your search

+43 -28
View File
@@ -24,22 +24,22 @@
затенения, вызывается завершение рендерера, снимается `in_render`, затем
рассылается `end-of-render`.
При retry кадра после пересоздания swapchain сохраняется прежний pending
sample, включая уже вычисленные позы и состояния FX и материалов. Для нового
drawable обновляются aspect, проекция и геометрия, зависящая от viewport; pose
берётся из pending camera. Новые события управления камерой остаются в
input controller и применяются следующим sample. Экранные billboards погоды
повторно проецируются из закэшированных мировых головы и хвоста, без второго
шага симуляции окружения и повторной отправки звуковых событий. Пауза нулевого
drawable не добавляет время.
В интерактивном preview часы материалов и окружения прибавляют полное время
между обновлениями. Ограничение шага в 100 мс остаётся у движения свободной
камеры и не обрезает эти часы. В режиме replay окружение получает разницу
последних применённых значений общего control clock.
Pending frame хранит пакет MAT0 для мира и, при наличии GPU-окружения, отдельный
пакет неба. Пакеты содержат выбранные селектор и категорию конвейера, фазовые
коэффициенты материала, четыре UV-преобразования и кортеж фаз дополнительных
текстур. Повторное применение пакета при retry или нескольких resize не выбирает
фазу заново и не продвигает RNG. Перед отрисовкой сначала применяются материалы
мира и их порядок прозрачности, затем MAT0 неба, после чего viewport-зависимый
проход неба записывает свои переопределения.
Если swapchain просит повторить ещё не представленный кадр, preview сохраняет
его общий clock, уже вычисленные позы, FX/RNG и фазы материалов. При изменении
drawable обновляются камера, aspect и viewport, после чего sky, environment
geometry и projected shadows пересобираются для нового размера.
Положение и ориентация камеры берутся из сохранённого состояния
ожидающего кадра; новый ввод мыши применяется при следующем сэмпле. Сэмпл
погоды остаётся прежним: экранные billboards дождя и снега повторно
проецируются из закэшированных мировых головы и хвоста, без второго шага
симуляции окружения или повторной отправки звуковых событий. Следующий такт
выбирается после успешного представления кадра; пауза нулевого drawable не
добавляет время.
## Элемент отрисовки
@@ -117,6 +117,10 @@ RVA `0x13D90`. Эти данные подтверждают только пор
путь превью принимает входные данные с матрицей `selector0_words`, полученные через
[процедуру захвата нативного кадра](../../tools/native-frame-capture/README.md).
Формат захвата сохраняет локальную матрицу `selector0_words` и, когда она
доступна, записывает `effective_world_matrix_words` с маркером пространства
`world`.
Процедура захвата записывает наблюдавшийся путь миссии и значение
`atmosphere_seconds`, если проверка потока, поколения и часов прошла успешно.
В превью с фиксированной камерой эта абсолютная фаза расписания используется,
@@ -163,14 +167,26 @@ RVA `0x4EBE0` использует соглашение о вызовах `__std
события, слушателю задаются захваченные позиция, направление вперёд и верхняя
ось; начальная сортировка диапазонов мира использует ту же позицию.
Если в JSON присутствует пара `effective_world_matrix_space: "world"` и
`effective_world_matrix_words`, превью использует мировую матрицу. Матрица
`selector0_words` остаётся локальной и используется как запасной вариант только
при отсутствии мировых полей, если `parented_camera` не равно `true`. Для
родительской камеры без эффективной мировой матрицы вход отклоняется.
Захват может содержать наблюдавшийся путь миссии и проверенное значение
`atmosphere_seconds`; последнее используется только при отсутствии явного
параметра командной строки. Это значение фиксирует фазу расписания атмосферы
при сравнении с неподвижной камерой, тогда как FX продолжает получать реальное
при сравнении с неподвижной камерой, тогда как FX по умолчанию получает реальное
время кадра. `simulation_time_seconds`, погода, RNG и полное состояние миссии
остаются неизвестными, поэтому совпадение камеры и фазы не подтверждает
визуального совпадения с нативным кадром.
Параметр `--control-clock-ms` воспроизводит единые часы MSH/FX от нуля до
выбранного значения в миллисекундах за указанное число кадров. Без этого
параметра часы идут в реальном времени. Для `--readback-sequence-out` этот
управляемый режим обязателен. Он не восстанавливает
`simulation_time_seconds`, погоду, RNG или полное состояние миссии.
Для неба превью вычисляет направление как `atan2(forward.x, forward.y)`. Оно
совпадает со вторым выходным значением, вычисляемым в `Terrain.dll` по RVA
`0x4F9C0`; при выборе сектора экранного градиента `CSky` добавляет π по RVA
@@ -183,15 +199,9 @@ RVA `0x4EBE0` использует соглашение о вызовах `__std
`1.3` рад — параметры, наблюдавшиеся в проверенном контексте GOG Ngi32
([формула native projection](../tomes/05-render.md#камера-и-размещение-в-оригинале)).
Для отношения ширины к высоте `a` превью вычисляет вертикальный угол
```rust
fn vertical_fov(self, aspect: f32) -> f32 {
2.0 * ((self.horizontal_fov * 0.5).tan() / aspect).atan()
}
```
Код заменяет невалидный `aspect` на отношение 16:9; горизонтальный угол
остаётся `1.3` рад после изменения размера окна, а новый viewport и матрица
камеры применяются при следующей отрисовке.
`2 * atan(tan(horizontal_fov / 2) / a)`. Поэтому горизонтальный угол остаётся
`1.3` рад после изменения размера окна; новый viewport и матрица камеры
применяются при следующей отрисовке.
Проекция направления не сравнивает косинус угла с ближней дистанцией: она
отбрасывает только лучи за камерой и почти параллельные плоскости изображения
@@ -254,6 +264,11 @@ D3D7 в `fparkan-render`, а затем один раз меняет знак в
- переход на запасной набор возможностей устройства;
- квантование времени симуляции.
Для отладки требуется детерминированный захват кадра: состояние камеры,
идентификаторы видимых объектов, список элементов отрисовки, ключи конвейера,
матрицы и хэши промежуточных буферов.
Параметр `--readback-sequence-out` сохраняет необработанные байты каждого
отправленного кадра; в имя файла записываются индекс кадра, значение общих
управляемых часов и размер изображения. Байты соответствуют выбранному формату
изображения swapchain Vulkan и не гарантируют порядок каналов R, G, B, A. Числовое
формат выводится как `readback_format`; расширение `.rgba` само по себе порядок
каналов не определяет. Последовательность не содержит структурированных ID
видимых объектов, списка элементов отрисовки, ключей конвейера, матриц или
хэшей промежуточных буферов.