Opengl ES 着色器介绍
Posted xiaomazixun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Opengl ES 着色器介绍相关的知识,希望对你有一定的参考价值。
Opengl ES基础系列文章是音视频学习的图形图像部分,旨在通过这部分学习,能够把Opengl ES和视频结合在一起,最终形成一个完整的知识体系。
着色器的写法类似C语言,可以定义变量、常量以及函数,有main方法,在Opengl ES渲染过程中,会不断调用其main方法来进行计算,我们不去大篇幅讨论着色器语法、API等,会通过实际的例子让大家真正知道着色器中变量的含义、以及对变量进行定位和其赋值等。
1. 术语
VertexShader:顶点着色器;
FragmentShader:片段着色器;
2. 着色器写法
下面是一个简单的顶点着色器和片段着色器的代码:
-
顶点着色器代码
attribute vec4 aVertexCoor; // 1
varying vec4 vTextrueCoor;
void main(void)
{
gl_Position = aVertexCoor;
}
gl_Position:Opengl ES的全局变量,这里表示当前计算的顶点坐标位置。
aVertexCoor:定义一个attribute类型的变量,用来存储顶点坐标值,实际使用中会把值赋给它;
-
片元着色器代码
uniform vec4 uColor; //
varying vec4 vTextrueCoor;
void main(void)
{
gl_FragColor = uColor;
}
gl_FragColor:经过计算后得到对片元(通过顶点着色器计算的区域)填充的颜色信息。
uColor:图形的填充颜色,实际中会设置需要填充的颜色值。
3. 着色器编译
前面章节介绍过,在Opengl ES中,在顶点着色器和片段着色器里定义完全相同的uniform和varying类型的变量,那么它们其实共享一个内存地址,相当于同一个变量。所以,在顶点代码里定义的vTextrueCoor,片段着色器里也同样定义了,因此,我们给顶点着色器的vTextrueCoor赋值,片段着色器里通过vTextrueCoor变量访问的也是同样的值,这样,纹理坐标的值通过顶点着色器透传给了片段着色器(这个纹理坐标绘制三角形暂时不用,后面使用图像纹理时会详细讲解)。
顶点着色器和片段着色器代码写好后,还不能用,需要通过Opengl ES进行编译、链接后才能使用。
-
着色器编译流程
-
着色器的链接过程
-
使用着色器
glUseProgram();
调用此函数切换到和program链接的顶点着色器和片段着色器,使用我们编写的着色器代码。
4. 着色器在Opengl ES管线中调用
在Opengl ES渲染管线流水线中,顶点着色器和片元着色器我们是可以编程定制的,下面看下在渲染过程中对顶点着色器和片元着色器的调用过程。
-
顶点着色器
-
片段着色器
5. 再谈顶点坐标和纹理坐标
-
顶点坐标
上节简单讲解了顶点坐标,其原点在中心点,归一化坐标在[-1, 1]之间,下面我们以绘制矩形来对顶点坐标做个直观了解。
上面四个图简要说明了绘制一个矩形其四个顶点其中的四种顶点坐标顺序,我们知道,在Opengl ES仅支持点、线、三角形绘制(先知道就这么回事),那么矩形可以看成是两个三角形组合而成,下面这句话大家一定要记住:
在Opengl ES,三角形是以连续的三个顶点坐标确定的。
记住上面的连续,三角形是以连续的三个顶点坐标组合而成,所以我们在不指定绘制顺序(order)的情况下,矩形的四个顶点只需要按照顺序组合成两个三角形,而这两个三角形刚好拼装成一个矩形就可以了,这里提一点,绘制顺序是可以指定,后面我们会讲到,我们看下上图的第一个,顶点顺序为:v1、v2、v4、v3,那么我们从四个顶点中,从第一个顶点开始,每三个一组(一个三角形需要三个顶点),取两组(一个矩形需要两个三角形组合),那么唯一的组合就是:(v1,v2,v4)、(v2,v4,v3),那为什么不是(v1,v2,v4)、(v1,v4,v3)呢,那是因为(v1,v4,v3)这个组合的点不是连续的,到这里大家应该明白了吧,其实只要保证两个对角线连续,三角形的三个点连续,那么就可以有多种组合,上面我们列出四种顶点组合,大家可以根据这个原理,列出其它的组合。
为了更直观,我们来看一组不能组合成矩形的顶点顺序。
从上图看到,如果以顶点顺序v1、v2、v3、v4,那么最终得到三角是交叉的,不能组合成矩形。
-
纹理坐标
上节我们说过,纹理坐标原点在左下角,向上为Y正轴,向右为X正轴,这里的纹理坐标实际会映射到我们图像纹理上,实际中我们的图像数据是从左到右,从上到下,其坐标系如下:
这个坐标其实和纹理坐标在垂直方向是一个镜像关系,因此,实际绘制中需要对纹理坐标沿X轴翻转180(垂直镜像),因为在图元装配和光栅化的时候,顶点坐标和纹理坐标会按照顺序一一对应起来,所以,要正确显示图像,那么顶点坐标和纹理坐标一定要对应起来,顶点坐标和图像纹理坐标对应关系如下(垂直做镜像):
上图黄色坐标系为图像纹理的坐标,只要按照上图的对应点进行组合顶点坐标和图像纹理坐标就可以正确绘制出我们的图像了(结合上面顶点坐标的组合然后对应这个图就可以正确的图像纹理坐标和顶点坐标了)。
这一节主要讲解着色器的基本概念、写法,编译和链接过程以及顶点坐标和纹理坐标,关于着色器相关的API调用,我们会在后续章节中实际的项目里进行讲解,那样效果会更好。
本系列文章均为原创,主要总结作者多年在软件行业的一些经验,和大家共同学习、进步,转载请注明出处,谢谢!
以上是关于Opengl ES 着色器介绍的主要内容,如果未能解决你的问题,请参考以下文章
OpenGL ES着色器语言----------------储存修饰符
OpenGL ES - 如何在 Blender Cycles Render 中实现光泽着色器?
在 iOS 上的 OpenGL ES 着色器中混合多个纹理会导致反向行为