閱讀53 返回首頁    go 技術社區[雲棲]


Opengl編程學習筆記(五)——從FRAGMENT到PIXEL(framebuffer 幀緩存)

1.幀緩存包括顏色、scissoralphastencildepth這些緩存,所以幀緩存不是一片緩存,而是所有這些緩存的組合,幀緩存它對應了屏幕上的每一個pixel(不是真正的pixel,而是一個fragment所對應的位置)的各種這些信息(顏色、ZBUFFER、等等),幾何體的fragment時沒有幀緩存的,幀緩存時屏幕上的,一個緩存的一位就對應一個位片麵。

Colorbuffer是最終表現在屏幕上的,但是其他緩存決定了最後這些color是否和怎樣繪製在屏幕上.,其中除了colorbuffer的那些幀緩存也稱作輔助緩存.

在光柵化得到fragment後,就要按照以下的順序進行各種測試,那些通過測試了的像素才有資格最後放到屏幕上,在通過所有測試後,這些fragment將可能被寫入原有的幀緩存(但是在最後混合出來的顏色值可能與屏幕原有的幀緩存中 的顏色緩存做各種運算,所以顏色緩存有時可能不會被簡單覆蓋,但其他緩存會。

2.顏色緩存的讀寫:glDrawBufferglReadBuffer(),然後調用GlwritePixelglreadpixel

3緩存掩碼(MASK):

可以設置每種幀緩存的掩碼,再寫入相應緩存時就會被掩碼作用,具體表現為

GlIndexmaskGlint  mask):如果在索引模式下,當mask的第i位為0時,則第i個索引的顏色不會被寫入到顏色緩存中,你會看到原本為那個顏色的區域變成空空的了,為1正常繪製,可以利用他進行層動畫。

GlcolormaskGLboolean redGLboolean greenGLboolean blueGLboolean alpha):它可以控製顏色值中的那個通道繪製那個不被繪製(1為繪製),這個可以讓你查看各種顏色的渲染,如圖是隻顯示紅色的情形:

GlDepthMaskGLboolean flag):當flag為真時寫入深度緩存,否則就不寫入。默認是寫入的,那如果為否不寫入你將看到什麼效果呢?這樣每一幀後繪製的那個物體它不寫幀緩存,也就是它的幀緩存默認為最小的0,所以此時你永遠看到後繪製的在前麵(這跟正常情況下不帶開深度測試看到的場景是一樣的)。

深度緩存的掩碼有很多的應用,例如你可以隨時置它與FALSE控製以後的物體為後繪製的現實在最上層

4fragment的測試

注意這裏要進行的所有測試都是在fragmen級別上的,這部分也是本章的核心內容。測試的意義是;當一個被計算出來的fragment要最終成為屏幕的一個pixel時要按照下麵順序通過測試,如果在哪個階段不被通過,就會不繪製,如果最後都通過了,確定要在屏幕的顏色緩存上繪製這一點時,還要將這點屏幕緩存該點原先顏色進行某種混合。

Scissor Test:這裏通過glScissor()定義一個矩形區域(Scissor box),如果片段在這和矩形內,則通過,不在則不通過(不顯示),這個相當於StencilTest的矩形版。效果如下:就像從一小窗口觀看的感覺

 

Alpha test:它的基本功能時利用alphaRGBAA 緩存來判定是否繪製一個像素,雖然它的值經常被用來進行混合效果。用glAlphaFunc()來定義參考值和通過測試的條件。測試的過程是,用fragmentalpha值遇一個定義的參考值做比較,比較的方式由glAlphaFunc指定,通過這個比較來判斷是否通過測試。

Alpha test可以製作鏤空效果或是billboard,製作billboard的過程是:製作一個貼有rgba四通道的貼圖,其中透明部分的alpha0,反之為1,在場景中為一個細分的多邊形貼上這個貼圖作為紋理,其中頂點的ALPHA值就為其貼圖的點的ALPHA值,最後使用alpha測試,並將比較函數設置為GL_GRETER,參考值為0.5,這樣0的那部分就會不通過,變成完全透明的了。

 

Stencil test:它時一個模板測試,形象的比喻就是在stencil test處理中,會依據stencil buffer這個記憶體中所存放的資料,來決定是否要舍棄像素。它的測試過程是這樣的,在所有像素的stencil buffer裏麵存儲了一些值,然後定義了一個比較方法和一個參考值,如果參考值與該點的stencilbuffer裏麵的值在這種比較方式下通過,那麼這點通過測試,被繪製。你不能直接寫入stencilbuffer,但是可以通過glStencilOp()來間接寫入,這個函數設定當一個fragment通過或者不通過Stencil緩存時Stencil緩存起什麼變化。

Stencil test最常用的用途就是在屏幕上定義一塊不規則的區域,然後限製在這個區域內顯示。它的實現方法是這樣的:

首先要清空當前的Stencil緩存為0glClearStencil0);glClearGL_STENCIL_BUFFER_BIT

然後設定glStencilFunc()為GLALWAYS1,就是都通過該測試,並且設定GLSENCILOPGL_REPLACEGL_REPLACEGL_REPLACE)接著繪製你希望的不規則區域的形狀。這段代碼的意思就是讓你繪製的那個形狀都通過Stencil測試,而且通過後都用1來取代那點的Stencil緩存。這樣就把Stencil緩存變成了那塊形狀的區域為1,定製了一個這種形狀的模板,注意每次RESIZE的時候stencil會自動清空掉

最後要清空屏幕的顏色和深度緩存,然後設定glStencilFuncGL_EQUAL1GLSENCILOPGL_KEEP(不變Stencil緩存了,最後後繪製你要繪製的場景,這樣那些等於1stencil位置被繪製上了,不等於的就不繪製了,這是這種算法的效果:裏麵在一個人形的區域內繪製,這對一些遊戲的GUI來說很有幫助

 

Depth test:通常進行深度測試的過程是這樣的,在每一幀開始用一個很大的值來清空深度緩存,然後在繪製時,會自動產生當前的深度,默認采用的比較函數是較小的深度通過測試進行繪製,這樣就剔除了背景。當然也可以用glDepthFunc來設置比較函數

 

當進行過上述測試後,所有即將認為要被寫到同一屏幕位置的片段將混合他們的顏色值,作為最後的顏色在最後一步寫在屏幕上,在這裏可以設置這個混合方式

 

Dithering:這一歩時用在索引模式,因為在索引模式下如果混合後的顏色不再索引中,他將找一種所顏色拚湊的方式來替代,打開GL_DITHER的開關即可。

 

最後一步邏輯操作:最後一步時邏輯操作,我們在前麵生成了將寫在屏幕上的顏色,而此時COLORBUFFER有剛才的顏色值,這是可以選擇對這兩個值進行操作,默認是GL_COPY,也就是單純拷貝新值到屏幕上,但是事實上還有很多可選的邏輯操作,當然要打開GL_COLOR_LOGIC_OP/INDEX開關。其實這個操作時非常有用的,它可以直接控製最後在屏幕上的顯示狀況,它隻是改變最後屏幕上的像素,所以可以很輕鬆的實現肯多小TRIK,如顏色反置,切換場景與清空等等。

 

關於Accumulation Buffer,這個framebuffer和測試無關,它用來累計顏色緩存上的值,也就是說他可以將每幀的顏色緩存的值類加到她這裏,然後她還可以把他累加的內容重新寫入顏色緩存,我們看上去就像一幅幾張圖像疊加的照片。我們可以控製這些過程。glAccum()控製對這個緩存的操作,通常有開始累加,清空重新累加、寫到屏幕顏色緩存、數值運算等操作。可以利用buffer進行反走樣和模煳處理。使用前要在最前麵打開GLUT_ACCUM模式,這個緩存有很多用處:如反走樣、模擬運動模煳、模擬多重曝光(即產生HDR圖)、產生軟影(soft shadow)等等。

最後更新:2017-04-02 00:06:48

  上一篇:go php中注冊器模式類的使用
  下一篇:go 剖析在WAS 6.1.0.19上碰到/snoop時執行不完整而出現ClassFormatError