可以用來干啥?
模板緩沖一般用來實現一些地面反射投影和類似鏡子的特殊效果,如下:


開啟模板緩沖
默認情況下,模板緩沖是關閉的,模板緩沖如果處於關閉狀態,運行模板相關的代碼不會報錯,但是不會出現預期的效果。
使用下面的代碼可以開啟模板緩沖:
var gl = canvas.getContext("webgl", { stencil: true });
使用流程
模板緩沖可以確定下次渲染時,指定的像素是否要進行剔除,可以理解為每個像素只有 0(丟棄) 和 1(保留) 兩個數值。
具體使用模板緩沖大體流程如下:
- 啟用模板測試;
- 設定模板參數;
- 渲染物體,同時根據本次渲染出來的內容更新模板緩沖的內容,注意本次渲染會正常更新顏色緩沖和深度緩沖(如果深度緩沖開啟);
- 設定模板參數;
- 渲染(其它)物體,這次根據模板緩沖的內容丟棄特定的片段;
- 禁用模板測試;
通過使用模板緩沖,我們可以根據場景中已繪制的其它物體的片段,來決定是否丟棄特定的片段。
當你啟用模板測試之后,所有的渲染調用都會以某種方式影響着模板緩沖。
模板相關方法
常規方法
1 // 清除模板緩沖,模板緩沖所有像素值都為0。 2 gl.clear(gl.STENCIL_BUFFER_BIT); 3 // 開啟模板測試 4 gl.enable(gl.STENCIL_TEST); 5 // 關閉模板測試 6 gl.disable(gl.STENCIL_TEST);
gl.stencilMask
glStencilMask允許我們設置一個位掩碼(Bitmask),它會與將要寫入緩沖的模板值進行與(AND)運算;
gl.stencilMask(0xFF); // 每一位寫入模板緩沖時都保持原樣 gl.stencilMask(0x00); // 每一位在寫入模板緩沖時都會變成0(禁用寫入)
gl.stencilFunc
https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/stencilFunc
確定后續的渲染,和當前模板緩沖中的像素模板值對比之后,是否丟棄掉渲染的結果。
glStencilFunc(GLenum func, GLint ref, GLuint mask)
func可選值如下:
GL_ALWAYS:不和模板緩沖中的值進行對比,所有渲染出的像素值都進行正常繪制;
GL_NEVER:不和模板緩沖中的值進行對比,所有渲染出的像素值都丟棄;
GL_LESS、GL_LEQUAL、GL_GREATER、GL_GEQUAL、GL_EQUAL、GL_NOTEQUAL:按照規則對比模板緩沖中的值和渲染出來的值進行釋放丟棄渲染結果的判定。
ref 和 mask:
配合func參數使用,具體規則請看MDN。
gl.stencilOp
https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/stencilOp
設定如何根據下一次渲染的結果來更新模板緩沖中的值。
glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)
- sfail:模板測試失敗時采取的行為。
- dpfail:模板測試通過,但深度測試失敗時采取的行為。
- dppass:模板測試和深度測試都通過時采取的行為。
具體可以傳遞的參數如下:
- KEEP(不改變,這也是默認值)
- ZERO(回零)
- REPLACE(使用測試條件中的設定值來代替當前模板值,stencilFunc方法中的ref參數)
- INCR(增加1,但如果已經是最大值,則保持不變)
- INCR_WRAP(增加1,但如果已經是最大值,則從零重新開始)
- DECR(減少1,但如果已經是零,則保持不變)
- DECR_WRAP(減少1,但如果已經是零,則重新設置為最大值)
- INVERT(按位取反)
示例
https://hammerc.github.io/dou3d-ts/learning/learningNotes/lesson_15/index.html
上下箭頭控制小方塊的移動。
