解析顶点着色器和片元着色器
转载 https://www.jianshu.com/p/a771639ffbbb
管线
也称渲染管线,因为 OpenGL ES在渲染处理过程中会顺序执行一系列操作,这一系列相关的处理阶段就被称为OpenGL ES 渲染管线。OpenGL ES 渲染过程就如流水线作业一样,这样的实现极大地提高了渲染的效率。如图就是 OpenGL ES 的管线图,学习OpenGL ES 就是学习这张图中的每一个部分。
图中阴影部分的 Vertex Shader(顶点着色器) 和 Fragment Shader(片元着色器) 是可编程管线 。可编程管线就是说这个操作可以动态编程而不必写死在代码中。可动态编程实现这一功能一般都是脚本提供的,在OpenGL ES 中也一样,编写这样脚本的能力是由着色语言GLSL提供的。那可编程管线有什么好处呢?方便我们动态修改渲染过程,而无需重写编译代码,当然也和很多脚本语言一样,调试起来不太方便。
Vertex Shader(顶点着色器)
-
如图,顶点着色器分为输入和输出两部分,负责的功能是把输入的数据进行矩阵变换位置,计算光照公式生成逐顶点颜⾊,⽣成/变换纹理坐标.并且把位置和纹理坐标这样的参数发送到片段着色器.
-
输入参数介绍:
1.着色器程序(Shader Program,图中没有画出):由 main 申明的一段程序源码或可执行文件,描述在顶点上执行的操作:如坐标变换、计算光照公式产生每个顶点颜色、计算纹理坐标。2.属性(Attribute):由 vertext array 提供的顶点数据,如空间位置,法向量,纹理坐标以及顶点颜色,属性可以理解为针对每一个顶点的输入数据。属性只在顶点着色器中才有,片元着色器中没有属性。
3.统一值(Uniforms): Uniforms保存由应用程序传递给着色器的只读常量数据。在顶点着色器中,这些数据通常是变换矩阵,光照参数,颜色等。由 uniform 修饰符修饰的变量属于全局变量,该全局性对顶点着色器与片元着色器均可见,也就是说,这两个着色器如果被连接到同一个应用程序中,它们共享同一份 uniform 全局变量集。因此如果在这两个着色器中都声明了同名的 uniform 变量,要保证这对同名变量完全相同:同名+同类型,因为它们实际是同一个变量。
4.采样器(Samplers): 一种特殊的 uniform,用于呈现纹理。sampler 可用于顶点着色器和片元着色器。
-
输出参数介绍:
1.可变变量(Varying):varying 变量用于存储顶点着色器的输出数据,也存储片元着色器的输入数据。varying 变量会在光栅化处理阶段被线性插值。顶点着色器如果声明了 varying 变量,它必须被传递到片元着色器中才能进一步传递到下一阶段,因此顶点着色器中声明的 varying 变量都应在片元着色器中重新声明为同名同类型的 varying 变量。
-
gl_Position:在顶点着色器阶段至少应输出位置信息-即内建变量
-
gl_FrontFacing:为back-face culling stage阶段生成的变量,无论精选是否被禁用,该变量都会生成。
-
gl_PointSize:点大小。
-
示例代码
// 位置属性
attribute vec4 position;
// 坐标属性
attribute vec2 textCoordinate;
// 旋转角度
uniform mat4 rotateMatrix;
// 输出变量
varying lowp vec2 varyTextCoord;
// 着色器程序(Shader Program)
void main()
{
// 赋值坐标属性到输出变量
varyTextCoord = textCoordinate;
// 位置乘以旋转矩阵
vec4 vPos = position;
vPos = vPos * rotateMatrix;
// 赋值位置到内建变量gl_Position上,作为输出信息(必须)
gl_Position = vPos;
}
Fragment Shader(片元着色器)
片元着色器的作用是处理由光栅化阶段生成的每个片元,最终计算出每个像素的最终颜色。归根结底,实际上就是数据的集合。这个数据集合包含每一个像素的各个颜色分量和像素透明度的值。
-
输入参数介绍:
1.着色器程序(Shader program): 由 main 申明的一段程序源码,描述在片元上执行的操作。2.可变变量(Varyings): 顶点着色器阶段输出的 varying 变量在光栅化阶段被线性插值计算之后输出到片元着色器中作为它的输入,即上图中的 gl_FragCoord,gl_FrontFacing 和 gl_PointCoord。
3.统一值(Uniforms): 用于片元着色器的常量,如雾化参数,纹理参数等。
4.采样器(Samples): 一种特殊的 uniform,用于呈现纹理。
-
输出参数介绍:
1.gl_FragColor: 在顶点着色器阶段只有唯一的 varying 输出变量-即内建变量gl_FragColor。 -
示例代码
// 纹理坐标
varying lowp vec2 varyTextCoord;
// 采样器
uniform sampler2D colorMp;
// 着色器程序(Shader program)
void main()
{
// 读取纹素(纹理的颜色)放到输出变量gl_FragColor上
gl_FragColor = texture2D(colorMap,varyTextCoord);
}