四.OpenGL 颜色混合

2020-07-11  本文已影响0人  凯歌948

我们把OpenGL 渲染时会把颜⾊值存在颜色缓存区中,每个片段的深度值也是放在深度缓冲区。当深度 缓冲区被关闭时,新的颜⾊将简单的覆盖原来颜⾊缓存区存在的颜色值,当深度缓冲区再次打开时,新的颜⾊⽚段只是当它们比原来的值更接近邻近的裁剪平⾯才会替换原来的颜⾊⽚段。

当混合功能被启动时,源颜色和目标颜⾊的组合方式是混合方程式控制的。
在默认情况下,混合方程式如下所示:
Cf = (Cs * S) + (Cd * D)
Cf :最终的颜⾊
Cs :源颜⾊ (作为当前渲染命令结果进入颜⾊缓存区的颜色值)
Cd :⽬标颜⾊ (已经存储在颜色缓存区的颜色值)
S :源混合因⼦
D :目标混合因⼦


image2.png

设置混合因⼦,需要用到glBlendFun函数
glBlendFunc(GLenum S,GLenum D);
S:源混合因⼦
D:目标混合因⼦


image1.png

核心代码只要下面3个函数:

//开启颜色混合
glEnable(GL_BlEND);

//如果颜色缓存区已经有一种颜⾊红⾊(1.0f,0.0f,0.0f,1.0f),如果在这上面⽤一种alpha为0.6的蓝色(0.0f,0.0f,1.0f,0.6f);那么:
//Cd (目标颜⾊) = (1.0f,0.0f,0.0f,1.0f); 
//Cs (源颜⾊) = (0.0f,0.0f,1.0f,0.6f); 
//S = 源alpha值 = 0.6f
//D = 1 - 源alpha值= 1-0.6f = 0.4f
//方程式Cf = (Cs * S) + (Cd * D)
//等价于 = (Blue * 0.6f) + (Red * 0.4f)
//设置混合颜色因子
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

//关闭颜色混合
glDisable(GL_BLEND);

最终颜色是以原先的红⾊(⽬标颜⾊)与后来的蓝⾊(源颜⾊)进行组合。源颜⾊的alpha值越⾼,添加的蓝色颜⾊成分越⾼,⽬标颜色所保留的成分就会越少。 混合函数经常⽤于实现在其他一些不透明的物体前面绘制一个透明物体的效果。

以下是补充知识:

除了能使用glBlendFunc 来设置混合因子,还可以有更灵活的选择。
void glBlendFuncSeparate(GLenum strRGB,GLenum dstRGB ,GLenum strAlpha,GLenum dstAlpha);
strRGB: 源颜色的混合因⼦ 
dstRGB: 目标颜色的混合因⼦
strAlpha: 源颜色的Alpha因⼦
dstAlpha: ⽬标颜⾊的Alpha因⼦

glBlendFunc 指定源和⽬标RGBA值的混合函数;但是glBlendFuncSeparate函数则允许为RGB 和 Alpha 成分单独指定混合函数。

在混合因子表中,GL_CONSTANT_COLOR,GL_ONE_MINUS_CONSTANT_COLOR,GL_CONSTANT_ALPHA,GL _ONE_MINUS_CONSTANT值允许混合方程式中引入一个常量混合颜色。

常量混合颜色,默认初始化为⿊色(0.0f,0.0f,0.0f,1.0f),但是还是可以修改这个常量混合颜色。
void glBlendColor(GLclampf red ,GLclampf green ,GLclampf blue ,GLclampf alpha );

综合练习:

 
    /*-----------核心代码(边框部分)-------------------*/
    /*
        glEnable(GLenum mode); 用于启用各种功能。功能由参数决定
        参数列表:http://blog.csdn.net/augusdi/article/details/23747081
        注意:glEnable() 不能写在glBegin() 和 glEnd()中间
        GL_POLYGON_OFFSET_LINE  根据函数glPolygonOffset的设置,启用线的深度偏移
        GL_LINE_SMOOTH          执行后,过虑线点的锯齿
        GL_BLEND                启用颜色混合。例如实现半透明效果
        GL_DEPTH_TEST           启用深度测试 根据坐标的远近自动隐藏被遮住的图形(材料
     
        glDisable(GLenum mode); 用于关闭指定的功能 功能由参数决定
     */
    
    //画黑色边框
    //多变形偏移
    glPolygonOffset(-1.0f, -1.0f);//偏移深度,在同一位置要绘制填充边线,会产生z冲突,所以要偏移
    glEnable(GL_POLYGON_OFFSET_LINE);//根据函数glPolygonOffset的设置,启用线的深度偏移
    
    //开启反锯齿,使线条平滑
    glEnable(GL_LINE_SMOOTH);
    //开启颜色混合
    glEnable(GL_BLEND);
    //设置混合颜色因子
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    //绘制线框几何黑色版 三种模式,实心,边框,点,可以作用在正面,背面,或者两面
    //通过调用glPolygonMode将多边形正面或者背面设为线框模式,实现线框渲染
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    //设置线条宽度
    glLineWidth(2.5f);
    
    /* GLShaderManager 中的Uniform 值——平面着色器
     参数1:平面着色器
     参数2:运行为几何图形变换指定一个 4 * 4 变换矩阵
           transformPipeline.GetModelViewProjectionMatrix() 获取的
           GetMatrix函数就可以获得矩阵堆栈顶部的值
     参数3:颜色值(黑色)
     */
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
    pBatch->Draw();

    //复原原本的设置
    //通过调用glPolygonMode将多边形正面或者背面设为全部填充模式
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    //关闭线的偏移
    glDisable(GL_POLYGON_OFFSET_LINE);
    glLineWidth(1.0f);
    //关闭颜色混合
    glDisable(GL_BLEND);
    //关闭反锯齿
    glDisable(GL_LINE_SMOOTH);

效果如下:


image3.png
上一篇下一篇

猜你喜欢

热点阅读