webgl 混合與模板測試

2021-08-03 05:32:55 字數 2920 閱讀 3210

今天研究了乙個混合與模板測試相結合的案例,這裡做以總結。

案例中乙個籃球在地板上不斷彈起並且落下,這裡主要涉及到了兩項技術:混合與模板測試。首先籃球在地板上反射出來的映象籃球就是通過混合技術實現的,為了讓映象體在運動脫離地板時消失,實現真實的效果,還需要加入模板測試。

首先介紹他們的繪製順序    

1.開啟模板測試,關閉深度檢測 

2.繪製實體地板  

3.設定模板測試引數    

4.繪製映象球 ,禁用模板測試   

5.開啟混合    

6.設定混合引數,繪製半透明地板

7.關閉混合,開啟深度檢測

看到這裡是不是有些頭暈了,不過沒關係,我們來一起理一理其中的思路。

首先關於深度檢測:深度檢測在此案例中不需要使用,我們完全可以根據繪製的順序來確定他們的顯示順序,當不開啟深度檢測時,會根據我們繪製的順序來決定誰會覆蓋誰。

其次是模板測試,先清除上一次繪製產生的模板緩衝,使得緩衝中所有值為0,然後給地板設定模板緩衝的引數,其中設定  glstencilfunc(gl_always, 1, 1); 這樣一來,地板的畫素的「模板值」為1,而其它地方畫素的「模板值」為0。glstencilop(gl_keep, gl_keep, gl_replace);這個函式第乙個引數是未通過模板測試時的操作,第二個引數是通過模板測試,未通過深度測試的操作,第三個是深度測試和模板測試都通過時的操作。我對這個函式的理解是:當其它物體通過模板測試與深度測試時用其它物體的畫素,取代該物體的畫素。

//設定模板測試引數

gl.stencilfunc(gl.always, 1,

1);//設定模板測試後的操作

gl.stencilop(gl.keep, gl.keep, gl.replace);

然後設定模板引數為equal,當進行比較時,通過比較ref也就是stencilfunc的第二個引數來確定是否通過模板測試,比較的方式是第乙個引數也就是equal相等。所以當映象體籃球在地板範圍內時通過模板測試與深度測試,顯示映象。當球體超出地板範圍之後模板測試失敗,不顯示該球體。

//設定模板測試引數

gl.stencilfunc(gl.equal,1,

1);

//設定模板測試後的操作

gl.stencilop(gl.keep, gl.keep, gl.keep);

最後是混合當理解了模板測試之後,混合也就更為簡單了,我們在繪製地板時,實際是繪製了兩次,第一次繪製了不透明度為1的地板,第二次繪製了不透明度為0.5的地板(也就是乙個半透明的地板),半透明地板的作用就是參與混合,使得映象籃球看起來更加真實,不會和實體籃球一樣。所以這裡使用了混合,目標因子是籃球的顏色,源因子是半透明地板,(用半透明地板去混合籃球,所以籃球是目標因子,地板是源因子)所以該引數的意思是根據(源因子的不透明度:目標因子減原因子的不透明度)這個比例來混合他們的顏色,最終達到映象效果。

//開啟混合

gl.enable(gl.blend);

//設定混合因子

gl.blendfunc(gl.src_alpha, gl.one_minus_src_alpha);

下面是繪製部分的**:

functiondrawframe()

//清除著色緩衝與深度緩衝

gl.clear(gl.color_buffer_bit | gl.depth_buffer_bit);

//清除模板快取

gl.clear(gl.stencil_buffer_bit);

//關閉深度檢測

gl.disable(gl.depth_test);

//允許模板測試

gl.enable(gl.stencil_test);

//設定模板測試引數

gl.stencilfunc(gl.always, 1,

1);//設定模板測試後的操作

gl.stencilop(gl.keep, gl.keep, gl.replace);

ms.pushmatrix();

ms.scale(0.3

,0.3

,0.3);

//繪製反射面地板

rectdb.drawself(ms,texmap["db"]);

ms.popmatrix();

//設定模板測試引數

gl.stencilfunc(gl.equal,1,

1);

//設定模板測試後的操作

gl.stencilop(gl.keep, gl.keep, gl.keep);

//繪製映象體

drawmirror();

//禁用模板測試

gl.disable(gl.stencil_test);

//開啟混合

gl.enable(gl.blend);

//設定混合因子

gl.blendfunc(gl.src_alpha, gl.one_minus_src_alpha);

ms.pushmatrix();

ms.scale(0.3

,0.3

,0.3);

//繪製半透明反射面地板

rectdb.drawself(ms,texmap["tm"]);

ms.popmatrix();

//開啟深度檢測

gl.enable(gl.depth_test);

//關閉混合

gl.disable(gl.blend);

//繪製實際物體

WebGL 示例 混合透明效果

顏色的中的 分量控制著顏色的透明度,在webgl實現透明效果需要用到 混合,因為webgl已經內建了該功能因此開啟即可 示例 透明混合 在進行 混合時,實際上webgl用到了兩個顏色,即源顏色和目標顏色,前者是待混合進去的顏色後者是待被混合進去的顏色 gl.blendfunc src factor,...

深度測試與alpha混合(3)

alpha源混合係數通常設定為d3dblend srcalpha,即當前繪製畫素的alpha值。目標混合係數設定為d3dblend invsrcalpha,即1減去當前繪製畫素的alpha值。那麼當前繪製畫素的alpha值又是如何得到的呢?如果沒有使用材質和紋理,當前繪製畫素的alpha值來自每個頂...

深度測試與alpha混合(5)

透過那些透明度非常高的物體看其他物體,例如透過幾乎完全透明的玻璃看其他物體,會感到玻璃好像不存在,在三維圖形程式中渲染時就可以不渲染這些透明度非常高的物體,從而可以提高渲染速度,這可以通過alpha測試來實現。alpha測試根據當前畫素是否滿足alpha測試條件 即是否達到一定的透明度 來控制是否繪...