跳转到内容

GLSL 编程/GLUT/顺序无关透明度

来自维基教科书,开放的书,开放的世界
“Where Have You Bean” 来自 flickr 用户 Ombligotron。标题中的拼写错误指的是名为 “Cloud Gate” 或 “The Bean” 的雕塑。

本教程涵盖了顺序无关混合

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

“84 – Father son” 来自 Ben Newton。双重曝光的例子。

顺序无关混合

[编辑 | 编辑源代码]

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

加法混合

[编辑 | 编辑源代码]

加法混合的标准示例是双重曝光,如本页上的图像所示:颜色被添加在一起,因此无法(或至少非常难)说出照片的拍摄顺序。加法混合可以用透明度教程中介绍的混合方程来描述

vec4 result = SrcFactor * gl_FragColor + DstFactor * pixel_color;

其中 SrcFactorDstFactor 由 OpenGL 的一个函数设置

glBlendFunc({SrcFactor 的代码},{DstFactor 的代码})

对于加法混合,DstFactor 的代码必须是 GL_ONE,而 SrcFactor 的代码不能依赖于帧缓冲区中的像素颜色;即它可以是 GL_ONEGL_SRC_COLORGL_SRC_ALPHAGL_ONE_MINUS_SRC_COLORGL_ONE_MINUS_SRC_ALPHA

一个例子是

attribute vec3 v_coord;
uniform mat4 m, v, p;

void main()
{
  vec4 v_coord4 = vec4(v_coord, 1.0);
  mat4 mvp = p*v*m;
  gl_Position = mvp * v_coord4;
}
void main()
{
  gl_FragColor = vec4(0.0, 1.0, 0.0, 0.3); 
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE)

请记住,您必须在3D 视图菜单中将视口着色设置为纹理,才能激活混合。此外,您应该激活Z 透明度并停用背面剔除,如透明度教程中所述。

乘法混合

[编辑 | 编辑源代码]

摄影中乘法混合的一个例子是使用多个统一的灰色滤镜:滤镜放在相机上的顺序对最终图像的衰减没有影响。在三角形栅格化方面,图像对应于三角形栅格化之前帧缓冲区的内容,而滤镜对应于三角形。

当使用以下方法在 OpenGL 中指定乘法混合时

glBlendFunc({SrcFactor 的代码},{DstFactor 的代码})

SrcFactor 的代码必须是 GL_ZERO,而 DstFactor 的代码必须依赖于片段颜色;即它可以是 GL_SRC_COLORGL_SRC_ALPHAGL_ONE_MINUS_SRC_COLORGL_ONE_MINUS_SRC_ALPHA。使用 GL_ONE_MINUS_SRC_ALPHA 作为 DstFactor 的代码,是衰减背景(其不透明度由片段的 alpha 分量指定)的一个典型例子

attribute vec3 v_coord;
uniform mat4 m, v, p;

void main()
{
  vec4 v_coord4 = vec4(v_coord, 1.0);
  mat4 mvp = p*v*m;
  gl_Position = mvp * v_coord4;
}
void main()
{
  gl_FragColor = vec4(0.0, 1.0, 0.0, 0.3); 
}
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA)

恭喜您已完成本教程。我们已经了解了

  • 什么是顺序无关透明度和顺序无关混合。
  • 两种最重要的顺序无关混合类型是什么(加法和乘法)。
  • 如何实现加法和乘法混合。

进一步阅读

[编辑 | 编辑源代码]

如果您还想了解更多

  • 关于着色器代码,您应该阅读透明度教程
  • 关于另一种顺序无关透明度技术,即深度剥离,您可以阅读 Cass Everitt 的技术报告:“Interactive Order-Independent Transparency”,该报告可在网上获得。


< GLSL 编程/GLUT

除非另有说明,本页上的所有示例源代码均授予公有领域。
返回OpenGL 编程 - 照明部分 返回GLSL 编程 - GLUT 部分
华夏公益教科书