上一篇博客 iOS — OpenGLES之初步认识 中主要介绍了OpenGLES在iOS中的简单使用,包括创建EAGLContext,设置CAEAGLLayer属性,使用renderbuffer和framebuffer等。这一次,我们将主要学习OpenGLES的着色器shader的基本语法。
关于OpenGLES渲染管线,请参考博客 [OpenGL ES 02]OpenGL ES渲染管线与着色器。着色器是可编程管线中的术语,其语法类似C语言,分为顶点着色器(Vertex Shader)和片元着色器(Fragment Shader)。
Vertex shader – 在你的场景中,每个顶点都需要调用的程序,称为“顶点着色器”。假如你在渲染一个简单的场景:一个长方形,每个角只有一个顶点。于是vertex shader 会被调用四次。它负责执行:诸如灯光、几何变换等等的计算。得出最终的顶点位置后,为下面的片段着色器提供必须的数据。
vertex shader可通过可编程的方式实现对顶点的操作,如坐标空间转换,颜色及纹理坐标。最简单的Vertex shader如下:
attribute vec4 Position;
void main(Void) {
gl_Position = Position; // must set gl_Position for vertex shader
}
Fragment shader – 在你的场景中,大概每个像素都会调用的程序,称为“片段着色器”。在一个简单的场景,也是刚刚说到的长方形。这个长方形所覆盖到的每一个像素,都会调用一次fragment shader。片段着色器的责任是计算灯光,以及更重要的是计算出每个像素的最终颜色
Fragment是可以被渲染到屏幕上的像素点,fragment shader即用于计算每个像素的颜色等属性。最简单的Fragment shader如下
precision mediump float;
void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // must set gl_FragColor for fragment shader
}
上边的vertex shader仅接收顶点的位置信息,因此像素颜色都是在fragment shader中写固定的(红色)。而在下边的vertex shader中,通过SourceColor传递像素颜色。
attribute vec4 Position; // position of vertex
attribute vec4 SourceColor; // color of vertex
varying vec4 DestinationColor; // will pass out to fragment shader
void main(void) {
DestinationColor = SourceColor;
gl_Position = Position;
}
对应的fragment shader为:
varying lowp vec4 DestinationColor;
void main(void) {
gl_FragColor = DestinationColor;
}
这里,fragment shader接收来自vertex shader的变量DestinationColor,赋值给gl_FragColor,再输出至OpenGLES。即每个像素的颜色由DestinationColor决定,这样可在代码中精确控制每个像素的颜色。
本文的一系列demo都可在github中找到,DemoOpenGL,如有不准确的地方,欢迎指正。
OpenGL Tutorial for iOS: OpenGL ES 2.0
OpenGL ES渲染管线与着色器