您的位置:首页 > 运维架构

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

2018-01-20 12:12 537 查看

GLSL语言–OpenGL Shading Language

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

1. 注释

类型符号
单行注释//
多行注释/* 内容 */
2.基本数据类型

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

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

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

基本类型2D向量3D向量4D向量矩阵类型非方阵矩阵
floatvec2vec3vec4mat2 mat3 mat4mat2x2 mat2x3 mat4x2…
doubledvec2dvec3dvec4dmat2 dmat3 dmat4dmat2x2 dmat2x3 dmat4x2…
intivec2ivec3ivec4
uintuvec2uvec3vec4
boolbvec2bvec3bvec4
在上面的非方阵矩阵中给出了两个维度的信息,例如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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: