模版快取是乙個遠離螢幕的快取,我們能夠用它來完成一些特效。模版快取與後快取和深度快取有相同的定義,因此在模版快取中的
[i][j]
畫素與後快取和深度快取中的
[i][j]
畫素是相協調的。就象名字所說,模版快取就象乙個模版它允許我們印刷渲染後快取的某個部分。
1.使用模板快取
1.1啟用模版快取
device
->setrenderstate(d3drs_stencilenable,true);
我們可以使用
idirect3ddevice9::clear
方法來清除模版快取並讓其擁有預設值,也用在
1.2清除後快取和深度快取中
device->clear(0,0,d3dclear_target|d3dclear_zbuffer|d3dclear_stencil,0xffffffff,1.0f,0);
表示把模版快取和目標(後快取)以及深度快取一起清除。
2.建立模板快取
在我們建立深度快取的同時乙個模版快取能夠被建立。當指定深度快取格式的時候,我們同時指定模版快取的格式。這樣,模版快取和深度快取分享同乙個離屏表面快取,但是每個畫素被指定到各自快取記憶體片段中。
下面列出了
3種深度
/模版快取的格式:
d3dfmt_d24s8—
乙個32
位深度/
模版快取,其中
24位為深度快取,
8位為模版快取。
d3dfmt_d24x4s4—
乙個32
位深度/
模版快取,其中
24位為深度快取,位為模版快取,還有
4位留著不用。
d3dfmt_d15s1—
乙個16
位深度/
模版快取,其中
15位為深度快取,
1位為模版快取。 3.
模板測試(
stencil test)
能夠使用模版快取來阻止渲染後快取中的某些部分,阻止特殊畫素被寫是通過模版測試(
stencil test
)來決定的,這是通過下面的表示式來完成的:
(ref & mask) comparisonoperation (value & mask)
模版測試是對每個畫素進行的,假設模版是被允許。將有兩個操作:
左手邊運算元(
lhs=ref&mask
)右手邊運算元(
rhs=value&mask)
模版測試比較
lhs和
rhs,通過比較運算來指定。全部的運算都得到乙個布林值(
true/false
)。假如結果是
true
,那麼我們把畫素寫入後快取。反之
,就阻止畫素被寫入後快取。如果畫素不能被寫入後快取,那麼它也不能被寫入深度快取。
控制模版測試
指定參考值(
stencil reference
)和掩碼
(mask value)
,以便進行比較運算。雖然不能明確地設定模版值(
stencil value),
但是能夠控制寫入模版快取的值。
模版參考值(
reference value
)模版參考值
ref的預設值為
0,通過設定
d3drs_stencilref
渲染狀態來改變:
device->setrenderstate(d3drs_stencilref,0x1);
值常用16位表示
模版掩碼(
stencil mask
)模版掩碼值
mask
是被用來掩飾(隱藏)在
ref和
value
變數中的位。它的預設值是
0xffffffff
,也就是沒有掩飾任何位,通過設定
d3drs_stencilmask
渲染狀態來改變,例掩飾高
16位:
device
->setrenderstate(d3drs_stencilmask,0x0000ffff);
模版值(
stencil value)
在模版快取中我們進行模版測試的當前畫素。對畫素進行模版測試,那麼該值將被寫入該模版快取。不能明確地設定個別模版值,但是可以清除模版快取。能夠使用模版渲染狀態來控制將什麼寫入模版快取。
比較運算
通過設定
d3drs_stencilfunc
渲染狀態來設定比較運算。這個比較運算能夠被
d3dcmpfunc
的任何成員型別列舉:
typedef
enum
d3dcmpfunc d3dcmpfunc, *lpd3dcmpfunc;
更新模板快取
除了決定是否寫或阻止乙個特殊畫素被寫入後快取以外,我們能夠定義模版快取基於三種可能的案例怎樣被更新:
對於[i][j]
處畫素模版測試失敗:
device->setrenderstate(d3drs_stencilfail, stenciloperation);
對於[i][j]
處畫素深度測試失敗:
device->setrenderstate(d3drs_stencilzfail, stenciloperation);
對於[i][j]
處畫素模版測試和深度測試都成功:
device->setrenderstate(d3drs_stencilpass, stenciloperation);
stenciloperation
是以下常數
typedef
enum
d3dstencilop d3dstencilop, *lpd3dstencilop;
模版寫掩碼
除了已經提及的模版渲染狀態之外,我們能夠設定乙個寫掩碼(
write mask
)它將掩飾我們寫進模版快取的任何值的位。我們能夠通過
d3drs_stencilwritemask
渲染狀態來設定寫掩碼。它的預設值是
0xffffffff
。下面的例子是掩飾高
16位:
device->setrenderstate(d3drs_stencilwritemask, 0x0000ffff);
反射矩陣:
d3dxmatrix * d3dxmatrixreflect(
__inout
d3dxmatrix *pout,//
輸出反射矩陣
__in
const
d3dxplane *pplane
//反射平面 );
3種特殊的反射變換:
關於三個座標平面的反射—
yz平面,
xz平面,和
xy平面—分別通過下面三個矩陣來表現:
陰影矩陣
影子本質上是把物體按照燈光照射方向平行地投射到平面
n*p+d=0
之上。同樣的,圖
8.7中所示的點光源,影子本質上是把物體按照透視畫法從光源投射到平面
n*p+d=0
之上。
我們能夠使用乙個矩陣來表示從乙個頂點
p變換到平面
n*p=d=0上的s
的變化。而且,我們能夠用同乙個矩陣來表現正交投影和透視投影。
我們用乙個
4d向量(
nx, ny, nz, d
)來表示將要用於投射陰影平面的平面等式中的各個係數。讓
4d向量l=(
lx, ly, lz, lw
)來表示平行光的照射方向或點光源的位置。我們用
w來區別:
1.假如
w=0,那麼
l表示平行光的照射方向。
2.假如w=
1,那麼
l表示點光源的位置讓k
=(nx, ny, nz, d)*
(lx, ly, lz, lw
)= nxlx+nyly+nzlz+dlw
那麼我們就可得到表示點p到點
s的變換矩陣,即陰影矩陣:
在d3dx
庫中已經給我們提供了乙個建立陰影矩陣的函式。其中當
w=0時表示平行光,當
w=1時表示點光源:
d3dxmatrix * d3dxmatrixshadow(
__inoutd3dxmatrix *pout,
__inconst d3dxvector4 *plight,
__inconst d3dxplane *pplane
);防止雙倍渲染
幾何學上,當我們將乙個物體投影到乙個平面上時,很可能會有兩個或者更多的投影三角形被重疊到一起。若我們就這樣渲染,那麼有重疊三角形的地方就會被多次混合以至這些地方將會變得更黑。
我們設定模版測試為允許畫素第一次被渲染。即,當把影子畫素渲染到後快取時,我們同時在模版快取中做好標記。然後,如果試圖把畫素向乙個已經渲染過的地方寫,那麼模版測試將會失敗。
我們能夠通過下面的混合等式來混合被反射的茶壺和鏡子:
例子:
D3D學習筆記(四)
光照 光照可分為環境光,漫射光,鏡面光三種 三種顏色的光均可用d3decolorvalue或d3dxcolor來表示,描述光線的顏色時,d3dxcolor中的alpha值將被忽略 材質 材質可用結構d3dmaterial9來表示 typedef struct d3dmaterial9d3dmater...
D3D學習筆記(七)
幾何資訊 id3dxbasemesh介面包含乙個頂點快取和乙個索引快取,可用以下方法得到指向這些介面的指標。hresult id3dxmesh getvertexbuffer9 vb 0 hresult id3dxmesh getindexbuffer9 ib 0 如果想鎖定快取進行讀寫操作,那麼可...
D3D學習筆記 繪製
1 頂點 索引緩衝區 頂點 索引緩衝區是一片儲存著頂點 索引資料的記憶體。頂點緩衝區通過idirect3dvertexbuffer9介面來定義的。索引緩衝區時通過idirect3dindexbuffer9介面來定義的。1.1 建立乙個頂點緩衝區和乙個索引緩衝區 建立頂點緩衝區函式原型 hresult...