OpenGL ES简介
- 是以手持和嵌入式为目标的高级3D图形应用程序编程接口,例如:iOS、Android、Windows、Linux等
- 是
OpenGL
的子集 - 是跨平台的,不会提供窗口相关的方法,需要系统各自提供载体
OpenGL ES渲染流程
- CPU:使用OPenGL ES的API通过
OPenGL ES client
来调用OPenGL ES Server
,将顶点、纹理数据等传递给GPU - GPU:处理图形硬件,如:显示、光栅化等
渲染流程
OpenGL ES 图形管道
image.png
- Application:提供图元装配的顶点、图片信息
- Vertex(顶点着色器):处理顶点 --> 旋转、平移、缩放等
- Geometry(图元装配):图元装配 + 裁剪 + 光栅化
- Fragment(片元着色器):纹理处理 + 雾化处理 --> 提交到帧缓冲区
- Framebuffer Operations(帧缓冲区):透明度、模板、深度测试,最后混合
顶点着色器
处理顶点数据的着色器程序
输入
-
attribute通道
输入顶点数据,提供每个顶点的数据 -
uniform通道
输入同一变量,顶点、片元着色器中不发生变化的数据 -
采样器
表示顶点着色器使用纹理的特殊统一变量类型
输出
gl_Position
:GLSL的内建变量,即处理后的最终顶点数据
gl_PointSize
:顶点着色器中点的大小,不怎么使用
image.png
使用场景
可以⽤于执⾏⾃定义计算,实施新的变换,照明或者传统的固定功能所不允许
的基于顶点的效果
- 变换矩阵位置
- 生成、变换纹理坐标(片元着色器是没有办法传入属性即attribute的,可以通过顶点着色器桥接,间接将纹理坐标属性传递到片元着色器)
- 计算光照公式,生成顶点颜色
代码案例
attribute vec4 position; //四维向量
attribute vec2 textCoordinate; //二维向量
uniform mat4 rotateMatrix; //4*4矩阵
varying lowp vec2 varyTextCoord; //纹理坐标传入片元着色器
void main()
{
varyTextCoord = textCoordinate;
vec4 vPos = position;
vPos = vPos * rotateMatrix;//旋转
gl_Position = vPos;
}
图元装配
将顶点数据计算成一个个图元,这个阶段会执行裁剪、透视分割和Viewport变换
光栅化
将图元转化为一组二维片段的过程,主要是由于屏幕是2D的,所以转换的像素点也是二维的
片元着色器
输入
- 由顶点着色器穿过来的纹理坐标等
-
uniform通道
输入统一变量,即顶点、片元着色器中不改变的数据 -
采样器
:顶点着色器使用纹理的特殊统一变量类型,例如纹理
输出
-
gl_FragColor
:某个像素点经过片元着色器处理后的结果
image.png
使用场景
- 计算颜色
- 获取纹理值
- 往像素点中填充颜色值(纹理值/颜色值)
代码案例
varying lowp vec2 varyTextCoord; //必须和顶点着色器中一模一样,这样才能传递纹理坐标
uniform sampler2D colorMap;//采样器类型
void main() {
gl_FragColor = texture2D(colorMap, varyTextCoord); //获取对应位置/坐标的颜色值
}
总结
顶点着色器、片元着色器都是代码段,类似于iOS中有返回值的函数/方法,
- 顶点着色器的返回值会被复制给gl_Position
- 片元着色器的结果会赋值给gl_fragColor
这两个返回值都属于GLSL中的内建变量,是封装好的,直接将数据赋值给它即可
- gl_Position:顶点着色器中某一个顶点经过一系列处理后得到的结果
- gl_fragColor:经过片元着色器对某一个像素点来进行处理之后的结果
OpenGL ES的应用
图片滤镜
- 获取图片中的每一个像素点
- 像素点做饱和度处理
- 得到新的颜色
- 将新的颜色翻入帧缓存区
- 最后进行显示
视频滤镜
原理以及处理方式是一样的(GLSL代码),视频也是一帧一帧处理的,而一帧就是一张图片
- 获得视频MP4文件
- 拿到h264(视频压缩文件) -
- 将视频解码(解压),还原成一帧一帧的图片
- 针对每一帧的图片进行处理