Что такое глубина (depth)?

Буфер/карта глубины для меня начинающего таили множество секретов и генерировали еще большее множество вопросов. Лишь только со временем мне удавалось находить на них ответы, основываясь на своем опыте. В данной статье я попробую донести понятным изложением суть понятия глубины в контексте программирования графики.

Примечание: тема рассматривается в контексте GAPI с аппаратной поддержкой + я знаком больше с DirectX чем с OpenGL. Статья не претендует на научную точность трактования и более того в статье я излагаю свой опыт (основанный на организации deferred shading, построении системы материалов pbr а также не самого плохого постпроцесса в движке SkyXEngine) и свои догадки. Возможно в каких-то моментах я ошибся и был некомпетентен, просьба неравнодушным: напишите об этом в комментариях с указанием ошибки и правльным изложением.

Глубина, общие теоретические моменты

Карта линейной глубины ( движок SkyXEngine)
Карта линейной глубины ( движок SkyXEngine)

Глубина (depth) — одно из понятий в трехмерной графике, характеризующая пространство либо объект.

В контексте пространства, глубина рассматривается в пространстве наблюдателя (камеры), и каждый элемент глубины характеризует расстояние от наблюдателя до ближайшей видимой точки. Расстояние в данном случае необязательно может измеряться в метрах, оно может быть линейным, то есть камера может иметь максимально допустимую дальность видимости, и в данном случае расстояние будет описано коэффициентом (гиперболическим либо линейным).

В контексте объекта глубина, наравне с шириной и высотой характеризует габариты объекта.

Примечание: далее pos — это позиция пикселя трансформированная мировой, видовой и проекционной матрицей, то есть pos это трехмерная координата пикселя в пространстве наблюдателя, а z координата в данном случае будет является расстоянием от камеры до этого пикселя..

Гиперболическое распределение глубины (гиперболическая глубина) — тип распределения глубины, который формируется путем pos.z/pos.w. Данный тип распределения свойственен аппаратной генерации глубины.

Линейное распределение глубины (линейная глубина) — тип распределения глубины, который формируется путем pos.z/far где far это значение дальней плоскости, или по простому — максимальная дальность видимости в метрах.

Буфер глубины

Буфер глубины (Z-buffer, depth buffer) — двумерный массив данных, имеющий размеры по ширине (X) и высоте (Y), предназначенный для определения дистанции от наблюдателя (камеры) до точки в сцене. Каждый элемент буфера глубины соответствует пикселю на экране.

Как правило буфер глубины (сгенерированный аппаратно) имеет гиперболическое распределение.

Разрядность буфера глубины имеет огромное значение. В основном используются 2 вида разрядности:

  • 16 бит — невысокая точность, низкое качество сортировки, поддерживается всеми (условно) видеокартами
  • 24 бит — хорошая точность, классика, именно эта разрядность используется большинством приложений,  поддерживается всеми (условно) видеокартами.

Совместно с буфером глубины сосуществует и стенсил (stencil)  буфер (буфер трафарета), который занимает 8 бит в случае 24 разрядного буфера глубины. Нужен ли буфер трафарета или нет зависит от требований, нам в движке он очень пригодился при формировании буфера освещения, так как у нас deferred shading.

На основе буфера глубины вычислительное устройство (видеокарта) определяет виден ли пиксель наблюдателю или нет? В данном случае пиксель может быть виден только если он не перекрыт более ближним к камере пикселем, а невидимый пиксель всегда будет закрыт более ближним к камере.

Основная суть работы Z-буферизации это сортировка текущего пикселя и предыдущего (записанного в буфер глубины) на основании значения их глубины и выявление самого ближнего пикселя в пост-перспективном пространстве (в пространстве камеры/наблюдателя).

Z-test — тест видимости пикселя на основании сравнения его глубины и глубины ранее записанной в буфере глубины. Функции теста могут быть следующими (то есть новый пиксель будет нарисован в случае выполнения условия):

  • false (NEVER) — тест никогда не проходит, то есть новые пиксели не будут нарисованы
  • new <  old (LESS) — глубина нового пикселя должна быть меньше чем глубина старого
  • new == old (EQUAL) — глубина нового пикселя должна быть равна глубине старого
  • new <= old (LESS_EQUAL) — глубина нового пикселя должна быть меньше либо равна глубине старого пикселя
  • new >  old (GREATER) — глубина нового пикселя должна быть больше глубины старого
  • new != old (NOT_EQUAL) — глубина нового пикселя не должна быть равной глубине старого
  • new >= old GREATER_EQUAL — глубина нового пикселя должна быть больше либо равной глубине старого
  • true (ALWAYS) — тест проходит всегда, то есть все пиксели буду нарисованы (а итоговый результат в позиции пикселя будет в виде самого последнего)

Early Z test (ранний Z-test) — тест глубины, который осуществляется до пиксельного (фрагментного шейдера), в случае если изменение глубины в буфере глубины отключено. Однако бытует мнение что есть множество, причин по которым Early Z test может не сработать.

Z-fighting — ситуация, при которой из-за нехватки точности диапазона значений в буфере глубины пиксели, находящиеся на очень близком расстоянии друг от друга, попеременно перекрывают друг друга в зависимости от поворота камеры. Также такая ситуация может возникнуть в случае указания очень малого near (ближней плоскости отсечения), в следствие чего на ближних расстояниях может не хватить точности из-за неравномерного распределения значений по всему вектору допустимых значений.

Карта глубины

Карта глубины (depth map) — текстура содержащая в себе информацию о глубине. Карта глубины это визуализированный буфер глубины.

Характеристика карты глубины:

  • во многих случаях имеет линейное распределение [0,1] где 0 ближняя плоскость, а 1 дальняя.
  • может отличаться от размеров буфера глубины, все зависит от целей ее использования.
  • может содержать иной диапазон данных нежели буфер глубины.

Необходимость в карте глубины возникает тогда когда появляется необходимость в более прогрессивных технологиях, которые не может предоставить фиксированный конвейер. К примеру в deferred shading без карты глубины не обойтись. Для многих эффектов пост процесса также необходима карта глубины. А для генерации теней на подобии shadow map, без карты глубины не обойтись (чтобы не рисовать сцену повторно).


Глубина это ключевой аспект в трехмерной графике, участвующий в формировании итогового изображения и характеризующий его, наравне с шириной и высотой.

Статья о post process, в ней я затрагиваю моменты касаемо получения карты глубины.

Рекомендую также почитать:

Поделиться:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*