learnOpenGL 4 3 透明混合

2021-10-09 18:57:44 字數 1662 閱讀 2316

在實際場景中,我們會遇到一些透明的物體,如何顯示透明物體是乙個問題。

rgba值中a即為透明度,當a非常小,接近或等於零時,我們可以直接在fragment shader中將這些部分捨棄。

void main()

注意,當取樣紋理的邊緣的時候,opengl會對邊緣的值和紋理下乙個重複的值進行插值(因為我們將它的環繞方式設定為了gl_repeat。這通常是沒問題的,但是由於我們使用了透明值,紋理影象的頂部將會與底部邊緣的純色值進行插值。這樣的結果是乙個半透明的有色邊框,你可能會看見它環繞著你的紋理四邊形。要想避免這個,每當你alpha紋理的時候,請將紋理的環繞方式設定為gl_clamp_to_edge:

gltexparameteri(gl_texture_2d, gl_texture_wrap_s, format == gl_rgba ? gl_clamp_to_edge : gl_repeat);

gltexparameteri(gl_texture_2d, gl_texture_wrap_t, format == gl_rgba ? gl_clamp_to_edge : gl_repeat);

當alpha值較大時,就必須用到blend混合

glenable(gl_blend);
以下是混合方程

通過glblendfunc(glenum sfactor, glenum dfactor)中的兩個引數,我們可以控制方程中的引數。

方程預設是相加的,我們還可以通過glblendequation(glenum mode)來改變方程,使其相減。

混合的原理是將當前片段與已繪製的片段進行混合,這有可能與深度測試衝突。

比如我們先繪製靠前的透明窗戶,在渲染靠後的箱子,此時箱子進行深度測試,由於深度值值小直接捨棄,並不進行繪製。造成了透明窗戶實際遮擋了後面的箱子。

所以繪製時要注意順序,大體規則是:

先繪製所有不透明的物體。

對所有透明的物體排序。

按順序從後往前繪製所有透明的物體。

排序透明物體的一種方法是,從觀察者視角獲取物體的距離。這可以通過計算攝像機位置向量和物體的位置向量之間的距離所獲得。

接下來我們把距離和它對應的位置向量儲存到乙個stl庫的map資料結構中。map會自動根據鍵值(key)對它的值排序,所以只要我們新增了所有的位置,並以它的距離作為鍵,它們就會自動根據距離值排序了。

我們使用了map的乙個反向迭代器(reverse iterator),反向遍歷其中的條目,並將每個窗戶四邊形位移到對應的窗戶位置上。

std::mapsorted;

for (unsigned int i = 0; i < windows.size(); i++)

for(std::map::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); ++it)

現在已經有次序無關的透明度演算法了,不過比較複雜

Learn OpenGL基礎書籍推薦

關於opengl的學習資料 c語言我覺得是最值得任何程式設計師花大量的時間學習的語言.原因是 c語言不在可能隨著時間的變化而產生太大的變動,最多也就是一點修修補補.可以說是一朝學會,終生受用 c語言是簡約的,就32個關鍵字,但是基本上現在任何語言都直接或者間接的構建在c語言之上.linux,wind...

Learn OpenGL基礎書籍推薦

關於opengl的學習資料 c語言我覺得是最值得任何程式設計師花大量的時間學習的語言.原因是 c語言不在可能隨著時間的變化而產生太大的變動,最多也就是一點修修補補.可以說是一朝學會,終生受用 c語言是簡約的,就32個關鍵字,但是基本上現在任何語言都直接或者間接的構建在c語言之上.linux,wind...

LearnOpenGL筆記6光照

last 鏡面光照 現實生活中看到某一物體的顏色並不是這個物體真正擁有的顏色,而是它所反射的 reflected 顏色。換句話說,那些不能被物體所吸收 absorb 的顏色 被拒絕的顏色 就是我們能夠感知到的物體的顏色。當我們把光源的顏色與物體的顏色值相乘,所得到的就是這個物體所反射的顏色 也就是我...