tags: [vr-ar]
Оптимизация графики под частоту обновления 72/90/120 Гц в VR
Пропущенный фрейм в VR — не просто заминка картинки. Это вестибулярный конфликт: визуальная система говорит «ты стоишь», вестибулярный аппарат говорит «ты двигаешься». При регулярных дропах появляется тошнота. При 72 fps бюджет на фрейм — 13.9 мс. При 90 — 11.1 мс. При 120 — 8.3 мс. Каждая миллисекунда на счету, и обычные подходы к оптимизации «как в обычной игре» здесь не работают.
Meta Quest 3 по умолчанию запускается на 72 Hz — разработчик должен явно запросить 90 или 120 через OVRManager.display.displayFrequency. Но запросить мало: нужно убедиться, что рендер-бюджет позволяет не дропать фреймы на выбранной частоте, иначе система автоматически откатится назад.
Где реально теряются миллисекунды
Самая частая причина дропов — overdraw на прозрачных материалах. VR рендерит два глаза, и каждый полупрозрачный объект рисуется дважды. Эффекты частиц с десятью слоями полупрозрачности, которые в обычной игре стоят 1–2 мс, в VR легко становятся 4–5 мс. RenderDoc позволяет точно измерить overdraw: в режиме Overdraw Heatmap сразу видно, где пиксели перерисовываются по 8–12 раз.
Вторая проблема — draw calls. На Quest 3 (Snapdragon XR2 Gen 2) GPU не так страшен, как CPU-overhead от большого числа вызовов. 300 draw calls при неэффективном батчинге — это 3–4 мс только на CPU-side. GPU Instancing работает хорошо для одинаковых мешей, Static Batching — для статики. Проблема в том, что при Dynamic Batching геометрия трансформируется на CPU, и это дороже, чем просто отрисовать отдельно. Dynamic Batching в VR стоит выключить и заменить ручным DrawMeshInstanced для динамических объектов.
Третье — тени. Real-time тени в VR — роскошь. Даже один каскадный Directional Light с Shadow Distance 30м на Quest будет стоить 3–5 мс. Стандартный подход: запекать тени в lightmap для статики, использовать Blob Shadow Projector или псевдотени для динамических объектов. Если тени необходимы — только один каскад, Shadow Distance не более 10–15 м, PCF фильтрация вместо VSM.
Fixed Foveated Rendering и Variable Rate Shading
FFR — главный инструмент оптимизации, которым не пользуются по незнанию. Периферийное зрение человека значительно менее чувствительно к деталям, чем центральное. FFR рендерит края экрана с пониженным разрешением — на Quest это настраивается через OVRManager.fixedFoveatedRenderingLevel.
Уровни FFR от Low до HighTop: на High края рендерятся на 1/4 разрешения. Для большинства сцен это неразличимо — но экономит до 20–30% GPU времени. Исключения: тонкий текст на периферии (UI-элементы по краям поля зрения), тонкие линии (провода, решётки). Для этих объектов FFR можно отключить через OVROverlay — рендерить их поверх основного слоя без FFR-деградации.
Variable Rate Shading — более гибкий вариант, где скорость шейдинга варьируется по тайлам экрана. В Unity 2022+ поддерживается через ShadingRateImage API, но только на платформах с поддержкой VRS в железе. Meta Quest 3 поддерживает.
Процесс оптимизации на практике
Без данных — нет оптимизации. Первый шаг всегда: профилирование через OVR Metrics Tool (для Quest) или Unity Profiler с подключением к устройству. Нас интересует GPU time per frame, а не FPS — FPS может казаться стабильным за счёт Asynchronous SpaceWarp (ASW), который синтезирует промежуточные кадры при дропах. ASW маскирует проблему, но не решает её.
После профилирования — Frame Debugger для анализа последовательности draw calls и RenderDoc для детального GPU capture. Обычно 80% GPU-времени занимают 20% объектов. Оптимизируем их, а не всё подряд.
Типичный результат работы на реальном проекте: Quest 3, экшн-игра, старт — 68 fps при 72 Hz с периодическими дропами. После анализа: overdraw от particle systems (6 слоёв эффектов сгорания) — минус 3.2 мс после замены на атласные спрайты с 2 слоями. Тени от трёх источников света — минус 4.1 мс после замена на запечённые lightmaps. Dynamic Batching — выключен, добавлен GPU Instancing для деревьев и камней — минус 1.8 мс CPU. Итог: стабильные 90 fps с запасом 2–3 мс.
Сроки
| Объём оптимизации | Сроки |
|---|---|
| Профилирование + рекомендации | 2–3 дня |
| Оптимизация рендера (тени, batching, FFR) | 1–2 недели |
| Полная оптимизация под целевую частоту | 3–6 недель |
Стоимость рассчитывается после аудита проекта и определения целевой платформы и частоты обновления.





