最近做課題的時候需要計算一個 view(就是一次渲染得到的幀) 下的重疊像素個數(兩個物體或更多的物體重疊),
- 最開始我的想法是渲染一個物體輸出一張紋理,這樣對比物體之間的紋理就知道重疊了,但是這樣當物體很多的時候需要輸出太多的紋理到CPU,太慢了,也很麻煩,
- 后來和同學討論了一下,覺得是不是可以使用一張紋理作為幀緩沖的輸出,同時作為片段著色器的輸入,這樣可以每渲染一個像素點加1,最終大于1的位置表示重疊,但是后來這樣試了,在片段著色器中采樣這張紋理的時候,采樣出來的值明顯不對,沒有隨著渲染一個物體后再次采樣會逐步積累增加,(感覺因為是同一張紋理,但是是輸入和輸出,在GPU中分配了兩個存盤位置,各自使用自己的,所以沒有疊加,我瞎猜的……)
- 后來查到仿佛可以使用累積緩沖,每次渲染的結果疊加在一起,但是需要加權,value = https://www.cnblogs.com/chen9510/p/α*value + (1-α)*newvalue ,感覺不太好操作,放棄了,
- 最后看了一下stencil,發現可以實作我需要的功能,雖然幾個月前看過一次,但是當時沒有太懂,這次算是理解了,
現在再來回顧一下 Stencil 的用法:
- glStencilMask(value) 位遮罩, value=https://www.cnblogs.com/chen9510/p/0x00表示模板緩沖不可寫入;value=0xFF表示可以寫入,
- void glStencilFunc(GLenum func, GLint ref, GLuint mask) 指定ref值與存盤的模板值對比
- void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) 指定模板值的寫入策略
流程代碼
glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); glStencilMask(0xFF); //開啟模板寫入 (清空模板緩沖需要開啟模板寫入!!!) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // 我們現在使用模板緩沖 glStencilOp(GL_INCR, GL_INCR, GL_INCR); glStencilMask(0x00); //關閉模板寫入 this->DrawSkyBox(false); this->DrawFloor(false); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilMask(0xFF); //開啟模板寫入 this->DrawBuildings(false); // 先渲染building,shader中的編號保持一致,但是sky一定在前 glStencilMask(0x00); //關閉模板寫入
遇到的坑是清空模板緩沖前一定要開啟模板寫入!!!
模板值讀取:
這個耽擱了很久,開始是附加模板紋理到幀緩沖中,然后從紋理中讀取值,但是怎么都讀出來不對……
后來發現可以直接使用其API讀取 glReadPixels ,
使用此API讀取時,其是直接面向當前幀緩沖獲取模板值資料,故與模板生成方式無關,可以是默認螢屏的幀緩沖,也可以使自己生成的幀緩沖(可以是RBO模板緩沖、模板緩沖紋理、深度-模板緩沖紋理),
float* WKS::Texture::GetStencilData(GLuint width, GLuint height) { float* pixels = new float[width * height]; glReadPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_FLOAT, pixels); return pixels;}
一定要記得在對應的幀緩沖中使用,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/2101.html
標籤:其他
上一篇:Mac錄制或保存視頻后如何放大?
