DirectX11 深度測試(有點另類)
(問到自己清楚就可)
@Author: 白袍小道
@說明:轉載隨緣,評論隨緣,詢問建議看書和源碼會得到更準確的答案
深度測試的來源、目的、做法
一、問題詢問
我們帶著一些問題去瀏覽一番
1、深度測試發生在光柵化階段後?
(這裏先補充一下先後:模版測試 --->深度測試---->混合狀態)
2、深度測試用來做什麽?
3、怎麽做?
二、說明詢問
2.1、深度測試如果說目的最直接的是:
2.2、深度緩沖區:
深度緩沖區,也稱為z-buffer,是Direct3D中用來存儲繪制到屏幕上的每個像素點的深度信息的一塊內存緩沖區,是一個只含有特定像素深度信息而不含圖像數據的表面,深度緩存為最終繪制的圖像中的每一個像素都保留了一個深度值.
(關鍵字:屏幕上的每個像素點,深度信息,內存緩沖區)
a.1 |
緩沖區直接在GPU上操作,物美價廉,相對而言是一種直接和容易擴展的方式。 |
a.2 |
可稍微調整解決其他問題,同時又兼顧了很多 |
a.3 |
DirectX處理上是采取狀態機模式 |
(程序關註數據,然後算法,解脫了)(調整就是有一定可操作程度,看上圖若半透明在遮擋中間就可以調整下測試,說白了也就是調整了相關結構)
2.3、 那這個正確的標準是什麽,怎麽判斷。
Stencil Settings
1. StencilEnable: |
Specify true to enable the stencil test; specify false to disable it. |
2. StencilReadMask: |
The StencilReadMask used in the stencil test: |
(API說明)
if(StencilRef & StencilReadMask ? Value & StencilReadMask)
accept pixel
else
reject pixel
這樣就很清晰說明是一個比較,比較什麽?
註意:
操作: 比較了當前和之前,這緩存不就出來了,再確定是否更新。
值: 深度值是由視矩陣和投影矩陣,結果就是位置在(近裁剪,遠裁剪)的範圍映射到(0,1)
註:函數可以看API
(,這是兩個操作)
(當然也可以利用這個緩存做些其他事情這是果,如同C++ template定出來,也不知道後面發生的事情,嘻嘻)
- 4 結構和操作
說明:關註的不是步驟順序,因為你也可以跳過。而是輸入和輸出,結構
清理、創建、分配、更新、
//創建
HRESULT ID3D11Device::CreateDepthStencilState
(
const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, // [In]深度/模板狀態描述
ID3D11DepthStencilState **ppDepthStencilState // [Out]輸出深度/模板狀態
);
///分配
void ID3D11DeviceContext::OMSetDepthStencilState
(
ID3D11DepthStencilState *pDepthStencilState, |
// [In]深度/模板狀態,使用nullptr的話則是默認深度/模板狀態 |
UINT StencilRef |
// [In]提供的模板值 |
);
///如果要恢復到默認狀況,可以這樣調用
md3dImmediateContext->OMSetDepthStencilState(nullptr, 0);
4.1 |
清理深度模板視圖 |
void ID3D11DeviceContext::ClearDepthStencilView
(
ID3D11DepthStencilView *pDepthStencilView, |
// [In]深度模板視圖 |
UINT ClearFlags, |
// [In]使用D3D11_CLEAR_FLAG枚舉類型決定需要清空的部分 |
FLOAT Depth, |
// [In]使用Depth值填充所有元素的深度部分 |
UINT8 Stencil |
// [In]使用Stencil值填充所有元素的模板部分 |
);
4.2 |
深度/模版描述 |
typedef struct D3D11_DEPTH_STENCIL_DESC
{
BOOL DepthEnable; |
// 是否開啟深度測試 |
D3D11_DEPTH_WRITE_MASK DepthWriteMask; |
// 深度值寫入掩碼 |
D3D11_COMPARISON_FUNC DepthFunc; |
// 深度比較函數 |
BOOL StencilEnable; |
// 是否開啟模板測試 |
UINT8 StencilReadMask; |
// 模板值讀取掩碼 |
UINT8 StencilWriteMask; |
// 模板值寫入掩碼 |
D3D11_DEPTH_STENCILOP_DESC FrontFace; |
// 對正面朝向的三角形進行深度/模板操作描述 |
D3D11_DEPTH_STENCILOP_DESC BackFace; |
// 對背面朝向的三角形進行深度/模板操作的描述 |
} D3D11_DEPTH_STENCIL_DESC;
4.3 |
比較函數 |
D3D11_COMPARISON_FUNC的枚舉說明
D3D11_COMPARISON_NEVER = 1 |
該比較函數一定返回false |
D3D11_COMPARISON_LESS = 2 |
使用<來替換? |
D3D11_COMPARISON_EQUAL = 3 |
使用==來替換? |
D3D11_COMPARISON_LESS_EQUAL = 4 |
使用<=來替換? |
D3D11_COMPARISON_GREATER = 5 |
使用>來替換? |
D3D11_COMPARISON_NOT_EQUAL = 6 |
使用!=來替換? |
D3D11_COMPARISON_GREATER_EQUAL = 7 |
使用>=來替換? |
D3D11_COMPARISON_ALWAYS = 8 |
該比較函數一定返回true |
D3D11_DEPTH_WRITE_MASK_ZERO |
不寫入深度/模板緩沖區 |
D3D11_DEPTH_WRITE_MASK_ALL |
允許寫入深度/模板緩沖區 |
4.4 |
描述操作 |
typedefstruct D3D11_DEPTH_STENCILOP_DESC {
D3D11_STENCIL_OP StencilFailOp;
D3D11_STENCIL_OP StencilDepthFailOp;
D3D11_STENCIL_OP StencilPassOp;
D3D11_COMPARISON_FUNC StencilFunc;
} D3D11_DEPTH_STENCILOP_DESC;
D3D11_STENCIL_OP 枚舉的定義:
D3D11_STENCIL_OP_KEEP |
保持目標模板值不變 |
D3D11_STENCIL_OP_ZERO |
保持目標模板值為0 |
D3D11_STENCIL_OP_REPLACE |
使用StencilRef的值替換模板模板值 |
D3D11_STENCIL_OP_INCR_SAT |
對目標模板值加1,超過255的話將值保持在255 |
D3D11_STENCIL_OP_DECR_SAT |
對目標模板值減1,低於0的話將保持在0 |
D3D11_STENCIL_OP_INVERT |
對目標模板值的每個位進行翻轉 |
D3D11_STENCIL_OP_INCR |
對目標模板值加1,超過255的話值將上溢變成0 |
D3D11_STENCIL_OP_DECR |
對目標模板值減1,低於0的話將下溢變成255 |
- 5 算法說明
- 6 回顧下PipeLine
DirectX11 深度測試(有點另類)