diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/appendices/knowledge-boundaries.md | 13 | ||||
| -rw-r--r-- | docs/reference/environment-effects.md | 9 | ||||
| -rw-r--r-- | docs/reference/msh.md | 5 | ||||
| -rw-r--r-- | docs/tomes/05-render.md | 81 |
4 files changed, 106 insertions, 2 deletions
diff --git a/docs/appendices/knowledge-boundaries.md b/docs/appendices/knowledge-boundaries.md index 0df1e5a..a60fa68 100644 --- a/docs/appendices/knowledge-boundaries.md +++ b/docs/appendices/knowledge-boundaries.md @@ -54,7 +54,10 @@ MSH-запрос со свободной preview-камерой; это не пÐ ([описание кадра](../reference/render-frame.md#прозрачность-порталов-msh)). Native CPU clipping может выбрать другую первую вершину; это приближение явно считается как `portal_fade_packet_selection_approx`. -Данные type 16 ещё не декодированы. Внутренний ракурс «Конструктора» после +Данные type 16 ещё не декодированы и считаются в `msh_type16_colors_unsupported`; +в статических сценах 29 миссий GOG (1736 загрузок моделей) этот поток отсутствует. +Его декодирование отложено до первого реального ненулевого счётчика. +Внутренний ракурс «Конструктора» после настоящего входа игрока подтверждает исчезновение чёрной поверхности в проходе; наружные окна обеих миссий сверены на расстояниях около 60/85/110, а ближние окна — с внутренней стороны. Окно «Конструктора» на правом краю кадра при @@ -73,6 +76,11 @@ MSH-запрос со свободной preview-камерой; это не пÐ среде, перехватить DirectDraw/Direct3D calls и surface flips, сохранить state log на минимальных сценах с одним типом материала. +Горизонтальные грани Land.msh с флагом `0x20000` используют исходную карту Du/Dv, окно shifted-камеры и квадратный размер текстуры, проверенные исполнением DLL. Диапазон глубины, небо/туман/FX основного вида и соответствие размеров при обрезанном capture остаются приближениями: `planar_reflection_render_context_approx`; неперспективная камера API использует обычное зеркало. +Raw queue clock задаёт фазу волн отдельно от времени суток и sky elapsed; старые захваты без него считаются в `captured_water_phase_unverified`. +Один target отражает ближайшую активную высоту воды; остальные высоты и неплоские грани считаются в `planar_reflection_other_planes_unsupported` и `planar_reflection_nonplanar_unsupported` и сохраняют обычный terrain shader. +`terrain_face8_pipeline_unverified` теперь считает только исходные грани с `0x8` без `0x20000`; сама семантика оставшихся специальных проходов ещё не установлена. + ## FXID field-level semantics Control Op1 пока использует цвет и радиус без случайных добавок команды; @@ -82,6 +90,9 @@ Control Op1 пока использует цвет и радиус без слу Control Op2 воспроизводит modes 0/2; modes 1/3, body+76 и неподдержанные time modes/привязки считаются как `render_coverage control_op2_unsupported`. Управление фазой экземпляра командами Control остаётся до его подключения в runtime. +При расширении выбранных начальных строк все пропущенные команды считаются +в `control_fx_unsupported`, а time modes 4–17 — в `control_fx_requires_game_state`; +причина и владелец выводятся в лог. Неразобранные FXID считаются отдельно в `control_fx_invalid_documents`. Размеры команд, resource references, lifecycle, flags families и используемые time modes известны. Не закрыто значение каждого поля body opcodes 1--10, diff --git a/docs/reference/environment-effects.md b/docs/reference/environment-effects.md index f3ecfb4..677c159 100644 --- a/docs/reference/environment-effects.md +++ b/docs/reference/environment-effects.md @@ -420,6 +420,15 @@ FX-команды используют общий preview clock и ограниÑ mode 0 оставляет фазу равной нулю, mode 1 вычисляет `elapsed / duration` без зажатия, mode 2 повторяет цикл. Header flags `0x200` и `0x20` преобразуют эту фазу; command path `0x8120` зажимает результат только после преобразований. +В [эталонной Effect.dll](original-binaries.md) RVA `0x5C60` режимы 4–17 +читают состояние владельца или провайдера; режим 14 тоже входит в эту группу. +Пропуски при расширении выбранных начальных Control-строк учитываются по +командам: `control_fx_requires_game_state` для этих режимов и +`control_fx_unsupported` для остальных непреобразованных команд. Диагностика +сохраняет причину, ресурс, объект, компонент, строку и номер команды. +`control_fx_invalid_documents` отдельно считает неразобранные FXID, где число +команд неизвестно. Счётчики суммируются по компонентам миссии; они не заменяют +учёт ещё не выбранных Control-групп и условных строк в фазе G. Effect renderer проверяет header bit `0x800` только при render selector 0; native AniMesh component path был захвачен с selector 1, поэтому preview использует selector 1 и не подавляет такие visual commands. diff --git a/docs/reference/msh.md b/docs/reference/msh.md index 130a203..873cae1 100644 --- a/docs/reference/msh.md +++ b/docs/reference/msh.md @@ -28,7 +28,10 @@ type 20 rare auxiliary table Reader ищет entries по type, но сохраняет исходный порядок для roundtrip. Поле `ModelAsset.type16_present` отмечает только наличие entry типа 16. Данные payload сохраняются, но этот путь рендера пока не преобразует их в цвета -вершин. +вершин; приложение считает затронутые диапазоны в `msh_type16_colors_unsupported`. +В статических сценах всех 29 миссий GOG ни одна из 1736 загрузок моделей +не содержит этого потока. Это ограничение проверенного набора ресурсов; +неиспользуемые модели и будущие игровые состояния сюда не входят. ## Node and slot selection diff --git a/docs/tomes/05-render.md b/docs/tomes/05-render.md index cfd352a..4aba919 100644 --- a/docs/tomes/05-render.md +++ b/docs/tomes/05-render.md @@ -1138,6 +1138,87 @@ lightmap state передаются в `VulkanStaticMaterial`, а shader посÐ сэмплирует эти четыре стадии. Animation clock обновляет выбранные фазы и коэффициенты без пересборки terrain mesh, сохраняя native type-14 overlay mask. +### Отражение на воде + +Поверхность воды нельзя рисовать тем же умножением текстур, что и землю. +В проходе ландшафта GOG Terrain.dll флаг грани `0x20000` участвует в выборе +отражения; при включённом EMBM живой водный кадр использует texture mode 10. +Оригинал создаёт для этого отдельную камеру `REFLECTION_SHIFTED`. +В [эталонной сборке](../reference/original-binaries.md) выбор грани находится +в Terrain.dll RVA `0x28A50`, а подготовка EMBM-пакета — в RVA `0x1B540`. + +Для горизонтальной воды на высоте `h` камера отражения находится в точке +`[eye_x, eye_y, 2h − eye_z]`. Но она не повторяет наклон основной камеры: +смотрит вертикально вверх, а её окно лежит на прямоугольнике водоёма. Поэтому +текстура отражения привязана к местности, а не к экрану игрока. В плоскости +воды координаты изображения равны `U = 1 − Ynorm`, `V = 1 − Xnorm`. + +Terrain.dll RVA `0x4EFF0` передаёт shifted-проекции пять значений: +`[min_y − eye_y, min_x − eye_x, span_y, span_x, eye_z − h]`. Например, +для наблюдателя `[1200, 800, 185]`, воды `150` и границ +`[1000, 500, 1500, 1200]` это `[-300, -200, 700, 500, 35]`. +Матрица камеры и эти аргументы проверены исполнением оригинальной функции +при двух положениях и разных поворотах основной камеры. Оракул подменяет +ввод-вывод очереди, ландшафта и камеры; сам renderer и матрица глубины в эту +проверку не входят. Vulkan-проекция сохраняет near/far основного вида; +Rust-тест отдельно проверяет углы водоёма и границы глубины. + +Отражённый вид меняет сторону отсечения и отбрасывает геометрию ниже воды. +Небо и оставшаяся сцена попадают в отдельную цветовую текстуру с собственной +глубиной. В основном проходе водные треугольники читают её по координатам +водоёма с добавленным смещением волн. Для неперспективной камеры API остаётся +обычное зеркало с экранными координатами. + +Размер изображения отражения выбирается отдельно от размера основного кадра. +Terrain.dll в конструкторе CShade (RVA `0x278E0`, цикл с `0x27FC7`) берёт +ширину и высоту renderer через Ngi32.dll RVA `0x7FB0`. Сторона квадратной +текстуры — наибольшая степень двойки, не превосходящая меньшую из этих +величин и 1024; нижний предел равен 2. Например, экран 1280×1024 даёт +отражение 1024×1024, а 1280×720 — 512×512. Getter размеров и исходный цикл +выбора проверены исполнением DLL на десяти входах; создание нативной текстуры +в этом оракуле пропущено. Vulkan создаёт цвет и глубину с этой стороной и +задаёт каждому проходу собственные viewport и область очистки. Так уменьшение +отражения не обрезает основной кадр и воспроизводит исходный масштаб его +пикселей, от которого зависит чёткость берегов и ряби. + +Цветовой target переходит из attachment layout в shader-read layout после +записи. Следующий зеркальный проход ждёт предыдущего чтения этой текстуры; +основной и отражённый виды используют разные слоты uniform buffer. Во время +записи отражения привязан отдельный нейтральный descriptor, чтобы проход +не читал собственное вложение. + +Волны не требуют готовой текстуры из ресурсов: Terrain.dll RVA `0x2BF50` +создаёт карту 128×128 со знаковыми парами Du/Dv. Для нормированных координат +текселя `x` и `y` угол равен `(x + y − 1) × 12,566360473632812`, а компоненты — +округлённые `64 cos(угол)` и `64 sin(угол)`. Все 32 768 байт Rust-генератора +сверены с исполнением этой функции DLL при игровом x87 CW `0x007F`. + +Рябь привязана к водоёму, поэтому не плывёт вслед за экраном. Конструктор +ландшафта собирает прямоугольник всех отражающих граней; U меняется против +мировой Y, V — против X. Эти координаты повторяются сто раз, к обеим прибавляется +`(queue_clock % 10000) / 10000`. Это самостоятельный clock: время суток и +относительный clock неба не задают фазу волн. Захват хранит исходный +`sky_uv_clock.raw_clock`; ограниченный replay фиксирует его, интерактивный +продолжает с этого значения. Старые захваты без raw clock явно считаются в +`captured_water_phase_unverified`. + +Карта Du/Dv смещает координаты следующей текстуры с диагональными коэффициентами +`0,01`, без изменения яркости. Это правило +[Direct3D BUMPENVMAP](https://learn.microsoft.com/en-us/windows/win32/direct3d9/bump-mapping-formulas). +В Vulkan карта хранится в двух каналах несжатой текстуры и возвращается к +знаковым значениям перед вычислением смещения. + +Матрица положения камеры, её окно, размер текстуры и координаты волн восстановлены, но весь +контекст отражённого вида ещё не повторён. Диапазон глубины, небо, туман и FX +заимствуются из основного вида. Для захвата с обрезанным viewport ещё не +подтверждено соответствие размера окна FParkan полному renderer оригинала. +Эти ограничения учитываются в `planar_reflection_render_context_approx`; +совпадение генератора волн и окна не доказывает совпадения итогового отражения. +Один target обслуживает ближайшую +активную высоту воды; другие высоты и негоризонтальные поверхности явно +считаются как неподдержанные. Это промежуточный водный проход, а не полная +приёмка воды или лавы. + ## Реализация Vulkan `LegacyPipelineState` хранит blend, depth, cull и alpha-test. Из этих значений |
