2D и 3D графика: в чём разница
3D-графика рисует мир с глубиной, но экран плоский — значит, объём нужно спроецировать в плоскость.
3D-рендеринг — построение плоского изображения трёхмерной сцены через проекцию из точки наблюдения (камеры).
Зачем это знать
Новички часто думают, что 3D «само» выглядит объёмным. На деле каждый кадр — это плоская картинка, полученная проецированием трёхмерных точек на экранную плоскость. Понимание проекции — ключ к матрице вида и матрице проекции, которые мы разберём дальше.
2D: координаты прямо на экране
В 2D объект задаётся координатами (x, y), которые более-менее напрямую соответствуют пикселям. Спрайт, кнопка, текст — всё лежит в одной плоскости, есть только порядок наложения (слои, z-order).
3D: объём и проекция
В 3D у точки есть (x, y, z). Чтобы показать её на экране, систему нужно «сфотографировать» камерой. Простейшая модель — перспективная проекция: чем дальше объект (больше z), тем сильнее он сжимается к центру, как в реальной фотографии. Деление на глубину — суть перспективы.
# Простейшая перспективная проекция точки на экран
def project(x, y, z, focal=1.0):
# деление на глубину z даёт эффект перспективы
sx = focal * x / z
sy = focal * y / z
return round(sx, 3), round(sy, 3)
print("Близкий объект z=1:", project(1, 1, 1))
print("Далёкий объект z=5:", project(1, 1, 5))
print("Очень далёкий z=20:", project(1, 1, 20))
Вывод:
Близкий объект z=1: (1.0, 1.0) Далёкий объект z=5: (0.2, 0.2) Очень далёкий z=20: (0.05, 0.05)
Один и тот же по размеру объект на экране становится тем меньше, чем он дальше — это и есть перспектива через деление на глубину.
Перспектива: дальние объекты сходятся к точке схода |\ | \___ | \___ | ### \___ <- рельсы сходятся | ### ___/ | ___/ |/ глаз/камера
Как работает под капотом
Полный путь: 3D-вершины проходят серию матричных преобразований (об этом — следующий урок), попадают в так называемое clip space, затем выполняется перспективное деление — деление на координату w (которая несёт глубину). После него остаются нормализованные координаты от -1 до 1, которые растягиваются на пиксели экрана. Параллельные линии, уходящие вдаль, после такого деления сходятся в точку схода — отсюда реалистичность.
Частые ошибки
- Думать, что 3D хранит готовую объёмную картинку — нет, объём считается заново каждый кадр.
- Путать ортографическую проекцию (без перспективы, для чертежей и 2D-игр) с перспективной.
- Забывать, что без деления на глубину дальние и ближние объекты выглядели бы одинакового размера.
Итоги
- Экран всегда плоский — 3D-сцена проецируется в 2D каждый кадр.
- Перспектива возникает из деления координат на глубину.
- Ортография сохраняет размеры (чертежи), перспектива их сжимает с расстоянием.
- Параллельные линии в перспективе сходятся в точку схода.