GLSL 程式設計/Blender/獨立於順序的透明度

本教程涵蓋 **獨立於順序的混合**。
它繼續討論 關於透明度的教程,並解決了標準透明度的一些問題。如果您還沒有閱讀過該教程,建議您先閱讀。

正如 關於透明度的教程 中所述,混合的結果通常(特別是對於標準 alpha 混合)取決於三角形渲染的順序,因此如果三角形沒有從後到前排序(通常不會),就會導致渲染偽像。術語“獨立於順序的透明度”描述了各種避免此問題的技術。其中一項技術是獨立於順序的混合,即使用不依賴於三角形光柵化順序的混合方程。有兩種基本可能性:疊加混合和相乘混合。
疊加混合的標準示例是本頁中的雙重曝光:顏色被疊加,因此無法(或至少很難)說出照片拍攝的順序。疊加混合可以用 關於透明度的教程 中介紹的混合方程來表徵
vec4 result = SrcFactor * gl_FragColor + DstFactor * pixel_color;
其中 SrcFactor 和 DstFactor 由 Blender 的 Python API 函式設定
bge.types.KX_BlenderMaterial.setBlending({code for SrcFactor},{code for DstFactor})
對於疊加混合,DstFactor 的程式碼必須為 bge.logic.BL_ONE,而 SrcFactor 的程式碼不能依賴於幀緩衝區中的畫素顏色;也就是說,它可以是 bge.logic.BL_ONE、bge.logic.BL_SRC_COLOR、bge.logic.BL_SRC_ALPHA、bge.logic.BL_ONE_MINUS_SRC_COLOR 或 bge.logic.BL_ONE_MINUS_SRC_ALPHA。
示例如下
import bge
cont = bge.logic.getCurrentController()
VertexShader = """
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
"""
FragmentShader = """
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 0.3);
}
"""
mesh = cont.owner.meshes[0]
for mat in mesh.materials:
shader = mat.getShader()
if shader != None:
if not shader.isValid():
shader.setSource(VertexShader, FragmentShader, 1)
mat.setBlending(bge.logic.BL_SRC_ALPHA, bge.logic.BL_ONE)
請記住,您必須在 **3D 檢視** 選單中將 **視口著色** 設定為 **紋理** 以啟用混合。此外,您還應該啟用 **Z 透明度** 並停用 **背面剔除**,如 關於透明度的教程 中所述。
攝影中相乘混合的一個示例是使用多個均勻的灰色濾鏡:濾鏡疊加到相機上的順序對影像的最終衰減沒有影響。就三角形的光柵化而言,影像對應於三角形光柵化之前幀緩衝區的內容,而濾鏡對應於三角形。
在 Python 中使用以下程式碼指定相乘混合
bge.types.KX_BlenderMaterial.setBlending({code for SrcFactor},{code for DstFactor})
SrcFactor 的程式碼必須為 bge.logic.BL_ZERO,而 DstFactor 的程式碼必須依賴於片段顏色;也就是說,它可以是 bge.logic.BL_SRC_COLOR、bge.logic.BL_SRC_ALPHA、bge.logic.BL_ONE_MINUS_SRC_COLOR 或 bge.logic.BL_ONE_MINUS_SRC_ALPHA。使用 bge.logic.BL_ONE_MINUS_SRC_ALPHA 作為 DstFactor 的程式碼,可以衰減由片段的 alpha 分量指定的背景,這是一種典型的示例。
import bge
cont = bge.logic.getCurrentController()
VertexShader = """
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
"""
FragmentShader = """
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 0.3);
}
"""
mesh = cont.owner.meshes[0]
for mat in mesh.materials:
shader = mat.getShader()
if shader != None:
if not shader.isValid():
shader.setSource(VertexShader, FragmentShader, 1)
mat.setBlending(bge.logic.BL_ZERO,
bge.logic.BL_ONE_MINUS_SRC_ALPHA)
恭喜您,您已經完成了本教程。我們已經瞭解了以下內容:
- 什麼是獨立於順序的透明度和獨立於順序的混合。
- 兩種最重要的獨立於順序的混合型別是什麼(疊加和相乘)。
- 如何實現疊加和相乘混合。
如果您想了解更多
- 關於著色器程式碼的資訊,請閱讀 關於透明度的教程.
- 關於另一種獨立於順序的透明度技術,即深度剝離,您可以閱讀 Cass Everitt 的技術報告:“互動式獨立於順序的透明度”,該報告可以在 網上 獲取。