Камеры: от фиксированных к динамическим
lerp, а экспоненциальное сглаживание — кадронезависимое и без перелёта). Ранний 3D решал проблему в лоб: фиксированные пререндер-ракурсы (Resident Evil, FF7) + tank-управление, потому что при смене ракурса «вперёд» меняет смысл. Mario 64 (1996) впервые отдал камеру игроку (оператор-Lakitu, аналог-стик, управление относительно камеры) — смело, но «скитчево». Zelda: Ocarina of Time (1998) добила проблему Z-таргетингом: лок-он на врага кадрирует обоих и превращает движение в страйф вокруг цели. Это скопировала вся индустрия.
Камера = view-матрица, которую считает риг
Напомним конвейер: view-матрица переводит мир в пространство камеры — это обратная матрица «глаза». Построить её из позиции камеры eye и точки интереса target — это look-at: три ортонормированных оси + перенос.
forward = normalize(target − eye) // куда смотрит камера right = normalize(cross(up, forward)) // вправо (up — мировой «вверх») up' = cross(forward, right) // истинный «вверх» камеры // view = базис [right | up' | forward]ᵀ + перенос (−eye) // (соглашение +Z в кадр; в OpenGL/gluLookAt forward = eye−target, знак обратный)
Вся «работа камеры» сводится к одному вопросу: чему равны eye и target в этом кадре? В FPS просто: eye = голова игрока, target = eye + направление взгляда; камера и есть глаза. В третьем лице за это отвечает риг — небольшая система ограничений поверх позиции героя.
Риг третьего лица: штанга, коллизия, демпфер
Камера висит на штанге (spring-arm / boom) — жёстком «удилище» длины L от цели (обычно за спиной и чуть выше). Три слоя поверх:
1. Коллизия штанги. Из цели в желаемую позицию камеры пускают луч/сферу. Если на пути стена на расстоянии d < L — камеру притягивают на d (минус «кожа»-зазор), чтобы не провалиться сквозь геометрию. Пример: штанга L=4 м, стена в 2.5 м за спиной → камера садится на 2.5−0.2 = 2.3 м. Отошёл от стены — штанга плавно вытягивается обратно.
2. Демпфирование. Камера не телепортируется к цели — она догоняет. Линейный lerp с фиксированным коэффициентом зависит от fps и либо дёргает, либо перелетает. Берут экспоненциальное сглаживание (критически задемпфированное, без колебаний):
где T — целевая позиция камеры, τ — постоянная времени (меньше τ = жёстче слежение). Пример: τ=0.12 с, кадр Δt=1/60 с → множитель e^(−0.0167/0.12) ≈ 0.87, то есть камера закрывает ~13% зазора за кадр — и ровно столько же за то же время на любом fps (экспонента кадронезависима, в отличие от наивного lerp(p, T, 0.13)).
3. Look-ahead. Камеру чуть ведут в сторону движения/взгляда — игрок видит, куда бежит, а не затылок. Те же демпферы, но для смещения target.
Управление относительно камеры — и почему пререндер требовал «танка»
Аналог-стик в 3D породил вопрос: «вперёд» — это куда? Mario 64 ввёл camera-relative-конвенцию: толкнул стик «от себя» → герой бежит от камеры, влево → влево по экрану. Интуитивно, но требует, чтобы камера была предсказуемой и плавной — иначе при её рывке «вперёд» внезапно меняет смысл и героя несёт не туда.
Ранний 3D с фиксированными пререндер-ракурсами (Resident Evil 1996, поля FF7) именно от этого и страдал: камера режет с ракурса на ракурс, и «вверх на стике» каждую секунду значит новое направление. Решение — tank-управление: стик/крест поворачивает персонажа (влево/вправо — разворот, вверх — вперёд по его носу), движение отвязано от камеры вообще. Неуклюже, но переживает любую смену ракурса. Tomb Raider (1996) пошёл тем же путём; Mario 64 в том же году выбрал аналог + camera-relative — две развилки одной проблемы.
Z-таргетинг: переключение режима камеры и управления
Прорыв — Ocarina of Time (1998). Зажал Z → лок-он на враге: камера ставит в кадр обоих (героя и цель), а семантика управления меняется — боковое движение становится страйфом по кругу вокруг цели, прыжок — уклонением вбок/бэкфлипом. Фея Navi работает «личностью» этого лок-она (подсвечивает цель). Один хват разом решает и кадрирование, и наведение, и читаемость боя — то, с чем камера Mario 64 («оператор-Lakitu», смелая, но скитчевая) воевала вручную. Индустрия скопировала Z-таргетинг мгновенно; лок-он Dark Souls — прямой потомок.
Хардкор · инженерия: spring-arm, коллизия, окклюзия, виртуальные камерыможно пропустить
- Spring-arm в движках. Unreal —
SpringArmComponent(длина, лаг позиции/поворота, тест коллизии), Unity — Cinemachine с теми же ручками. Камера крепится к концу штанги, штанга делает collision-probe и демпфинг. - Sphere-cast, не ray-cast. Притягивание по тонкому лучу даёт мерцание на углах (луч проскакивает мимо края). Кастуют сферу радиусом с ближнюю плоскость камеры — камера не клиппит угол стены.
- Окклюзия ≠ коллизия. Стена между камерой и героем (а не за спиной) — отдельная беда: либо dolly-in (придвинуть камеру), либо fade/dither загораживающей геометрии, либо сделать её прозрачной. Выбор зависит от жанра.
- Критическое демпфирование. Пружина с перелётом (underdamped) даёт «качание» камеры — тошнотворно. Берут критическое (
SmoothDampUnity / экспоненту) — приходит к цели максимально быстро без колебаний. - Разделение aim/look. Куда целится игрок и куда смотрит камера — часто разные векторы (особенно в шутерах от третьего лица): прицел по центру экрана, камера демпфирована — иначе дрожание прицела передаётся в картинку.
- Виртуальные камеры + блендинг. Современный подход (Cinemachine): расставить «виртуальные камеры» на ситуации, движок блендит между ними по приоритету — режиссура без хардкода в одном монолитном контроллере.
Хардкор · дизайн: кадрирование, читаемость и тошнотаможно пропустить
- Не отнимай управление резко. Худшее — выдрать камеру из рук игрока в неожиданный момент. Если нужно срежиссировать ракурс (катсцена, узкий коридор) — делай это плавно и предсказуемо, верни управление так же мягко.
- Композиция. Правило третей, «воздух» над головой (headroom), вести взгляд по ходу движения (look-ahead). Камера — оператор: герой не должен елозить в углу кадра.
- Тошнота (motion sickness). Триггеры: высокий FOV-мисматч с реальным углом обзора, лаг камеры/ввода, тряска и автоматическое качание, резкие непрошеные повороты. Бюджет camera-shake — маленький; опция отключить — обязательна.
- FOV и скорость. Шире FOV → сильнее ощущение скорости и периферия (но искажение краёв и риск тошноты); уже → «телефото», спокойнее, но клаустрофобно. FOV — это и game feel (см. модуль 9), и комфорт.
- Первое vs третье лицо. FPS — максимальная иммерсия и точность прицела, но нулевая периферия и не видно своего тела/окружения за спиной. Третье лицо — обзор и «вижу персонажа», ценой того, что камера сама становится игровой системой со своими багами.
Робототехника / CV: view-матрица = экстринсики камеры (поза в мире); «эгоцентрическая vs аллоцентрическая» система координат — буквально выбор eye/target. Spring-arm с коллизией = крошечная задача constraint-solving, родня обратной кинематике (IK) манипулятора.
ML / AI: экспоненциальное демпфирование камеры — это EMA (экспоненциальное скользящее среднее), тот же приём, что momentum в SGD, Polyak-усреднение target-сетей в RL и сглаживание метрик: «иди к цели, но гладко, гася рывки». View-матрица и проекция — это экстринсики+интринсики в NeRF / 3D Gaussian Splatting / SfM, где они дифференцируемы и оптимизируются. Эгоцентрический кадр — основа embodied-агентов и robot learning.
UX / визуализация: «следуй за фокусом, но плавно» — автоскролл к активному элементу, smooth-pan карт, камера-облёт в 3D-вьюверах; критическое демпфирование, чтобы не было перелёта и качания.
Принцип: выбери систему отсчёта под наблюдателя; следуй за целью демпфированно (гаси рывки экспонентой, без колебаний); и разрули конфликтующие ограничения маленьким решателем, а не кучей if.
SpringArm3D + Camera3D на персонажа; в Unreal — SpringArmComponent (включи bDoCollisionTest, CameraLag). Загони героя спиной в стену — увидишь притягивание камеры; покрути длину штанги и лаг/демпфер (жёстко→дёргано, мягко→плывёт, найди критическое). Поставь столб между камерой и героем — поймай окклюзию, попробуй прозрачность/dolly-in. Добавь camera-relative управление и lock-on-режим (страйф вокруг цели) — мини-Z-таргет.🕹 В какие игры поиграть — и что заметить
Эволюция от «камеру вообще не двигаем» к управляемому ригу и лок-ону. По каждому: что внутри и во что сыграть, чтобы почувствовать.
Камера не двигается вовсе — заранее срежиссированные пререндер-ракурсы, между которыми идут резкие катсы. Чтобы управление пережило смену ракурса, движение отвязали от камеры: tank-управление (поворот корпуса + «вперёд по носу»).
🎮 Сыграй: в Resident Evil (или поля FF7) пройди через границу комнаты — камера режет на новый ракурс, и если бы управление было camera-relative, «вперёд» тут же сменило бы смысл. Почувствуй, зачем нужен «танк»: он один и тот же при любом ракурсе.
Первая серьёзная динамическая камера в руках игрока: её «держит» Lakitu-оператор (диегетически — снимает Марио на удочке-камере), C-кнопки крутят ракурс, движение — относительно камеры через аналог-стик. Смело и до сих пор играбельно, но камера временами «скитчевая» — застревает, теряет угол в тесноте.
🎮 Сыграй: в Mario 64 зайди в узкий коридор или угол — почувствуй, как камера дёргается и борется за ракурс (C-кнопками доводишь вручную). Это передовая 1996-го и одновременно список проблем, которые решит Zelda через два года.
Лок-он как режим камеры и управления: зажал Z — камера кадрирует героя и цель, движение становится страйфом по кругу, прыжки — уклонениями. Navi — «личность» лок-она. Решило ровно те беды, с которыми мучился Mario 64.
🎮 Сыграй: в OoT (или 3DS-ремейке) подерись с врагом, зажав Z: камера сама держит обоих в кадре, ты кружишь и блокируешь, не думая о ракурсе. Отпусти Z — и вернётся вся морока свободной камеры. Один хват = решённая проблема.
Камера-«хвост» за Ларой плюс tank-управление: компромисс между следящей камерой и неоднозначностью направления. Прямой предок «traversal»-камеры Uncharted (модуль 5).
🎮 Сыграй: в Tomb Raider у края платформы заметь, как камера то следует, то упирается в стену, а управление остаётся «танковым» — поворот Лары, а не экранное «вперёд». Контраст с аналогом Mario 64 того же года.
Тот же скелет, доведённый до блеска: spring-arm с коллизией и демпфером, lock-on-страйф (прямой наследник Z-таргета в Dark Souls), бесшовная камера без катов (God of War 2018 — весь сюжет «одним кадром»).
🎮 Посмотри: в любой соулс-игре включи лок-он на босса — это Z-таргетинг 1998-го. В God of War 2018 обрати внимание, что камера ни разу не режет — один непрерывный план; это инженерия рига, а не магия. В Unreal-демо с SpringArm загони камеру в стену — увидишь притягивание из этого урока.
eye и target каждый кадр.Почему пререндер-ракурсы вынуждали к tank-управлению, а не наоборот?
Математика view-матрицы простая — почему тогда камера «самое сложное» в 3D?
Почему демпфируют экспонентой, а не линейным lerp или пружиной?
lerp(p, T, k) с фиксированным k зависит от fps (на 30 и 144 Гц камера догоняет с разной скоростью) и либо дёргает, либо мажет. Пружина с инерцией (underdamped) перелетает и качается — тошнотно. Экспоненциальное / критически задемпфированное сглаживание приходит к цели максимально быстро без колебаний и кадронезависимо (множитель e^(−Δt/τ) учитывает реальный Δt). Поэтому индустрия осела на SmoothDamp/экспоненте, а не на наивном lerp.Зачем Z-таргетинг меняет ещё и управление, а не только камеру?
Почему высокий FOV даёт «скорость», но и тошноту?
Почему sphere-cast, а не ray-cast для коллизии штанги?
- Mark Haigh-Hutchinson, «Real-Time Cameras» — настольная книга по игровым камерам (риги, коллизия, демпфирование).
- Game Maker's Toolkit — разборы камер Mario 64 и Z-таргетинга Ocarina of Time.
- Iwata Asks: Ocarina of Time — как Nintendo пришла к Z-таргету и метафоре Navi.
- Unreal
SpringArmComponent/ Unity Cinemachine — документация по продакшн-ригам. - GDC: камера God of War (2018) — бесшовный «один план» в 3D от третьего лица.
- Модуль 3 (
03-3d-revolution-1993-1999.md), раздел «Camera Systems».