OpenGL ES系列三--GLSL着色器语言

GLSL语言–OpenGL Shading Language

无论是OpenGL还是其他图形API的着色器,通常都是通过一种特殊的编程语言去编写的。对于OpenGL来说,我们会使用GLSL,它是在OpenGL2.0版本左右发布的,GLSL与“C”语言非常类似,当然还有一点C++的影子。因为从下一节基本图元的绘制开始,我们就会开始接触到GLSL,所以必须先介绍GLSL。我们主要从以下几个常用的方面介绍:
1. 注释

类型 符号
单行注释 //
多行注释 /* 内容 */

2.基本数据类型

GLSL是一种强类型语言,所有变量都必须事先声明,并要给出变量的类型(如下表)。变量名的命名规范与C语言相同:可以使用字母、数字、以及下划线字符,但是数字不能作为变量名称的第一个字符,此外也不能包含连续的下划线。

类型 符号
float 32位浮点数
double 64位浮点数(使用double时要看是否支持,不支持要看起扩展)
int 有符号二进制补码的32位整数
uint 无符号的32位整数
bool 布尔值

3. 聚合类型

GLSL的基本类型可以合并,从而与OpenGL的数据类型相匹配。GLSL支持2个、3个以及4个分量的向量,每个分量都可以使用bool、int、uint、float、double这些基本变量,此外GLSL也支持float和double类型的矩阵。具体如下表:

基本类型 2D向量 3D向量 4D向量 矩阵类型 非方阵矩阵
float vec2 vec3 vec4 mat2 mat3 mat4 mat2x2 mat2x3 mat4x2…
double dvec2 dvec3 dvec4 dmat2 dmat3 dmat4 dmat2x2 dmat2x3 dmat4x2…
int ivec2 ivec3 ivec4
uint uvec2 uvec3 vec4
bool bvec2 bvec3 bvec4

在上面的非方阵矩阵中给出了两个维度的信息,例如mat4x3,其中第一个值表示列数,第二个值表示行数。

在访问向量时可以通过以下几种方式,我们以常用的vec4为例:

分量访问符 符号描述
(x、y、z、w) 与位置相关的分量
(r、g、b、a) 与颜色相关的分量
(s、t、p、q) 与纹理相关的分量
   //定义一个颜色向量(需要注意的是不能混合使用分量访问符)
   vec4 color = vec4(1.0f,1.0f,1.0f,1.0f);
   float red = color.r;
   float green = color.g;
   color.b = 0.2f;
   //错误示范
   vec2 temp = color.ry;
   ...
//矩阵访问
mat4 m = mat4(2.0);
//获取矩阵的第二列(从0开始)
vec4 zVec = m[2];
float yScale = m[1][1];

​4. 结构体

结构体和C语言的用法类似,我们就简单的写一个示例来说明:

   struct Demo{
        float lifeTime;
        vec3 position;
   };

   vec3 pos = vec3(1.0);
   Demo d = Demo(10.0,pos);

这个目前我用的不是很多,如果后面用的多的话,会更新这些文章的。所以这里就简单说明一下。
5. 数组

GLSL支持任意类型的数组,包括结构体数组。这个和C语言也是差不多的,下面写一个示例:

   //有3个float元素的数组
   float coeff[3];
   float[3] coeff;
   //未定义维数,后面可以重新声明它的维数
   int indices[];

6.存储限制符
通过存储限制符可以改变数据类型的行为。GLSL中一共定义了以下几种全局范围内的修饰符,如下表:

类型修饰符 描述
const 将一个变量定义为只读形式 ,必须在声明时初始化
in 设置变量为着色器阶段的输入变量
out 设置变量为着色器阶段的输出变量
inout 设置变量同时作为输入、输出变量
uniform 设置变量为应用程序传递给着色器的数据
buffer 指定后面所修饰的块作为着色器与应用程序共享的一块内存缓存。这块缓存对于着色器来说是可读、可写的
shared 设置变量是本地工作组中共享,它只能用于计算着色器中
attribute 表示只读的顶点数据,只用在顶点着色器中 可以是浮点数类型的标量,向量,或者矩阵
varying 作为顶点和片元中的共享参数,注意参数名必须相同

以上这些限制符在后面的文章所搭配的Demo中只要有用到都会有详细说明。

7.语句
语句这里蛮多的,主要说明一些我们常用的:

  • 算术运算符
操作符 描述
() 用于表达式组合,函数调用,构造
[] 数组下标,向量或矩阵的选择器
. 结构体和向量的成员选择
++ – 前缀或后缀的自增自减操作符
    – !
一元操作符,表示正 负 逻辑非
    /
乘 除操作符
    -
二元操作符 表示加 减操作
<> <= >= == != 小于,大于,小于等于, 大于等于,等于,不等于 判断符
&& || ^^ 逻辑与 ,或, 异或
?: 条件判断符
= += –= *= /= 赋值操作符
, 表示序列
  • 循环语句
   for(int i = 0; i < 10;i++){}

   while(n<10){}

   do{
     ...
   }while(n<10);
  • 流控制语句
语句 描述
break 跳出当前所以的最近一层的循环
continue 终止本次循环,继续下一次循环
return 结束当前函数,可携带返回值
discard 丢弃当前的片元,终止着色器的执行。discard只在片元着色器中生效
  • 函数

    GLSL中的函数和C也是差不多的,如下,我们就不在多说了。

   void test(float a){

   }

到这里在OpenGL ES中常用的GLSL着色器语言就差不多了。下面我们给出了两个示例着色器代码。

顶点着色器

//从变换矩阵
uniform mat4 uMVPMatrix;
//顶点数据
attribute vec3 aPosition;
//颜色
attribute vec4 aColor;
//传递给片元着色器的颜色
varying vec4 vColor;

/*
 * 程序入口
 */
void main() {
    gl_Position = uMVPMatrix*vec4(aPosition,1);
    vColor = aColor;
}

片元着色器

precision mediump float;
//接收从顶点着色器过来的参数
varying vec4 vColor;

void main() {
    //给片元设置颜色值
    gl_FragColor = vColor;
}

你可能感兴趣的:(OpenGL-ES)