一文详解 OpenGL ES 纹理颜色混合的方法

目录
  • 一、混合API
  • 二、参数含义
    • 2.1 举个栗子
    • 2.2 参数含义
  • 三、 几种常用混合方式效果
    • 3.1 混合(GL_ONE, GL_ZERO)
    • 3.2 混合(GL_ONE, GL_ONE)
    • 3.3 混合(GL_ONE, GL_ONE_MINUS_DST_ALPHA)
    • 3.4 混合 (GL_SRC_ALPHA, GL_ONE)
    • 3.5 混合 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

在OpenGL中绘制的时候,有时候想使新画的颜色和已经有的颜色按照一定的方式进行混合。例如:想使物体拥有半透明的效果,或者绘制叠加光亮的效果,这时候就需要用到OpenGLES混合

如上图所示,为石头墙、绿色矩形、蓝色云彩 三个矩形混合后的展示效果。三个矩形(Z轴深度由深到浅)分别为,石头墙、绿色矩形、蓝色云彩。

一、混合API

在OpenGLES中若使用混合,需要用到API函数方法(Java):
void glBlendFunc( int srcfactor, int destfactor );

(1) 其OpenGL函数原型为:
void glBlendFunc(GLenum srcfactor, GLenum destfactor);

(2) 其功能为:
控制新画上来的颜色 (source values, RGBA) 和 已经在帧缓冲区中的颜色 (destination values, RGBA) 的混合时源与目标 在最终颜色通道中所占的比例

(3) 方法参数

  • srcfactor:代表源因子,即新画上来的颜色。

该参数由九个枚举型被接受使用:
GL_ZERO,
GL_ONE,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA,
GL_SRC_ALPHA_SATURATE.

  • destfactor:代表的是目标因子,即已经在帧缓冲区中的颜色。

该参数由八个枚举型被接受使用:
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA

二、参数含义

  • 举个栗子
  • 参数含义

2.1 举个栗子

我们先看一个常用混合参数搭配:

// 最常用的混合因子搭配方式
// 即源因子为 GL_SRC_ALPHA 目标因子为 GL_ONE_MINUS_SRC_ALPHA
glBlendFunc(GL30.GL_SRC_ALPHA, GL30.GL_ONE_MINUS_SRC_ALPHA);

以上参数搭配方式假设:

  • (Sr, Sg, Sb, Sa)代表源颜色src(要绘制的颜色)
  • (Dr, Dg, Db, Da)代表目标颜色Dest(缓冲区中颜色)

如果源因子的不透明度为0.2(透明度0.8),alpha值的最大值为1,那么源与目标混合后的最终颜色值为:

// 最终颜色值为:0.2*S+0.8*D
// OpenGL ES 最终颜色计算结果如下:
(0.2*Sr+(1-0.2)*Dr , 0.2*Sg+(1-0.2)*Dg , 0.2*Sb+(1-0.2)*Db,0.2*Sa+(1-0.2)*Da)

启用混合与纹理矩形绘制顺序代码举例:

// 开启混合
gl.glEnable(GL10.GL_BLEND);
// 指定混合比例
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);  

// 绘制石头墙纹理矩形
gl.glPushMatrix();
gl.glTranslatef(-0.8f, -0.8f, -0.02f);
wallRect.drawSelf(gl, tex_wall);
gl.glPopMatrix();  

// 绘制绿色纹理矩形
gl.glPushMatrix();
gl.glTranslatef(0, 0, -0.01f);
greenRect.drawSelf(gl, tex_green);
gl.glPopMatrix();  

// 绘制蓝色云彩纹理矩形
gl.glPushMatrix();
gl.glTranslatef(0.8f, 0.8f, 0f);
cloudRect.drawSelf(gl, tex_cloud);
gl.glPopMatrix();`

2.2 参数含义

有了上边的例子,我们再回来看各个参数因子。

假设:

  • (Sr, Sg, Sb, Sa)代表源颜色src(要绘制的颜色)
  • (Dr, Dg, Db, Da)代表目标颜色Dest(缓冲区中颜色)
  • (Kr, Kg, Kb, Ka)代表缓冲区中各个通道R, G, B, A的最大值。

那么各个参数因子所代表的值如下表所示:

混合因子 各颜色通道色彩比例值
GL_ZERO (0,0,0,0)
GL_ONE (1,1,1,1)
GL_SRC_COLOR (Sr/Kr, Sg/Kg, Sb/Kb, Sa/Ka)
GL_DST_COLOR (Dr/Kr, Dg/Kg, Db/Kb, Da/Ka)
GL_ONE_MINUS_SRC_COLOR (1,1,1,1) - (Sr/Kr,Sg/Kg,Sb/Kb,Sa/Ka)
GL_ONE_MINUS_DST_COLOR (1,1,1,1) - (Dr/Kr,Dg/Kg,Db/Kb,Da/Ka)
GL_SRC_ALPHA ( Sa/Ka, Sa/Ka, Sa/Ka, Sa/Ka )
GL_ONE_MINUS_SRC_ALPHA (1,1,1,1) - (Sa/Ka,Sa/Ka,Sa/Ka,Sa/Ka)
GL_DST_ALPHA ( Da/Ka, Da/Ka, Da/Ka, Da/Ka )
GL_ONE_MINUS_DST_ALPHA (1,1,1,1) - (Da/Ka,Da/Ka,Da/Ka,Da/Ka)
GL_SRC_ALPHA_SATURATE (min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,1)

三、 几种常用混合方式效果

下边以三张纹理图片在不同混合因子设置下的效果图,对几种常见的混合效果进行举例说明。

  • 其中 离摄像机最远的为一张 Alpha=1.0石头墙纹理图;
  • 其次 为一张 Alpha=0.6蓝色云彩纹理图;
  • 最后离摄像机最近的为一张 Alpha=0.4的绿色纹理图。

3.1 混合(GL_ONE, GL_ZERO)

源颜色(最后绘制的绿色矩形)参数因子为GL_ONE,目标色(缓冲区中颜色)参数因子为GL_ZERO。

这种参数因子组合混合比例 (1.0, 0.0)

  • 源颜色(最后绘制的绿色矩形)覆盖目标色(缓冲区中颜色);
  • 目标色(缓冲区中颜色)不起作用,

其运行效果如下图所示:

3.2 混合(GL_ONE, GL_ONE)

源颜色(最后绘制的绿色矩形)与 目标色(缓冲区中颜色)均为GL_ONE。

这种参数因子组合混合比例 (1.0, 1.0)

  • 源颜色(最后绘制的绿色矩形)目标色(缓冲区中颜色)在混合时,源与目标的色彩通道颜色所占的比例相同

其运行效果如下图所示:

仔细观察以上效果图,可以看到三张图片叠加部分,几乎为白色。

3.3 混合(GL_ONE, GL_ONE_MINUS_DST_ALPHA)

源颜色(最后绘制的绿色矩形)参数因子为 GL_ONE,目标色(缓冲区中颜色)参数因子为 GL_ONE_MINUS_DST_ALPHA。

这种参数因子组合混合比例 (1.0, 1.0-Da/Ka)

  • 源颜色(最后绘制的绿色矩形)目标色(缓冲区中颜色),在混合时取源颜色 (1- Da/Ka)比例进行混合。

其运行效果如下图所示:

观察以上效果图:可以看到最上边绿色矩形占最终混合颜色的比例较高。
三张纹理绘制时:

  • 前两张纹理混合时:源颜色为蓝色云彩纹理矩形,目标颜色为石头墙纹理矩形
  • 由于混合比例为 (1.0, 1.0-Da/Ka),混合后的最终颜色只显示蓝色云彩纹理矩形(石头墙纹理的ALPHA=1.0,最终石头墙颜色所占的比例 1.0-1.0=0.0,比例为0)。
  • 其次绿色纹理矩形缓冲区中颜色进行混合:源颜色为绿色纹理矩形,目标颜色为缓冲区中颜色

混合后的最终颜色基本只显示绿色纹理矩形(蓝色云彩纹理矩形的ALPHA=0.6,(1-0.6)云纹理与绿色矩形混合后,几乎看不到云纹理的颜色)。

3.4 混合 (GL_SRC_ALPHA, GL_ONE)

源颜色(最后绘制的绿色矩形)参数因子为 GL_SRC_ALPHA,目标色(缓冲区中颜色)参数因子为 GL_ONE。

这种参数因子组合混合比例 (Sa/Ka, 1.0)

  • 源颜色(最后绘制的绿色矩形)目标色(缓冲区中颜色),在混合时以源颜色值乘以Sa/Ka与目标颜色值相加。

其运行效果如下图所示:

观察以上效果图,可以看出目标墙面与云纹理混合后墙面纹理颜色值所占比例较高,三个纹理图片叠加部分有些像素点为白色。

3.5 混合 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

这种方式是最常用的混合方式,源颜色(最后绘制的绿色矩形)参数因子为 GL_SRC_ALPHA,目标色(缓冲区中颜色)参数因子为 GL_ONE_MINUS_SRC_ALPHA。

这种参数因子组合混合比例 (Sa/Ka, 1.0-Sa/Ka)

  • 源颜色(最后绘制的绿色矩形)目标色(缓冲区中颜色)在混合时,取源颜色的 (Sa/Ka) 与目标颜色 (1.0-Sa/Ka) 相加计算最终的颜色值。

其运行效果如下图所示:

附案例代码

案例源码下载地址:
https://download.csdn.net/download/aiwusheng/64038379

到此这篇关于一文详解 OpenGL ES 纹理颜色混合的文章就介绍到这了,更多相关OpenGL ES 纹理颜色混合内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 通过OpenGL ES混合模式缩放视频缓冲区来适应显示尺寸

    当开发基于软件模式的游戏时,通过缩放视频缓冲区来适应显示尺寸是最棘手的问题之一.当面对众多不同的分辨率时(比如开放环境下的Android),该问题会变得更加麻烦,作为开发人员,我们必须尝试在性能与显示质量之间找到最佳平衡点.正如我们在第2章中看到的,缩放视频缓冲区从最慢到最快共有3种类型. 软件模拟:3中类型中最慢,但最容易实现,是没有GPU的老款设备上的最佳选择.但是现在大部分智能手机都支持硬件加速. 混合模式:这种方式混合使用软件模拟(创建图像缓冲区)和硬件渲染(向显示屏绘制)两种模式.这种

  • 一文详解 OpenGL ES 纹理颜色混合的方法

    目录 一.混合API 二.参数含义 2.1 举个栗子 2.2 参数含义 三. 几种常用混合方式效果 3.1 混合(GL_ONE, GL_ZERO) 3.2 混合(GL_ONE, GL_ONE) 3.3 混合(GL_ONE, GL_ONE_MINUS_DST_ALPHA) 3.4 混合 (GL_SRC_ALPHA, GL_ONE) 3.5 混合 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 在OpenGL中绘制的时候,有时候想使新画的颜色和已经有的颜色按照一定的方式

  • 详解Java ES多节点任务的高效分发与收集实现

    目录 一.概述 二.请求分发的简单思路 三.es中search的多节点分发收集 3.1.多节点响应结果处理 3.2.异步提交请求实现 一.概述 我们知道,当我们对es发起search请求或其他操作时,往往都是随机选择一个coordinator发起请求.而这请求,可能是该节点能处理,也可能是该节点不能处理的,也可能是需要多节点共同处理的,可以说是情况比较复杂. 所以,coordinator的重要工作是,做请求分发与结果收集.那么,如何高性能和安全准确地实现这一功能则至关重要. 二.请求分发的简单思

  • 一文详解JS私有属性的6种实现方式

    目录 _prop Proxy Symbol WeakMap #prop ts private 总结 class 是创建对象的模版,由一系列属性和方法构成,用于表示对同一概念的数据和操作. 有的属性和方法是对外的,但也有的是只想内部用的,也就是私有的,那怎么实现私有属性和方法呢? 不知道大家会怎么实现,我梳理了下,我大概用过 6 种方式,我们分别来看一下: _prop 区分私有和公有最简单的方式就是加个下划线 _,从命名上来区分. 比如: class Dong { constructor() {

  • 一文详解C#中方法重载的底层玩法

    目录 一:为什么 C 不支持 二:C++ 符号表突破 三:C#如何实现突破 最近在看 C++ 的方法重载,我就在想 C# 中的重载底层是怎么玩的,很多朋友应该知道 C 是不支持重载的,比如下面的代码就会报错. #include <stdio.h> int say() { return 1; } int say(int i) { return i; } int main() { say(10); return 0; } 从错误信息看,它说 say 方法已经存在了,尴尬... 一:为什么 C 不支

  • 一文详解Golang中net/http包的实现原理

    目录 前言 http包执行流程 http包源码分析 端口监听 请求解析 路由分配 响应处理 前言 Go语言自带的net/http包提供了HTTP客户端和服务端的实现,实现一个简单的http服务非常容易,其自带了一些列结构和方法来帮助开发者简化HTTP服务开发的相关流程,因此我们不需要依赖任何第三方组件就能构建并启动一个高并发的HTTP服务器,net/http包在编写web应用中有很重要的作用,这篇文章会学习如何用 net/http 自己编写实现一个 HTTP Server 并探究其实现原理,具体

  • 一文详解Golang 定时任务库 gron 设计和原理

    目录 cron 简介 gron 定时参数 源码解析 Cron Entry 按照时间排序 新增定时任务 启动和停止 Schedule 扩展性 经典写法-控制退出 结语 cron 简介 在 Unix-like 操作系统中,有一个大家都很熟悉的 cli 工具,它能够来处理定时任务,周期性任务,这就是: cron. 你只需要简单的语法控制就能实现任意[定时]的语义.用法上可以参考一下这个Crontab Guru Editor,做的非常精巧. 简单说,每一个位都代表了一个时间维度,* 代表全集,所以,上面

  • 详解OpenGL Shader抗锯齿的实现

    目录 绘制圆形锯齿问题 smoothstep函数介绍 抗锯齿实现 扩展 自制smoothstep函数抗锯齿 自制linearstep函数抗锯齿 绘制圆形锯齿问题 普通绘制圆形形状时可以看到图形边缘会有明显锯齿现象并不像真实圆形形状一样圆润边缘平滑.在glsl中这种情况是常见情况,这里是可以借助glsl内置函数来消除锯齿现象. vec3 sdfCircle(vec2 uv,float r,vec3 value){ float d = length(uv) - r; return d > 0. ?

  • 详解OpenGL Shader彩虹条纹效果的实现

    目录 前言 回顾 效果实现 增加条纹 角度变化 拓展 前言 在一款图片处理软件colorow中发现彩虹效果滤镜感觉蛮有意思. 在OpenGL Shader系列更新到现在尝试通过之前积累的知识点来自行实现效果. 回顾 之前使用过内置函数smoothstep可实现数值过渡效果.如下代码所示实现在坐标0.5分割黑色和白色分界. void main() { vec2 uv = gl_FragCoord.xy / iResolution.xy; vec3 color = vec3(0.); float g

  • 一文详解JS中的事件循环机制

    目录 前言 1.JavaScript是单线程的 2.同步和异步 3.事件循环 前言 我们知道JavaScript 是单线程的编程语言,只能同一时间内做一件事,按顺序来处理事件,但是在遇到异步事件的时候,js线程并没有阻塞,还会继续执行,这又是为什么呢?本文来总结一下js 的事件循环机制. 1.JavaScript是单线程的 JavaScript 是一种单线程的编程语言,只有一个调用栈,决定了它在同一时间只能做一件事.在代码执行的时候,通过将不同函数的执行上下文压入执行栈中来保证代码的有序执行.在

  • 一文详解如何用原型链的方式实现JS继承

    目录 原型链是什么 通过构造函数创建实例对象 用原型链的方式实现继承 方法1:Object.create 方法2:直接修改 [[prototype]] 方法3:使用父类的实例 总结 今天讲一道经典的原型链面试题. 原型链是什么 JavaScript 中,每当创建一个对象,都会给这个对象提供一个内置对象 [[Prototype]] .这个对象就是原型对象,[[Prototype]] 的层层嵌套就形成了原型链. 当我们访问一个对象的属性时,如果自身没有,就会通过原型链向上追溯,找到第一个存在该属性原

随机推荐