fix(render): use native shifted water reflection camera
Docs Deploy / Build and Deploy MkDocs (push) Successful in 35s

This commit is contained in:
Valentin Popov committed 2026-11-01 07:49:51 +04:00
1 parent 6d15bc2006
commit 0f8b14abbf
7 files changed
+168 -25

No files matched your search

+1 -1
View File
@@ -76,7 +76,7 @@ MSH-запрос со свободной preview-камерой; это не п
среде, перехватить DirectDraw/Direct3D calls и surface flips, сохранить state
log на минимальных сценах с одним типом материала.
Горизонтальные грани Land.msh с флагом `0x20000` используют Vulkan-отражение и исходную карту волн Du/Dv; перенос её смещений в обычное зеркало приближённый: `planar_reflection_shifted_camera_unsupported`.
Горизонтальные грани Land.msh с флагом `0x20000` используют исходную карту Du/Dv и окно shifted-камеры, проверенное исполнением Terrain.dll. Диапазон глубины, небо/туман/FX основного вида и размер target остаются приближениями: `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`; сама семантика оставшихся специальных проходов ещё не установлена.
+25 -10
View File
@@ -1147,13 +1147,27 @@ lightmap state передаются в `VulkanStaticMaterial`, а shader пос
В [эталонной сборке](../reference/original-binaries.md) выбор грани находится
в Terrain.dll RVA `0x28A50`, а подготовка EMBM-пакета — в RVA `0x1B540`.
Первый Vulkan-проход строит плоское зеркало. Для горизонтальной воды на
высоте `h` отражённая координата точки равна `z′ = 2h − z`. Это преобразование
применяется перед обычной проекцией. Оно меняет порядок вершин треугольника,
поэтому проход меняет сторону отсечения и отбрасывает геометрию ниже воды.
Для горизонтальной воды на высоте `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 остаётся
обычное зеркало с экранными координатами.
Цветовой target переходит из attachment layout в shader-read layout после
записи. Следующий зеркальный проход ждёт предыдущего чтения этой текстуры;
@@ -1182,10 +1196,11 @@ lightmap state передаются в `VulkanStaticMaterial`, а shader пос
В Vulkan карта хранится в двух каналах несжатой текстуры и возвращается к
знаковым значениям перед вычислением смещения.
Обычное зеркало ещё не повторяет shifted-камеру оригинала: смещения Du/Dv
сейчас переводятся из координат водоёма в текущую зеркальную проекцию.
Это приближение учитывается в `planar_reflection_shifted_camera_unsupported`;
совпадение генератора волн не доказывает совпадения итогового отражения.
Матрица положения камеры, её окно и координаты волн восстановлены, но весь
контекст отражённого вида ещё не повторён. Диапазон глубины, небо, туман и FX
заимствуются из основного вида, а размер target совпадает со swapchain.
Эти ограничения учитываются в `planar_reflection_render_context_approx`;
совпадение генератора волн и окна не доказывает совпадения итогового отражения.
Один target обслуживает ближайшую
активную высоту воды; другие высоты и негоризонтальные поверхности явно
считаются как неподдержанные. Это промежуточный водный проход, а не полная