1. 程式人生 > >Directx11教程(48) depth/stencil buffer的作用

Directx11教程(48) depth/stencil buffer的作用

padding 陰影 logs 光柵 rec ott ive mat order

原文:Directx11教程(48) depth/stencil buffer的作用

     在D3D11中,有depth/stencil buffer,它們和framebuffer相對應,如下圖所示,framebuffer中一個像素,有相對應的depth buffer和stencil buffer值:

 

技術分享圖片

      D3D11中,depth buffer和stencil buffer一起定義,比如DXGI_FORMAT_D24_UNORM_S8_UINT,是指用一個無符號24位的值做為像素的深度緩沖值,並把它映射到[0,1],用一個8位的值表示像素stencil值,並把它映射到[0,255]。

註意:在hardware中,detph buffer和stencil buffer實際上是兩個獨立的buffer

     

     下面我們看看depth buffer和stencil buffer的作用:

      在光柵化階段,光柵化硬件在光柵化primitive(比如一個三角形)的時候,會訪問stencil buffer和depth buffer,並進行相應的比較,這種比較我們通常稱為stencil test和depth test,只有通過stencil test和depth test的pixel(或者稱為sample 或者fragment更合適),才能最終被寫入framebuffer。

     下圖是stencil test和depth test的框圖:

技術分享圖片

       首先會進行stecil test,就是當前pixel的stencil值和stencil buffer中對應的stencil值進行某種比較,只有通過比較測試的pixel才會進行depth test,否則就會被光柵化硬件丟棄掉。接著會進行depth test,depth test能夠保證物體在場景中前後位置關系。如果兩個test都pass,就會更新depth buffer值(當然stencil pass的時候,就可以根據stencil function更新或者保持stencil buffer值了

)。

    通過使用stencil test,我們可以實現蒙版的效果,從而實現一些渲染效果,比如鏡子,體積陰影等。

舉個例子:

    在一個frame中,我們首先渲染一個四邊形,做為鏡子,渲染前,清除depth/stencil buffer值(depth設置為1.0, stencil 設置為0),這時場景中stencil buffer為

技術分享圖片

接著,我們設置stencil 總是pass,並設置stencil buffer值為1,渲染一個鏡子(四邊形)。這是stencil buffer的值為

技術分享圖片

接下來,我們渲染其它的primitive,比如一個三角形,先設置stencil 值為1,並設置stencil比較函數為等於,這樣渲染三角形時候,會比較stencil值,對於三角形光柵化後的pixel,如果它在鏡子的範圍內,1=1,所以stencil pass,會保留這個像素,如果在鏡子的外面,因為stencil buffer的值為0,所以stencil test fail,從而放棄這個pixel。如下圖三角形,最後實際保留的像素只為藍色的pass stencil test的部分。

技術分享圖片

   下面一章,我們將在D3D11中,通過使用stencil,實現一個鏡子的效果。

Directx11教程(48) depth/stencil buffer的作用