零基礎學習OpenGL(五) 混合

2021-09-02 05:00:19 字數 1930 閱讀 9568

opengl中,混合用來實現物體透明度。透明就是說乙個物體的顏色是物體本身的顏色和它背後其它物體的顏色的不同強度結合。乙個物體的透明度是通過它顏色的aplha值來決定的。

想載入有alpha值的紋理時,要在紋理生成過程中告訴opengl,我們的紋理現在使用alpha通道了:

glteximage2d(gl_texture_2d, 0, gl_rgba, width, height, 0, gl_rgba, gl_unsigned_byte, data);

保證你在片段著色器中獲取了紋理的全部4個顏色分量,而不僅僅是rgb分量:

// fragcolor = vec4(vec3(texture(texture1, texcoords)), 1.0);

fragcolor = texture(texture1, texcoords);

丟棄opengl預設是不知道怎麼處理alpha值的,更不知道什麼時候應該丟棄片段。我們需要自己手動來弄。glsl給了discard命令,一旦被呼叫,它就會保證片段不會被進一步處理,所以就不會進入顏色緩衝。有了這個指令,我們就能夠在片段著色器中檢測乙個片段的alpha值是否低於某個閾值,如果是的話,則丟棄這個片段,就好像它不存在一樣。

vec4 texcolor = texture(texture1, texcoords);

if(texcolor.a < 0.1)

discard;

fragcolor = texcolor;

混合啟用gl_blend來啟用混合:    glenable(gl_blend);

混合方式如下:

混合時機:片段著色器完成,所有測試都通過後。

比如兩個正方形,如果希望是綠色的正方形在紅色正方形之上,源為綠色,目標為紅色,如果設定源因子為0.6,目標因子為1 - 0.6 = 0.4,

最終的顏色將會被儲存到顏色緩衝中,替代之前的顏色。

opengl使用乙個函式設定因子:glblendfunc。

glblendfunc(glenum sfactor, glenum dfactor)函式接受兩個引數,來設定源和目標因子。opengl為我們定義了很多個選項,我們將在下面列出大部分最常用的選項。

上面例子中使用的就是:glblendfunc(gl_src_alpha, gl_one_minus_src_alpha);

glblendequation(glenum mode)允許我們設定運算子的正負,比如結果等於源+目標或者源-目標等。

每當opengl渲染了乙個片段時,它都會將當前片段的顏色和當前顏色緩衝中的片段顏色根據alpha值來進行混合。有個問題:深度測試和混合一起使用的話會產生一些麻煩。當寫入深度緩衝時,深度緩衝不會檢查片段是否是透明的,所以透明的部分會和其它值一樣寫入到深度緩衝中。結果就是不論透明度都會進行深度測試。即使透明的部分應該顯示背後的窗戶,深度測試仍然丟棄了它們。eg:

要想讓混合在多個物體上工作,我們需要最先繪製最遠的物體,最後繪製最近的物體。普通不需要混合的物體仍然可以使用深度緩衝正常繪製,所以它們不需要排序。但我們仍要保證它們在繪製(排序的)透明物體之前已經繪製完畢了。當繪製乙個有不透明和透明物體的場景的時候,大體的原則如下:

1.先繪製所有不透明物體;2.對所有透明物體排序;3.按順序繪製所有透明的物體。(排序透明物體的一種方法是,從觀察者視角獲取物體的距離。通過計算攝像機位置向量和物體的位置向量之間的距離所獲得。)

參考自

零基礎學習OpenGL(三) 深度測試

深度緩衝 在每個片段中儲存了資訊,以16 24 32位float的形式儲存它的深度值。片段著色器執行之後,在螢幕空間中執行。當深度測試啟用,opengl會將乙個片段的深度值和深度緩衝的內容相比,如果測試通過,深度緩衝將更新為新的深度值 如果測試失敗,片段丟棄。啟用深度測試 glenable gl d...

零基礎學習OpenGL(十一) Gamma校正

人眼對光的敏感度在不同亮度上是不一樣的,人眼會對暗的區域變化更加敏感。如果用8位空間來儲存畫素,0 1區間可以表示256種亮度,但是我們不會一半表示暗的,一半表示亮的 即暗和亮都是128種顏色 因為我們應該花更多的空間去儲存暗的區域,換句話說,暗的需要被區分成更多種。編碼 當攝影裝置儲存 時對畫素進...

零基礎學習網頁製作(五)

零基礎學習網頁製作 五 五 如何定位乙個元素的位置 一 1 描述 這邊可以認為是一條公路上有茫茫多的汽車,每個汽車在公路中之間的距離控制以及每輛車中人與貨物中的位置 2 引入 引入了width,height可以使用百分之多少的形式來代替 margin left代表一輛車左後視鏡與左邊車輛右後視鏡的距...