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 каждый кадр.
  • Перспектива возникает из деления координат на глубину.
  • Ортография сохраняет размеры (чертежи), перспектива их сжимает с расстоянием.
  • Параллельные линии в перспективе сходятся в точку схода.
Проверьте себя
1. Что создаёт эффект перспективы при проекции?
AСложение координат
BДеление координат на глубину z
CУмножение на цвет
DСортировка пикселей
2. Чем ортографическая проекция отличается от перспективной?
AОна цветная
BОна сохраняет размеры объектов независимо от расстояния
CОна работает только в 2D
DОна быстрее в 1000 раз
3. Сколько координат у точки в 3D-пространстве (до однородных)?
AОдна
BДве
CТри
DЧетыре