Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Термины / Буфер глубины (Z-buffer)

Буфер глубины (Z-buffer)

Буфер глубины (Z-buffer, depth buffer) — двумерный массив данных, дополняющий двумерное изображение, где для каждого пикселя (фрагмента) изображения сопоставляется «глубина» (расстояние от наблюдателя до поверхности изображаемого объекта).

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

Буфер глубины может иметь различную разрядность данных:

  • 16 бит. Устаревший формат с невысокой точностью. На современных видеокартах используется редко, например для рендера в текстуру глубины на картах АТИ Радеон 9***, которые не поддерживают получения данных буфера глубины более высокой разрядности.
  • 24 бита. Можно сказать, стандартный тип данных буфера глубины, в основном используется он.
  • 32 бита. Формат ещё более высокой точности, но совершенно не распространён, не стоит рассчитывать на его поддержку.

Если для отрисовки нужен буфер трафарета, то данные для него будут расположены вместе с данными буфера глубины. Например, при использовании 24-битного буфера глубины на один фрагмент изображения будет приходиться 32 бита данных (не считая цвета), 8 бит которых будут представлять данные буфера трафарета.

Проверка видимости этим методом на современных видеокартах может проводиться в двух местах:
а) До выполнения фрагментного шейдера (early Z test), если фрагментный шейдер не изменяет глубину фрагмента (впрочем, вполне могут быть и другие условия, по причине которых early Z test проводиться не будет). Дополнительно к этому, современные видеокарты могут отбрасывать сразу целые блоки фрагментов, что ещё более повышает производительность.
б) После выполнения фрагментного шейдера.

Проверка производиться с использованием значения глубины текущего фрагмента в пост- проективном пространстве и предыдущего значения, хранящегося в буфере глубины. Сравнение происходит с использованием функции, выбранной пользователем. Доступны следующие функции:

ДействиеНазвание в Direct3D10Название в Direct3D9Название в OpenGL
falseD3D10_COMPARISON_NEVERD3DCMP_NEVERGL_NEVER
Znew <  ZoldD3D10_COMPARISON_LESSD3DCMP_LESSGL_LESS
Znew == ZoldD3D10_COMPARISON_EQUALD3DCMP_EQUALGL_EQUAL
Znew <= ZoldD3D10_COMPARISON_LESS_EQUALD3DCMP_LESSEQUALGL_LEQUAL
Znew >  ZoldD3D10_COMPARISON_GREATERD3DCMP_GREATERGL_GREATER
Znew != ZoldD3D10_COMPARISON_NOT_EQUALD3DCMP_NOTEQUALGL_NOTEQUAL
Znew >= ZoldD3D10_COMPARISON_GREATER_EQUALD3DCMP_GREATEREQUALGL_GEQUAL
trueD3D10_COMPARISON_ALWAYSD3DCMP_ALWAYSGL_ALWAYS

Где Znew значение глубины фрагмента и Zold предыдущее значение глубины.
Функция сравнения устанавливается функциями IDirect3DDevice::SetRenderState(D3DRS_ZFUNC, func) в DirectX, и glDepthFunc(func) в OpenGL. Также для работы следует включить тест глубины функциями IDirect3DDevice::SetRenderState(D3DRS_ZENABLE, true) в DirectX, и glEnable(GL_DEPTH_TEST) в OpenGL.

После того как тест пройден, новое значение записывается в буфер глубины. В некоторых алгоритмах требуется отключить данный шаг. Это делается вызовами IDirect3DDevice::SetRenderState(D3DRS_ZWRITEENABLE, false) или glDepthMask(false); значение по умолчанию - true.

Значение глубины точки можно рассчитать при помощи следующей формулы:
z' = zfar + znear + 1 * (-2 * zfar * znear)
        zfar - znear    z *    (zfar - znear)

Полученное значение z' затем нормализуется в диапазон [0; 1], где 0 — у ближней плоскости отсечения, и 1 — у дальней.
Значения глубины точки не находятся в линейной зависимости от расстояния до камеры. Значения у ближней плоскости расположены очень плотно, а с увеличением дальности к дальней плоскости отсечения всё более редко. По этой причине нужно следить за расстояниями, на которых вы ставите плоскости отсечения: ближнюю плоскость не стоит ставить слишком близко! В противном случае можно получить множество артефактов изображения вдали, в особенности z-fighting, когда небольшое изменение ракурса камеры может изменить видимость близко расположенных треугольников.

Что такое Буфер глубины (Z-buffer)?

19 апреля 2007

#буферы, #Direct3D, #OpenGL, #pipeline


Обновление: 17 ноября 2009

2001—2017 © GameDev.ru — Разработка игр