Skip to content

Система координат WebGPU

Что уже должно быть понятно:

Что появится в этой главе:

  • какие системы координат проходит вершина на пути к экрану
  • почему clip space от -1 до 1
  • перспективное деление
  • правосторонняя система координат в WebGPU

Итог: теоретическая глава — визуального результата нет, но без понимания этого пути вершины на экран невозможно осознанно работать с проекциями


Каждая вершина проходит через несколько систем координат, прежде чем попасть на экран. Понимание этого пути объяснит, зачем нужны матрицы проекции и что делает GPU под капотом.

Путь вершины

Object space

Координаты относительно центра объекта. Вершины куба от -0.5 до 0.5 — это object space. Куб «не знает», где он находится в мире.

World space

Координаты в общей системе сцены. Model-матрица переводит object space → world space: сдвигает, поворачивает и масштабирует объект на нужное место.

View space (eye space)

Координаты относительно камеры. View-матрица перестраивает мир так, что камера оказывается в начале координат и смотрит вдоль оси -Z (в правосторонней системе).

Clip space

Результат умножения на projection-матрицу. Координаты всё ещё однородные (x,y,z,w). GPU проверяет, что wxw, wyw, 0zw — если вершина не попадает в этот объём, она отсекается.

Frustum: область видимости камеры

Область видимости камеры называется frustum — усечённая пирамида. Near и far задают диапазон глубины, FOV — угол обзора. Объекты за пределами frustum не рисуются.

NDC (Normalized Device Coordinates)

После перспективного деления (x/w, y/w, z/w) координаты становятся в диапазоне:

  • x: [1,1] (слева направо)
  • y: [1,1] (снизу вверх)
  • z: [0,1] (от ближней плоскости к дальней) — это отличие от OpenGL, где z[1,1]

Screen space

NDC преобразуются в пиксели экрана через viewport:

pixelx=ndcx+12widthpixely=1ndcy2height

Ось y инвертируется: в NDC она направлена вверх, а на экране пиксели считаются сверху вниз.

Правосторонняя система координат

WebGPU использует правостороннюю систему:

  • +X — вправо
  • +Y — вверх
  • +Z — на наблюдателя (из экрана)
Правосторонняя система координат: +X вправо, +Y вверх, +Z на наблюдателя

Проверка «правило правой руки»: если указательный палец — X, средний — Y, то большой палец указывает направление Z.

По соглашению камера смотрит вдоль -Z. Это значит, что объекты перед камерой имеют отрицательные координаты Z в view space — projection-матрица переворачивает ось Z так, чтобы ближние объекты имели меньшее значение глубины.

Перспективное деление

В clip space координаты — однородные (x,y,z,w). Projection-матрица подготавливает w так, что он равен глубине точки относительно камеры. GPU автоматически делит:

ndcx=clipxclipw,ndcy=clipyclipw,ndcz=clipzclipw

Это создаёт эффект перспективы — далёкие объекты (большой w) сжимаются к центру экрана (малые ndcx, ndcy). Ближние объекты (малый w) растягиваются.

Числовой пример: вершина через все пространства

Пусть вершина куба находится в позиции (1,1,5) в object space. Куб сдвинут на (3,0,0) в world space. Камера в точке (0,0,5) смотрит вдоль Z.

1. Object → World (model = сдвиг на (3,0,0)):

pworld=(1+3, 1+0, 5+0)=(4, 1, 5)

2. World → View (view matrix: камера в (0,0,5), смотрит вдоль Z — все Z смещаются на 5):

pview=(4, 1, 55)=(4, 1, 10)

3. View → Clip (perspective_rh с fov=45°, aspect=1, near=0.1, far=100):

Projection-матрица преобразует Z в диапазон [0,1], а w становится равным |zview|:

pclip(9.66, 2.41, 9.9, 10.0)

4. Clip → NDC (перспективное деление):

ndcx=9.6610=0.966,ndcy=2.4110=0.241,ndcz=9.910=0.99

Z = 0.99 — почти на дальней плоскости (1.0 = far). X и Y в пределах [1,1] — вершина видима.

5. NDC → Screen (окно 800×600):

pixelx=0.966+12800=786,pixely=10.2412600=228

Вершина отобразится в пиксель (786,228) — правая часть окна, ближе к верху.

Типичные ошибки

Диапазон Z в NDC

В WebGPU Z-координата в NDC находится в диапазоне [0,1], а не [1,1] как в OpenGL. Если переносите код или формулы из OpenGL-туториалов, учтите это — иначе объекты будут отсекаться неправильно.

Нулевая ближняя плоскость

Значение near = 0 в perspective_rh приведёт к делению на ноль при перспективном делении. Ближняя плоскость отсечения всегда должна быть строго больше нуля — типичное значение 0.1.

Направление оси Y на экране

В NDC ось Y направлена вверх (+Y), но на экране пиксели считаются сверху вниз. Формула преобразования инвертирует Y: pixely=1ndcy2height. Путаница в знаке — частая причина «перевёрнутого» рендера.

Попробуйте сами

Упражнение 1

Подставьте в числовой пример из главы координаты вершины (-1, -1, -3) вместо (1, 1, -5) и проследите путь через все системы координат до экранных пикселей. Попадёт ли вершина на экран?

Упражнение 2

Уменьшите дальнюю плоскость отсечения до far = 5.0 в перспективной проекции. Подумайте: какие вершины из числового примера окажутся отсечёнными и почему?

Упражнение 3

Проверьте «правило правой руки» для системы координат WebGPU: убедитесь, что ось +Z действительно направлена на наблюдателя, вычислив cross product осей X и Y: (1,0,0)×(0,1,0)=(0,0,1).


С этими знаниями мы готовы к следующей главе, где применим model, view и projection матрицы на практике.

Опубликовано под лицензией CC-BY-4.0