Z-буферизація

Принцип дії Z-буфера

Z-буферизація (англ. Z-buffering) (інша назва: глибинна буферизація (англ. depth buffering)) — алгоритм який відповідає за створення зображень 3D-об'єктів спираючись на глибину елементів зображення. Зазвичай реалізується на апаратному рівні, іноді в програмному забезпеченні. Є одним з рішень проблеми видимості об'єктів та попіксельним узагальненням алгоритму художника.

При створенні (візуалізації) 3D-об'єкту, його глибина генерується на осі Z-координат і зберігається у Z-буфері. Сам буфер, зазвичай, являє собою двомірний масив X-Y координат із одним елементом (глибиною) для кожного екранного пікселя. Коли інший об'єкт сцени повинен бути відображений у цьому пікселі зараз, тоді порівнюється дві глибини та перекривається поточний піксель, якщо об'єкт знаходиться ближче до спостерігача. Обрана глибина зберігається в Z-буфері і замінює попередню. Зрештою, Z-буфер дозволяє правильно відтворювати звичне для нас сприйняття глибини: ближчий до нас об'єкт перекриває наступні, що розташовуються за ним — невидимих поверхонь.

Для Z-буферизації є критичним роздільна здатність буферу. Чим вона вища, тим краще відображаються глибина об'єктів сцени. Так, 16-розрядний буфер дозволяє порівняти за глибиною лише 64 тис. точок. Можуть з'явитися так звані артефакти (англ. z-fighting) — коли два об'єкти знаходяться дуже близько один до одного але мають однакову глибину. Тоді як Z-буфер на 24 розряди, має роздільну здатність 16 млн, 32 розряди — вже два мільярди.

Використання

Z-буферизація дозволяє поєднувати 2D елементи у тривимірному просторі, створюючи декорації, а також складні ефекти такі як відображення різних типів поверхонь. Наприклад, 3D-редактор Maya дозволяє виконувати пост-рендеринг текстур для одного об'єкту, при цьому використовуючи кілька буферів на кшталт Z-буферу: α-буфер (α — коефіцієнт прозорості); ідентифікатор об'єкту; координати розгортки (англ. UV mapping) та будь-які інші координати необхідні для пост-обробки, економлячи при цьому час на моделювання, оскільки без їх використання потрібно-б було повторно створювати об'єкт. Z-буфер, містить дані для отримання рендерінгу (візуалізації) відображення поверхонь, дозволяє створювати тіні в scanline візуалізації, проектуючи Z-буфер вниз створюючи ефект тіні. Цей процес аналогічний до того, який називають не-трасовані промені (англ. non-raytracing) та використовують у безкоштовних та відкритих 3D-пакетах.

Еволюція

При недостатньо великому ступені деталізації, можуть виникати проблеми з якістю. Коли значення відстані, що містяться у Z-буфері, нерівномірно розподілені на всій відстані. Ближчі значення завжди точніші і відображаються краще, ніж ті, які знаходяться далі. Як правило, це і потрібно, проте іноді це викликає артефакти зображення — коли дальній об'єкт перекривається ближнім. Z-буферизація, яка дозволяє точніше розподіляти зображення називають — W-буферизація. Кожна нова сцена спричинює очищення Z-буфера, щоб отримати нове значення, як правило — 1 або 0, оскільки ці значення є крайніми для визначення глибини (у шкалі від 0 до 1), тобто об'єкт присутній/не присутній в цій точці видимого простору. Винахід Z-буферизації пов'язують із іменем Едвіна Кетмелла, хоча сам процес вперше описав Волфган Штрассер (Wolfgang Straßer) у своїй дисертації 1974 року1.

На сучасних комп'ютерних 3D відеокартах, в процесі створення зображення, Z-буферизація використовує значний об'єм доступної пам'яті. Тому, одним із головних завдань для виробників обладнання стає зменшення використання пам'яті Z-буфером, не зменшуючи при цьому якості зображення. Так, одним із методом Z-Compression є стиснення й розпакування зображення буферу, оскільки воно займає менше пам'яті. Іншим методом є Fast Z-Clear швидке очищення Z-буфера. Після побудови і виведення зображення на екран, інформація, що розміщується у Z-буфері, вже неактуальна тому стирається. Z-буфер обнуляється, але вже не записуються окремі значення, а використовуються блоки які заміщають кілька значень одразу.

Відсікання невидимих поверхонь

Перекриття об'єктів або англ. Z-fighting

У процесі візуалізації, відсікання невидимих поверхонь на основі глибини (англ. Z-culling), дозволяє збільшити продуктивність при його рендерінгу, проте, є доволі ресурсомісткими. Це прямий наслідок Z-буферизації, коли глибина кожного пікселю порівнюється із глибиною наявної геометрії, за яким вона може бути прихована.

При використанні Z-буфера піксель відсікаються чи не відсікаються, як тільки стає відомою його глибина, це дозволяє уникнути процес текстурування й освітлення того пікселю, який ми не бачимо в сцені за будь-яких обставин. До того-ж, значні ресурси системи, які були б потрібні при прорисовці піксельних шейдерів, як правило, не виконуються для відсічених пікселів. Це робить відсікання невидимих поверхонь хорошим кандидатом для оптимізації, в ситуаціях, коли швидкість текстурування, освітлення, або піксельних шейдерів є вузьким місцем. У той час, Z-буферизація дозволяє геометрії, сортувати полігони за рахунок збільшення глибини(при цьому використовує алгоритм зворотної палітри — алгоритм художника) і дозволяє на кожен екранний піксель витрачати менший час. Це може збільшити продуктивність в швидких сценах, з великою кількістю перерисовок, але таке поєднання із Z-буферизацією страждає серйозними проблемами, такими як:

Полігони послідовно закривають один одного.
  • полігони можуть перекривати один одного (трикутник А закриває В, В закриває С, С закриває А) і
  • неможливо визначити «найближчу» до глядача точку на трикутнику (наприклад, якщо сортувати трикутники за центроїдом, найближчою чи найвіддаленішою точкою, то все одно можлива ситуація, що А «ближчий» ніж В, але трикутник В повинен бути зображений першим).

Таким чином, алгоритм зворотної палітри не може бути використаним як альтернатива до процесу відсікання невидимих поверхонь, за винятком оптимізації. Для прикладу: для оптимізації ми можемо отримати полігони сортовані у X-Y координатах і Z — глибиною, що забезпечує межу, для швидкого визначення двох полігонів що можуть перекривати один одного.

Алгоритм

Дано: список полігонів {P1, P2, …, Pn}

Вихід: кольоровий масив, що показує інтенсивність відображення поверхонь полігона.

Введення:

note : z-depth and z-buffer(x, y) is positive...
           z-buffer(x,y)=max depth; and
           COLOR(x,y)=background color.


Початок

for : (each polygon P in the polygon list)
      do{
          for(each pixel(x,y) that intersects P) 
          do{
               Calculate z-depth of P at (x,y)
               If (z-depth < z-buffer[x,y]) 
               then{
                      z-buffer[x,y]=z-depth;
                      COLOR(x,y)=Intensity of P at(x,y);
                   }
            }
        }
  display COLOR array.

Математика

Діапазон значень глибини в просторі (3D проєкція) візуалізація значень, таких як близько n e a r {\displaystyle {\mathit {near}}} і далеко f a r {\displaystyle {\mathit {far}}} та значенням z {\displaystyle z} . Після перетворення, проєкція перспективи змінюється на нові значення з z {\displaystyle z} на z {\displaystyle z'} , це визначається за формулою: z = f a r + n e a r f a r n e a r + 1 z ( 2 f a r n e a r f a r n e a r ) {\displaystyle z'={\frac {{\mathit {far}}+{\mathit {near}}}{{\mathit {far}}-{\mathit {near}}}}+{\frac {1}{z}}\left({\frac {-2\cdot {\mathit {far}}\cdot {\mathit {near}}}{{\mathit {far}}-{\mathit {near}}}}\right)} Після цього проєкція отримує нові значення z {\displaystyle z} , або z {\displaystyle z'} визначається за формулою: z = 2 z n e a r f a r n e a r 1 {\displaystyle z'=2\cdot {\frac {{z}-{\mathit {near}}}{{\mathit {far}}-{\mathit {near}}}}-1} якщо, z {\displaystyle z} має старе значення z {\displaystyle z} у просторі її часто називають w {\displaystyle w} або w {\displaystyle w'} . Отримані значення z {\displaystyle z'} урівнюють між значенням −1 та 1, де n e a r {\displaystyle {\mathit {near}}} значення площини від −1 та f a r {\displaystyle {\mathit {far}}} площина, яка дорівнює 1. Значення за межею цього діапазону є точкам невидимого простору, тому не відображаються.

Відображення нерухомої коми

Як правило, всі значення зберігаються у Z-буфері відеокарти в форматі фіксованої точки. Спочатку їх приводять до більш загальних значень [0,1] шляхом заміни відповідних перетворень z 2 = ( z 1 + 1 ) 2 {\displaystyle z'_{2}={\frac {\left(z'_{1}+1\right)}{2}}} згідно попередньої формули: z = f a r + n e a r 2 ( f a r n e a r ) + 1 z ( f a r n e a r f a r n e a r ) + 1 2 {\displaystyle z'={\frac {{\mathit {far}}+{\mathit {near}}}{2\cdot \left({\mathit {far}}-{\mathit {near}}\right)}}+{\frac {1}{z}}\left({\frac {-{\mathit {far}}\cdot {\mathit {near}}}{{\mathit {far}}-{\mathit {near}}}}\right)+{\frac {1}{2}}}

Наступним кроком, згідно наведеної вище формули, є множення S = 2 d 1 {\displaystyle S=2^{d}-1} де d — глибина Z-буфера (зазвичай 16, 24 чи 32 біти), отриманий результат округлюється до цілого числа:[1]

z = f ( z ) = ( 2 d 1 ) ( f a r + n e a r 2 ( f a r n e a r ) + 1 z ( f a r n e a r f a r n e a r ) + 1 2 ) {\displaystyle z'=f\left(z\right)=\left\lfloor \left(2^{d}-1\right)\cdot \left({\frac {{\mathit {far}}+{\mathit {near}}}{2\cdot \left({\mathit {far}}-{\mathit {near}}\right)}}+{\frac {1}{z}}\left({\frac {-{\mathit {far}}\cdot {\mathit {near}}}{{\mathit {far}}-{\mathit {near}}}}\right)+{\frac {1}{2}}\right)\right\rfloor }

Ця формула може бути оберненою і утворює у розрахунках Z-буфера так звану «зернистість», про яку говорилось вище. Оберненим до цього f ( z ) {\displaystyle f\left(z\right)} :

z = f a r n e a r z S ( f a r n e a r ) f a r = S f a r n e a r z ( f a r n e a r ) f a r S {\displaystyle z={\frac {-{\mathit {far}}\cdot {\mathit {near}}}{{\frac {z'}{S}}\left({\mathit {far}}-{\mathit {near}}\right)-{far}}}={\frac {-{\mathit {S}}\cdot {far}\cdot {\mathit {near}}}{z'\left({\mathit {far}}-{\mathit {near}}\right)-{far}\cdot S}}}

where S = 2 d 1 {\displaystyle S=2^{d}-1}

Роздільна здатність Z-буфера — термін коли точка огляду (камера) отримує додаткові значення результатів мінімальних змін і зберігає їх у Z-буфері як значення +1 чи −1. Тому роздільна здатність може бути розрахована з похідного z {\displaystyle z} as a function of z {\displaystyle z'} :


d z d z = 1 1 S f a r n e a r ( z ( f a r n e a r ) f a r S ) 2 ( f a r n e a r ) {\displaystyle {\frac {dz}{dz'}}={\frac {-1\cdot -1\cdot {\mathit {S}}\cdot {far}\cdot {\mathit {near}}}{\left(z'\left({\mathit {far}}-{\mathit {near}}\right)-{far}\cdot S\right)^{2}}}\cdot \left({\mathit {far}}-{\mathit {near}}\right)}

Візуалізація тла об'єкта, являє собою z {\displaystyle z'} by the above f ( z ) {\displaystyle f\left(z\right)} : d z d z = 1 1 S f a r n e a r ( f a r n e a r ) ( S ( f a r n e a r z + f a r ) f a r S ) 2 = {\displaystyle {\frac {dz}{dz'}}={\frac {-1\cdot -1\cdot {\mathit {S}}\cdot {far}\cdot {\mathit {near}}\cdot \left({\mathit {far}}-{\mathit {near}}\right)}{\left({\mathit {S}}\cdot \left({\frac {-{\mathit {far}}\cdot {\mathit {near}}}{z}}+{\mathit {far}}\right)-{far}\cdot S\right)^{2}}}=}

( f a r n e a r ) z 2 S f a r n e a r = {\displaystyle {\frac {\left({\mathit {far}}-{\mathit {near}}\right)\cdot z^{2}}{S\cdot {\mathit {far}}\cdot {\mathit {near}}}}=}

z 2 S n e a r z 2 S f a r = {\displaystyle {\frac {z^{2}}{S\cdot {\mathit {near}}}}-{\frac {z^{2}}{S\cdot {\mathit {far}}}}=}

~ z 2 S n e a r {\displaystyle {\frac {z^{2}}{S\cdot {\mathit {near}}}}}

Це показує, що значення z {\displaystyle z'} згруповані щільніше поруч з n e a r {\displaystyle {\mathit {near}}} площиною — а далі, вже рідше; це дає змогу отримати більшу точність ближче до камери. Що менше n e a r / f a r {\displaystyle {\mathit {near}}/{\mathit {far}}} співвідношення, тим менша точність n e a r {\displaystyle {\mathit {near}}} заднього тла площини, оскільки частинки розміщуються занадто тісно вони стають причиною артефактів візуалізації у віддалених об'єктах.[2]

У Z-буфері вираховуються, значення і лінійно інтерполюються через екранний простір між вершинами поточного багатокутник, ці проміжні значення, як правило, зберігається в Z-буфері у форматі нерухомої коми.

Див.також

Примітки

  1. The OpenGL Organization. Open GL / FAQ 12 - The Depth buffer. Архів оригіналу за 20 червня 2010. Процитовано 1 листопада 2010.
  2. Grégory Massal. Depth buffer - the gritty details. Архів оригіналу за 3 серпня 2008. Процитовано 3 серпня 2008.

Джерела

Note 1: see W.K. Giloi, J.L. Encarnação, W. Straßer. "The Giloi’s School of Computer Graphics". Computer Graphics 35 4:12–16.