专业网站制作技术,做自媒体需要用的网站,必应网站提交入口,京东网上购物官方网站AlphaBlend
OpenGL-ES 混合本质上是将 2 个片元的颜色进行调和(一般是求和操作)#xff0c;产生一个新的颜色 OpenGL ES 混合发生在片元通过各项测试之后#xff0c;准备进入帧缓冲区的片元和原有的片元按照特定比例加权计算出最终片元的颜色值#xff0c;不再是新#xf…AlphaBlend
OpenGL-ES 混合本质上是将 2 个片元的颜色进行调和(一般是求和操作)产生一个新的颜色 OpenGL ES 混合发生在片元通过各项测试之后准备进入帧缓冲区的片元和原有的片元按照特定比例加权计算出最终片元的颜色值不再是新源片元直接覆盖缓冲区中的目标片元。 OpenGL-ES 混合方程 CresultCsource∗Fsource Cdestination∗Fdestination
其中 其中 Csource源颜色向量来自纹理的颜色向量 Cdestination目标颜色向量储存在颜色缓冲中当前位置的颜色向量 Fsource源因子设置了对源颜色加权 Fdestination目标因子设置了对目标颜色加权 操作符可以是加、减-、Min、Max 等。
这里的向量可以理解为通道的含义比如 RGB 可以用 Vec3 来表示
编程方法
开启 Alpha Blend
启用 OpenGL ES 混合使用 glEnable(GL_BLEND); 然后通过 glBlendFunc 设置混合的方式其中 sfactor 表示源因子dfactor 表示目标因子
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// GL_SRC_ALPHA 表示源因子取值为源颜色的 alpha
// GL_ONE_MINUS_SRC_ALPHA 表示目标因子取值为 1- alpha源颜色的 alpha
// 操作符默认为 GL_FUNC_ADD 即加权相加。
// 混合公式变成了 源颜色向量 × alpha 目标颜色向量 × 1- alpha注意下面的混和因子说明表格中存在 const alpha 的选项既可以使用 const alpha 混合
定义颜色操作符
我们也可以通过 glBlendEquation 自定义两个颜色之间的操作符:
GL_FUNC_ADD默认的彼此元素相加CresultCSrc CDst GL_FUNC_SUBTRACT彼此元素相减CresultCSrc − CDst GL_FUNC_REVERSE_SUBTRACT彼此元素相减但顺序相反CresultCDst - CSrc GL_MIN混合结果的 4 个通道值分别取 2 元素中 4 个通道较小的值 GL_MAX混合结果的 4 个通道值分别取 2 元素中 4 个通道较大的值
颜色通道和Alpha 通道分开设置
//对 RGB 和 Alpha 分别设置 BLEND 函数
//void glBlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha);
glBlendFuncSeperate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);//混合结果颜色 RGB 向量 源颜色 RGB 向量 × alpha 目标颜色 RGB 向量 × (1- alpha);
//混合结果颜色 alpha 源颜色 alpha × 1 目标颜色 alpha × 0;也可以为 RGB通道和 alpha 通道设置不同的操作符
void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);sss
验证代码
下面的代码中loadTgaTextures 生成了两张 Texture在绘制的时候绘制了两次第一次绘制了 Dst第二次绘制了 Src指定 const alpha 的 SFactor 和 DFactor 都为 0.5
typedef struct
{GLuint programObject;GLint samplerLocal;GLuint textureIdDst;GLuint textureIdSrc;
} UserData;static int Init(ESContext *esContext)
{UserData *userData esContext-userData;char vShaderStr[] #version 300 es \nlayout(location 0) in vec4 a_position; \nlayout(location 1) in vec2 a_texCoord; \nout vec2 v_texCoord; \nvoid main() \n{ \n gl_Position a_position; \n v_texCoord a_texCoord; \n} \n;char fShaderStr[] #version 300 es \nprecision mediump float; \nin vec2 v_texCoord; \nlayout(location 0) out vec4 outColor; \nuniform sampler2D s_texture; \nvec4 tempColor; \nvoid main() \n{ \n tempColor texture( s_texture, v_texCoord ); \n outColor vec4(tempColor.r, tempColor.b, tempColor.g, tempColor.a); \n} \n;userData-programObject esLoadProgram(vShaderStr, fShaderStr);userData-samplerLocal glGetUniformLocation(userData-programObject, s_texture);userData-textureIdSrc loadTgaTextures(./Huskey.tga);userData-textureIdDst loadTgaTextures(./scene.tga);// 启用 alpha 混合 指定 const alpha 值为 0.5glEnable(GL_BLEND);glBlendColor(1.0f, 1.0f, 1.0f, 0.5f);glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);glClearColor(1.0f, 1.0f, 1.0f, 0.0f);return TRUE;
}static void Draw(ESContext *esContext)
{UserData *userData esContext-userData;GLfloat vVertices[] {-1.0f, 1.0f, 0.0f, // Position 00.0f, 0.0f, // TexCoord 0 -1.0f, -1.0f, 0.0f, // Position 10.0f, 1.0f, // TexCoord 11.0f, -1.0f, 0.0f, // Position 21.0f, 1.0f, // TexCoord 21.0f, 1.0f, 0.0f, // Position 31.0f, 0.0f // TexCoord 3};GLushort indices[] { 0, 1, 2, 0, 2, 3 };glViewport(0, 0, esContext-width, esContext-height);glClear(GL_COLOR_BUFFER_BIT);glUseProgram(userData-programObject);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices[3]);glEnableVertexAttribArray(0);glEnableVertexAttribArray(1);// Bind the textureglActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, userData-textureIdDst);// Set the sampler texture unit to 0glUniform1i(userData-samplerLocal, 0);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);// 任然使用可以 texture0, 但是可以指定不同的 texture idglActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, userData-textureIdSrc);glUniform1i(userData-samplerLocal, 0);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}实际效果如下