78 lines
3.1 KiB
Markdown
78 lines
3.1 KiB
Markdown
|
|
# Рендер-паритет (кадровый diff)
|
|||
|
|
|
|||
|
|
Документ описывает процесс проверки соответствия рендера:
|
|||
|
|
`оригинальный движок -> эталонный кадр -> render-demo -> diff-метрики`.
|
|||
|
|
|
|||
|
|
## Цель
|
|||
|
|
|
|||
|
|
- Зафиксировать объективный критерий "паритет достигнут / не достигнут".
|
|||
|
|
- Убрать субъективную визуальную оценку "похоже/не похоже".
|
|||
|
|
- Дать CI-проверку, которая ловит регрессии сразу после коммита.
|
|||
|
|
|
|||
|
|
## Единица проверки
|
|||
|
|
|
|||
|
|
Один тест-кейс = один объект (одна модель) + фиксированная конфигурация:
|
|||
|
|
|
|||
|
|
- архив ресурса;
|
|||
|
|
- имя модели;
|
|||
|
|
- `lod`;
|
|||
|
|
- `group`;
|
|||
|
|
- размер кадра (`width`, `height`);
|
|||
|
|
- угол камеры (`angle`);
|
|||
|
|
- PNG-эталон из оригинального рендера.
|
|||
|
|
|
|||
|
|
## Инварианты детерминизма
|
|||
|
|
|
|||
|
|
Для корректного сравнения кадры должны быть сняты в одинаковых условиях:
|
|||
|
|
|
|||
|
|
- одинаковый FOV и расстояние камеры до объекта;
|
|||
|
|
- одинаковый clear-color/фон;
|
|||
|
|
- одинаковые `lod/group`;
|
|||
|
|
- фиксированный угол (`angle`), без анимации;
|
|||
|
|
- фиксированное разрешение.
|
|||
|
|
|
|||
|
|
## Метрики сравнения
|
|||
|
|
|
|||
|
|
Сравнение выполняется по RGB-каналам:
|
|||
|
|
|
|||
|
|
- `mean_abs`: средняя абсолютная разница канала (0..255);
|
|||
|
|
- `max_abs`: максимальная разница канала;
|
|||
|
|
- `changed_ratio`: доля пикселей, где хотя бы один канал превышает `diff_threshold`.
|
|||
|
|
|
|||
|
|
Кейс считается пройденным, если:
|
|||
|
|
|
|||
|
|
- `mean_abs <= max_mean_abs`;
|
|||
|
|
- `changed_ratio <= max_changed_ratio`.
|
|||
|
|
|
|||
|
|
## Конфигурация кейсов
|
|||
|
|
|
|||
|
|
Файл: `parity/cases.toml`.
|
|||
|
|
|
|||
|
|
- секция `[meta]`: глобальные дефолты;
|
|||
|
|
- `[[case]]`: параметры конкретной модели и путь к эталонному PNG.
|
|||
|
|
|
|||
|
|
Эталонные кадры хранятся в `parity/reference/`.
|
|||
|
|
|
|||
|
|
## Локальный запуск
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cargo run -p render-parity -- \
|
|||
|
|
--manifest parity/cases.toml \
|
|||
|
|
--output-dir target/render-parity/current
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
При расхождении утилита пишет diff-изображение в:
|
|||
|
|
|
|||
|
|
- `target/render-parity/current/diff/<case>.png`
|
|||
|
|
|
|||
|
|
## CI-модель
|
|||
|
|
|
|||
|
|
CI запускает `render-parity` на каждом push/PR:
|
|||
|
|
|
|||
|
|
1. собирает `parkan-render-demo`;
|
|||
|
|
2. прогоняет кейсы из `cases.toml`;
|
|||
|
|
3. при падении публикует текущие кадры и diff как артефакт.
|
|||
|
|
|
|||
|
|
Важно: оригинальный движок в CI обычно не запускается.
|
|||
|
|
Эталонные PNG снимаются офлайн и версионируются в репозитории.
|