Разработка мобильного VR-приложения (Google Cardboard)
Google Cardboard — самый демократичный способ попасть в VR: картонный корпус за несколько долларов, смартфон внутри. Для разработчика это значит: стереоскопический рендеринг, трекинг головы через IMU, и жёсткие ограничения по производительности — всё это делается на обычном мобильном железе без специализированного VR-процессора.
Google Cardboard SDK
После того как Google открыл исходники Cardboard SDK в 2021 году, он стал официальным путём для Cardboard-приложений на iOS и Android. SDK предоставляет:
- Дисторция-коррекцию для линз (каждый корпус имеет свой lens distortion profile, сканируемый QR-кодом)
- Head tracking через фьюжн данных акселерометра и гироскопа (IMU fusion)
- Eye matrices для корректной проекции на каждый глаз
- Trigger button обработку (магнитная кнопка в картонном Cardboard)
Unity интеграция — com.google.cardboard UPM пакет. После подключения:
// CardboardHeadTracker читается через Cardboard.SDK
void Update() {
Cardboard.SDK.UpdateScreenParams();
// Позиция/ротация головы применяется автоматически через CardboardCamera компонент
}
Нативная Android интеграция через CardboardHeadTracker и CardboardLensDistortion:
// Инициализация
headTracker = CardboardHeadTracker.create();
lensDistortion = CardboardLensDistortion.create(encodedDeviceParams, width, height);
// В render loop
headTracker.getPose(monotonic_time_nanos, target_time_nanos, outEyeFromHead);
Стереоскопический рендеринг: split-screen
Экран делится пополам. Левая половина — для левого глаза, правая — для правого. Каждая половина рендерится с небольшим смещением камеры (IPD — interpupillary distance, ~63–65mm). Разница между двумя изображениями создаёт стереоэффект.
В Unity это управляется через CardboardCamera компонент с двумя рендер-текстурами. Каждая текстура рендерится отдельно, затем применяется barrel distortion correction.
Критичная проблема производительности: two-pass rendering удваивает нагрузку на GPU. На среднем смартфоне 2020 года при 1080p это 30–40 FPS без оптимизаций. Решения:
- Foveated rendering — снижение разрешения по краям экрана (не центральная область видна через линзы)
- Single Pass Instanced Rendering в Unity (рендеринг обоих глаз за один draw call)
- Снижение разрешения рендер-текстур до 0.7–0.8 от экранного разрешения
Head tracking и Motion Sickness
Motion sickness возникает, когда visual latency > 20ms. IMU работает на 200–1000Hz, но рендеринг на 60Hz. Для компенсации используется ATW (Asynchronous TimeWarp) — перепроецирование последнего кадра с учётом новой ориентации головы за время между рендером и выводом на экран.
В Cardboard SDK ATW реализован автоматически через дополнительный композитинг-пасс. Убедитесь, что Cardboard.SDK.UpdateScreenParams() вызывается в начале каждого Update(), а не реже.
Рекомендации по Scene Design для снижения укачивания:
- Нет acceleration-based locomotion (телепортация предпочтительнее)
- Постоянный горизонт или cockpit-reference (кабина, интерьер) снижают дискомфорт
- Не масштабируйте мир относительно игрока в рантайме
Ввод: кнопка и Gaze
У базового Cardboard одна кнопка. Всё взаимодействие строится на:
- Gaze input — курсор следует за взглядом, активация по фиксации взгляда (dwell time, обычно 1.5–2 сек)
- Trigger button — подтверждение выбора, телепортация
Gaze reticle (курсор) рендерится в world space на фиксированном расстоянии от камеры. Raycast из центра каждого глаза определяет объект под курсором:
// Unity: Gaze Raycaster
void Update() {
Ray ray = new Ray(Camera.main.transform.position,
Camera.main.transform.forward);
if (Physics.Raycast(ray, out RaycastHit hit, maxDistance, interactableLayer)) {
gazeTarget = hit.collider.GetComponent<IGazeable>();
gazeTarget?.OnGazeEnter();
gazeTimer += Time.deltaTime;
if (gazeTimer >= DWELL_TIME) {
gazeTarget?.OnGazeActivate();
gazeTimer = 0f;
}
} else {
gazeTarget?.OnGazeExit();
gazeTimer = 0f;
gazeTarget = null;
}
}
QR-сканирование профиля устройства
При первом запуске пользователь сканирует QR-код с корпуса Cardboard. SDK загружает lens distortion profile для конкретного корпуса. Без этого шага искажение некорректно — изображение выглядит деформированным.
Cardboard SDK сохраняет профиль в SharedPreferences / NSUserDefaults после сканирования. Добавьте на первый экран инструкцию с иконкой QR и явную кнопку «повторно отсканировать устройство» в настройках.
Процесс работы
Определение типа приложения: пассивный опыт (360-видео, тур) или интерактивный (игра, обучение).
Настройка Cardboard SDK: Unity пакет или нативная интеграция, конфигурация проекции.
Разработка сцены с учётом VR-ограничений: без acceleration locomotion, с gaze input.
Оптимизация производительности: Single Pass Instanced, foveated rendering, LOD.
Тестирование на устройствах разных ценовых сегментов, оценка комфорта.
Ориентиры по срокам
Простой пассивный VR-опыт (360-контент, базовая навигация взглядом) — 1–2 недели. Интерактивное VR-приложение с игровой механикой, множеством сцен и полным UI — 2–3 месяца.







