OpenGL學習筆記——Blending

注:本文檔只記錄要點和我自己的一些新得,並不是教程。需要教程的請去看OpenGLLearn原文。


混合可以實現物體透明度。

實現透明度由兩種方式:

1是拋棄(discard)一部分片段,這種情況下,不存在半透明的片段。

2纔是真正意義上的混合。將當前片段,和目標片段,按照一定的公式,進行加權計算。

【1】

#version 330 core
out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D texture1;

void main()
{             
    vec4 texColor = texture(texture1, TexCoords);
    if(texColor.a < 0.1)
        discard;
    FragColor = texColor;
}

丟棄片段的比較暴力了,直接判斷alpha<某個常亮的片段,丟棄掉,不過這個if會產生邏輯分支,所以效率也就那樣吧……

環繞紋理設置成:GL_CLAMP_TO_EDGE 可以略微提高視覺效果。


【2】混合

激活混合用:glEnable(GL_BLEND);


那一大丟丟的參數,其實最常用的也就只有:glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

也就是源alpha 和 1-源alpha

這裏glBlendFunc是混合操作設置函數。

glBlendFuncSeparate更爲鬼畜一些,他可以爲顏色和Alpha分別設置操作函數。


這兩個都是設置源和目標,如何處理rgb和alpha值的。


glBlendEquation可以用來設置混合運算符。其實最常用的也就是GL_FUNC_ADD


這個函式,是設置用哪個公式去處理這些alpha和RGB值的。


混合的原理:

前提是你已經在混合之前畫過一些東西(哪怕只天空盒也OK),不然混合個毛線?

混合的時候,將要繪製的東西是Source,已經畫完的東西是Target。

混合的時候,你的Shader裏面幾乎不用改什麼東西,片段會按照混合公式和數值規則,自己去和已經繪製好的片段進行混合。Unity則是在用ShaderLab的語法去設置這些函式的.


之前遇到過的一個問題的解釋:

幾個月以前,我曾經遇到過一個問題,在我用WorldCreatorPro製作地圖的時候,在沒有使用SpeedTree而使用切片LOD的時候,也就是離的比較遠的時候,樹會變成半透明切片。這時候半透明區域會將後面的地形隱藏掉。


現在時候很容易解釋這個問題了。借用LearnOpenGL作者的圖:



看籃圈的部分:

如果先繪製前面的圖,由於Z-Buffer是不理會Alpha的,所以,這裏的透明像素也會被寫進ZBuffer。

當繪製後面的物體時(無論它是不是透明,只要他比前面物體遠)Z-測試會失敗,然後對應像素就被丟棄了。


結論:Z-Buffer和Blending一起用的時候,必須先畫遠處物件再畫近處的,才能保證不出錯。

那麼之前用的樹木,即便可以排序,每幀將幾千棵樹每幀排一次序,然後在渲染,也是非常恐怖的開銷,所以索性直接換成SpeedTree好了,直接用模型LOD,也不是用貼圖LOD,雖然它確實很省。


方法:如何正確使用Blending。

  1. 先繪製所有不透明的物體。
  2. 對所有透明的物體排序。
  3. 按順序(由遠到進)繪製所有透明的物體。具體來講,可以按距離插入排序,先畫遠處,後畫近處。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章