1. 程式人生 > >零基礎學習OpenGL(五)--混合

零基礎學習OpenGL(五)--混合

        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.按順序繪製所有透明的物體。(排序透明物體的一種方法是,從觀察者視角獲取物體的距離。通過計算攝像機位置向量和物體的位置向量之間的距離所獲得。)

 

參考自https://learnopengl-cn.github.io