一.模板緩衝區:
板緩衝區(Stencil Buffer)與後臺緩衝區大小相同,類似於深度緩衝區可以控制相似是否寫入。
模板可以通過設置簡單的參數及測試方法允許或者拒絕像素的寫入。
利用模板緩衝技術可以實現陰影體 鏡面反射 漸入漸出等效果。
這裏只介紹陰影體和鏡面的實現方式。
二.鏡面反射:
鏡面反射實現思路比較簡單利用模板測試的方式分三次繪製即可實現:
1. 繪製除鏡面成像以外的所有場景對象.
2. 繪製鏡面區域設置通過設置模板掩碼及模板值標記出鏡面區域例如:
設置模板比較函數爲總是通過,通過之後將模板值設置爲0xffffffff
(Device->SetRenderState( D3DRS_STENCILREF, 0x1 );
Device->SetRenderState( D3DRS_STENCILMASK, 0xffffffff );
Device->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
Device->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE );
然後繪製鏡面)此時就將鏡面區域的模板值設置爲了0xffffffff。
3. 計算場景對象在鏡面中的位置 開啓模板測試 設置可以在模板
值爲0xffffffff的區域內繪製,即可保證在鏡面區域內繪製出鏡面中的場景.
( Device->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_EQUAL);
Device->SetRenderState( D3DRS_STENCILMASK, 0xffffffff );
然後繪製鏡面中場景物件即可。 )
三.動態陰影:
相比鏡面反射,動態陰影的實現則更爲複雜些。其具體步驟可以簡單歸納爲:
1. 計算輪廓邊:
a. 將光線方向轉化到模型空間
b. 遍歷模型所有面,由面法線與光線方向計算夾角,取得所有夾角小
於90度的面及邊
c. 判斷所有邊中只出現過一次的邊則爲輪廓邊
2. 由輪廓邊及光線方向可將輪廓邊的每個頂點沿光線方向
延伸出一條射線形成陰影體。
3. 通過設置模板緩衝繪製陰影區域:(也是動態陰影繪製最複雜部分)
a. 設置背面裁剪繪製陰影體,在繪製陰影體時設置模板緩衝區總是通過,
且通過之後模板值自增1.
b. 設置證明裁剪繪製陰影體,在繪製陰影體是設置模板緩衝總是通過,
且通過之後模板值自減1.
4. 繪製陰影,開啓模板測試,將模板掩碼設置爲1,測試函數設置爲小於等於,
在測試通過區域繪製陰影。
注:
基本原理如下:
如圖: 上面三角形區域是輪廓邊 整個三棱柱爲陰影體, 而所需繪製
的陰影部分則爲紅色圈區域 - 綠色圈區域。因此先繪製紅色邊區域(也
就是背面剔除 繪製)將此部分區域也就是紅色圈模板自增1, 然後正面剔
除繪製背面區域也就是綠色區域將模板值自減1,此時剩下的模板值爲1的
區域就是陰影區域。
三.其他:
除鏡面和陰影外模板還可以用於實現漸入漸出等效果,另外關於模板掩碼
模板值 模板比較函數 三個值得關係是用模板值與上模板掩碼 在用比較
函數進行比較
比較結果爲通過時可以繪製。
設模板掩碼爲 MASK 模板值爲 VALUE 比較函數爲 FUC 則模板測試的過程爲 FUC( MASK & VALUE )