跳转到内容

GLSL 编程/Blender/独立于顺序的透明度

来自 Wikibooks,开放世界中的开放书籍
“Where Have You Bean” 由 flickr 用户 Ombligotron 拍摄。标题中的拼写错误指的是被描绘的雕塑“云门”,又名“豆子”。

本教程涵盖 **独立于顺序的混合**。

它继续讨论 关于透明度的教程,并解决了标准透明度的一些问题。如果您还没有阅读过该教程,建议您先阅读。

“84 – Father son” 由 Ben Newton 拍摄。双重曝光的示例。

独立于顺序的混合

[编辑 | 编辑源代码]

正如 关于透明度的教程 中所述,混合的结果通常(特别是对于标准 alpha 混合)取决于三角形渲染的顺序,因此如果三角形没有从后到前排序(通常不会),就会导致渲染伪像。术语“独立于顺序的透明度”描述了各种避免此问题的技术。其中一项技术是独立于顺序的混合,即使用不依赖于三角形光栅化顺序的混合方程。有两种基本可能性:叠加混合和相乘混合。

叠加混合

[编辑 | 编辑源代码]

叠加混合的标准示例是本页中的双重曝光:颜色被叠加,因此无法(或至少很难)说出照片拍摄的顺序。叠加混合可以用 关于透明度的教程 中介绍的混合方程来表征

vec4 result = SrcFactor * gl_FragColor + DstFactor * pixel_color;

其中 SrcFactorDstFactor 由 Blender 的 Python API 函数设置

bge.types.KX_BlenderMaterial.setBlending({code for SrcFactor},{code for DstFactor})

对于叠加混合,DstFactor 的代码必须为 bge.logic.BL_ONE,而 SrcFactor 的代码不能依赖于帧缓冲区中的像素颜色;也就是说,它可以是 bge.logic.BL_ONEbge.logic.BL_SRC_COLORbge.logic.BL_SRC_ALPHAbge.logic.BL_ONE_MINUS_SRC_COLORbge.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_COLORbge.logic.BL_SRC_ALPHAbge.logic.BL_ONE_MINUS_SRC_COLORbge.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 的技术报告:“交互式独立于顺序的透明度”,该报告可以在 网上 获取。


< GLSL 编程/Blender

除非另有说明,否则本页上的所有示例源代码均为公有领域。
华夏公益教科书