丟棄片段
- 在此之前處理的都是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