混合

丟棄片段

  • 在此之前處理的都是rgb三個通道的數據,第四個通道a存儲的是物體的透明度
  • stb_image在紋理有透明通道的時候會自動加載,但是我們需要在生成紋理過程中告訴openGl,我們的紋理現在使用alpha通道了
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  • OpenGL並不知道如何對alpha通道進行處理,因此需要我們手動來弄,比如當透明度小於某個閾值的時候將這個片段丟棄
vec4 texColor = texture(texture1, TexCoords);
    if(texColor.a < 0.1)
        discard;
    FragColor = texColor;

渲染半透明時的順序問題

  • 如果我們利用深度測試來渲染物體,那麼兩個半透明物體,比較遠的物體如果在靠後渲染會無法通過深度測試然後將片段丟棄。結果導致較近透明物體顏色直接將其覆蓋,沒有辦法顯示出後面物體顏色
  • 所以應該將所有的半透明物體按照距離遠近進行排序,先繪製比較遠的物體,然後繪製近處的物體
  • 這樣繪製出較遠物體之後,按照深度緩衝,近處物體能夠通過,並且也可以順利進行混合
  • 對於普通不需要混合的物體則任然可以使用深度緩衝正常繪製
  • 當繪製一個有不透明和透明物體的場景的時候,大體的原則如下:
  • 先繪製所有不透明的物體。
  • 對所有透明的物體排序。
  • 按順序繪製所有透明的物體。

爲什麼是這個順序

  • 不透明物體會遮擋所有物體,因此先繪製他們,深度緩衝放置的就是他們的深度數據
  • 然後半透明物體有兩種情況,可能會在其前面,也可能在其後面,在後面的因爲深度緩衝測試被直接丟棄
  • 在前面的可以通過測試,然後混合顏色
  • 半透明物體和半透明物體之間則排列順序,然後渲染

後記

  • 雖然按照距離排序物體這種方法對我們這個場景能夠正常工作,但它並沒有考慮旋轉、縮放或者其它的變換,奇怪形狀的物體需要一個不同的計量,而不是僅僅一個位置向量。

  • 在場景中排序物體是一個很困難的技術,很大程度上由你場景的類型所決定,更別說它額外需要消耗的處理能力了。完整渲染一個包含不透明和透明物體的場景並不是那麼容易。

疑惑

  • 片段着色器運行完成後,並且所有的測試都通過之後,這個混合方程(Blend Equation)纔會應用到片段顏色輸出與當前顏色緩衝中的值(當前片段之前儲存的之前片段的顏色)上
  • 混合是在最靠後的
  • 我想知道爲什麼是這個順序,先片段着色器運行,然後是模板測試,再其次是深度測試
  • 【模板測試我可以理解,渲染物體來影響模板值,然後通過這些模板值來進一步影響渲染】
  • 【可是在頂點着色器進行空間變換的時候,就已經獲得每個物體的深度值了,直接根絕這些深度值將某些片段丟掉難道不可以嗎?】
  • 【而且提前深度測試需要關閉寫入深度值,這是爲什麼】

線性插值

  • y = (1 − α)y0 + αy1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章