1. 程式人生 > >OpenGL中的深度、深度快取、深度測試

OpenGL中的深度、深度快取、深度測試

 1、深度

     所謂深度,就是在openGL座標系中,畫素點Z座標距離攝像機的距離。攝像機可能放在座標系的任何位置,那麼,就不能簡單的說Z數值越大或越小,就是越靠近攝像機。

     2、深度緩衝區

      深度緩衝區原理就是把一個距離觀察平面(近裁剪面)的深度值(或距離)與視窗中的每個畫素相關聯。       首先,使用glClear(GL_DEPTH_BUFFER_BIT),把所有畫素的深度值設定為最大值(一般是遠裁剪面)。       然後,在場景中以任意次序繪製所有物體。硬體或者軟體所執行的圖形計算把每一個繪製表面轉換為視窗上一些畫素的集合,此時並不考慮是否被其他物體遮擋。       其次,OpenGL會計算這些表面和觀察平面的距離。如果啟用了深度緩衝區,在繪製每個畫素之前,OpenGL會把它的深度值和已經儲存在這個畫素的深度值進行比較。新畫素深度值<原先畫素深度值,則新畫素值會取代原先的;反之,新畫素值被遮擋,他顏色值和深度將被丟棄。

      為了啟動深度緩衝區,必須先啟動它,即glEnable(GL_DEPTH_TEST)。每次繪製場景之前,需要先清除深度緩衝區,即glClear(GL_DEPTH_BUFFER_BIT),然後以任意次序繪製場景中的物體。

      數學基礎:

      待渲染的照相機空間中的深度經常定義為近距 near 到遠距 far 之間的 z 值,Z座標和X、Y座標一樣。在變換、裁減和透視除法後,Z的範圍為-1.0~1.0。DepthRange對映指定Z座標的變換,這與用於將X和Y對映到視窗座標的視口變換類似,在透視變換之後,得到新的 z' 值:

z'=\frac{\mathit{far}+\mathit{near}}{\mathit{far}-\mathit{near}} +\frac{1}{z} (\frac{-2 \cdot \mathit{far} \cdot \mathit{near}}{\mathit{far}-\mathit{near}} )

     其中 z 是照相機空間的值,它有時候也表示為 w 或者 w'。

      結果 z' 是在 -1 到 1 之間歸一化之後的值,其中近距 near 平面位於 -1 處,遠距 far 平面位於 1 處。在這個範圍之外的相應點在檢視體之外,不需要進行渲染。

     為了實現深度緩衝,在整個螢幕空間上的對當前多邊形頂點之間進行插值來計算 z' 的值,通常這些中間數值在深度緩衝區中用定點數格式儲存。距離近距 near 平面越近,z' 值越密;距離越遠,z' 值越稀。這樣距離照相機越近精度越高。near 平面距離照相機越近,則遠距離位置的精度越低。near 平面距離照相機太近是在遠距離物體產生人為誤差的一個常見因素。

       3、深度測試

       OpenGL中的深度測試是採用深度快取器演算法,消除場景中的不可見面。在預設情況下,深度快取中深度值的範圍在0.0到1.0之間,這個範圍值可以通過函式:         glDepthRange (nearNormDepth, farNormalDepth);        將深度值的範圍變為nearNormDepth到farNormalDepth之間。這裡nearNormDepth和farNormalDepth可以取0.0到1.0範圍內的任意值,甚至可以讓nearNormDepth > farNormalDepth。這樣,通過glDepthRange函式可以在透視投影有限觀察空間中的任意區域進行深度測試。        另一個非常有用的函式是:         glClearDepth (maxDepth);        引數maxDepth可以是0.0到1.0範圍內的任意值。glClearDepth用maxDepth對深度快取進行初始化,而預設情況下,深度快取用1.0進行初始化。由於在進行深度測試中,大於深度快取初始值的多邊形都不會被繪製,因此glClearDepth函式可以用來加速深度測試處理。這裡需要注意的是指定了深度快取的初始化值之後,應呼叫:         glClear(GL_DEPTH_BUFFER_BIT);   完成深度快取的初始化。        在深度測試中,預設情況是將需要繪製的新畫素的z值與深度緩衝區中對應位置的z值進行比較,如果比深度快取中的值小,那麼用新畫素的顏色值更新幀快取中對應畫素的顏色值。這種比較測試的方式可以通過函式:         glDepthFunc(func); 進行修改。其中引數func的值可以為GL_NEVER(沒有處理)、GL_ALWAYS(處理所有)、GL_LESS(小於)、GL_LEQUAL(小於等於)、GL_EQUAL(等於)、GL_GEQUAL(大於等於)、GL_GREATER(大於)或GL_NOTEQUAL(不等於),其中預設值是GL_LESS。這些測試可以在各種應用中減少深度快取處理的的計算。