OpenGL: 混合

6.1 混合

6.1.1 源因子和目标因子

假定源和目标混合因子分别为(Sr, Sg, Sb, Sa)和(Dr,Dg,Db,Da), 混合后的RGB值如下:

(RsSr + RdDr, GsSg + GdDg, BsSb + BdDb, AsSa + AdDa)

最后,将该四元组的各个分量截取到[0,1].

将源片元和目标象素合并起来的默认方式是,将它们的值相加.

 

选择源混合因子和目标混合因子的方式:

第一种方式是调用函数glBlendFunc(),并指定两个混合因子, 其中第一个参数为源RGBA的混合因子, 第二个参数为目标RGBA的混合因子.

第二种方法是调用glBlendFuncSeparate()并指定4个混合因子, 这样可以用不同的方式来混合RGB和alpha值.

void glBlendFunc(GLenum srcfactor, GLenum destfactor);

srcfactor指出如何计算源混合因子; destfactor指出如何计算目标混合因子.

void glBlendFuncSeparate(GLenum srcRGB, GLenum destRGB, GLenum srcalpha, GLenum destalpha);

源混合因子和目标混合因子

常量: RGB混合因子                alpha混合因子

GL_ZERO: (0, 0, 0)             0

GL_ONE: (1, 1, 1)               1

GL_DST_COLOR: (Rd, Gd, Bd)

GL_SRC_COLOR: (Rs, Gs, Bs)  A

GL_ONE_MINUS_DST_COLOR: (1, 1, 1) - (Rd, Gd, Bd)

GL_ONE_MINUS_SRC_COLOR: (1, 1, 1) - (Rs, Gs, Bs)    1 - A

GL_SRC_ALPHA: (As,As,As,As)

GL_ONE_MINUS_SRC_ALPHA: (1, 1, 1, 1) - (As,As,As,As)

GL_DST_ALPHA: (Ad, Ad, Ad, Ad)

GL_ONE_MINUS_DST_ALPHA: (1, 1, 1, 1) - (Ad, Ad, Ad, Ad)

GL_SRC_ALPHA_STATURATE: (f, f, f, 1); f = min(As, 1 - Ad)

 

另将GL*CONSTANT*作为参数时, 需要使用glBlendColor()指定一个常量(constant)颜色

void glBlenColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

设置执行混合操作时使用的常量颜色的红,绿,蓝和alpha值(Rc, Gc, Bc, Ac)

 

6.1.2 启用混合操作

glEnable(GL_BLEND);

 

6.1.3 使用混合方程来合并像素

采用标准混合方式时, 将帧缓存中的颜色和输入片元的颜色合并起来, 得到新的帧缓存颜色.

void glBlendEquation(GLenum mode);

上面的函数用来指定其他数学运算,以计算帧缓存颜色和片元颜色的差, 它们中的最大值或最小值.

指定如何混合帧缓存中的颜色和片元颜色.

Cs和Cd表示源颜色和目标颜色, S和D表示函数glBlendFunc()或glBlendFuncSeparate()指定的源混合因子和目标混合因子.

GL_FUNC_ADD                                     CsS + CdD

GL_FUNC_SUBTRACT                          CsS - CdD

GL_FUNC_REVERSE_SUBTRACT       CdD - CsS

GL_MIN                                        min(CsS, CdD)

GL_MAX                                        max(CsS, CdD)

 

要使用OpenGL扩展代码

1. 增加头文件

#include

2. 定义函数指针

PFNGLBLENDEQUATIONPROC glBlendEquation = NULL;        //定义函数指针

3. 在内存中找到函数地址

PFNGLBLENDEQUATIONPROC glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation");

 

使用深度透视,重绘的时候要注意清除深度缓存,否则会消失.

 

6.1.4 混合的用途

1. 均匀地混合两幅图像:

   首先将源因子和目标因子分别设置为GL_ONE和GL_ZERO. 并绘制第一副图像.

   然后将源因子设置为GL_SRC_ALPHA, 目标因子设置为GL_ONE_MINUS_SRC_ALPHA, 并在绘制第二幅图像时使用alpha值0.5. 这是最常用的混合方式.

   如要设置第一副图像占75%, 第二幅图像占25%. 可以在绘制第二幅图像使用alpha值0.25.

2. 均匀地混合三幅图像, 目标因子设置为GL_SRC_ALPHA, 然后使用alpha值 0.3333333绘制这些图像.这样每幅图像的亮度只有原来的三分之一.

3. 逐渐加深图像的颜色: 源混合因子和目标混合因子分别设置为GL_SRC_ALPHA和GL_ONE_MINUS_SRC_ALPHA, 并将画笔的alpha值设置为0.1

4. 通过将源混合因子设置为GL_DST_COLOR或GL_ONE_MINUS_DST_COLOR.将目标混合因子设置为GL_SRC_COLOR或GL_ONE_MINUS_SRC_COLOR,可以分别调整各个颜色分量.

   相当于使用一个简单的滤光器.

   如红色分量乘以0.8,绿色分量乘以0.4,蓝色分量乘以0.72. 相当于滤光器滤掉20%的红光, 60%的绿光和28%的蓝光.

5. 纯色背景三个半透明面组成的图像.最远的透过其后80%的颜色, 接下来的面40%,最近的90%.

   首先用默认的源混合因子和目标混合因子绘制背景

   然后源混合因子和目标混合因子为GL_SRC_ALPHA和GL_ONE_MINUS_SRC_ALPHA, 并依次是哟个alpha值0.2绘制最远的面,0.6绘制中间面,0.1绘制最近的面.

6. 如果系统有alpha位面, 可以每次渲染一个物体, 然后将它们读取到内存中, 然后对渲染后的物体执行有趣的合成操作.

7. 通过给图像中的片元指定不同的alpha值,可以实现非矩形光栅图像的效果.

   透明片元的alpha值设置为0, 不透明片元的alpha值设置为1.0.

8. 混合也可以用于实现反走样.

 

6.1.5 一个混合的例子




6.1.6 使用深度缓存的三维混合

方法: 启用深度缓存, 并在绘制半透明物体时, 将深度缓存设置为只读的.

首先, 将深度缓存设置为正常状态, 并绘制所有的不透明物体, 然后将深度缓存设置为只读的, 并使这些深度值保持不变. 绘制半透明物体时,将深度同不透明物体的深度值进行比较,这样, 如果他们位于不透明物体后面,不绘制他们, 如果它们离视点更近, 也不会消除不透明物体, 因为深度缓存的值是无法修改的,而是与不透明物体混合在一起.

 

函数glDepthMask()可以控制深度缓存的读写状态. 参数GL_FALSE将深度缓存设置为只读. 参数GL_TRUE设置为可写.

你可能感兴趣的:(OpenGL)