1 数据存储限制符

GLSL的基本数据类型和聚合数据类型可以通过数据存储修饰符改变自己的行为。
主要的存储限制符如下:

类型修饰符 描述
const 将一个变量定义为只读形式,如果它初始化时用的是一个编译时常量,那么它本身也会成为编译时常量
in 设置变量为着色器阶段的输入变量
out 设置变量为着色器阶段的输出变量
uniform 设置变量为用户应用程序传递给着色器的数据,对于给定的图元是一个常量数值
buffer 设置应用程序共享的一块可读写的内存,这块内存也可以作为着色器的存储缓存使用
shared 设置变量是本地工作组中共享的,只能用于计算着色器中

其中in、out和uniform是经常使用的,下面将详细介绍各个存储限制符。

2 const存储限制符

GLSL中的const与C语言的作用相同,主要是设置变量为只读。
例如:

const float value = 1.0;

对value变量加了const修饰之后,则不允许修改变量的值,只能作为常量使用。

3 in存储限制符

in用于定义着色器的输入变量。

  • 对于顶点着色器,用in修饰的变量一般为顶点属性。
  • 对于片段着色器,用in修饰的变量为顶点着色器的输出变量,即顶点着色器的out修饰的变量。

4 out存储限制符

out用于定义着色器的输出变量。

  • 对于顶点着色器中,out经常用于顶点着色器输出的坐标变换之后的顶点齐次坐标;
  • 对于片段着色器,out经常用于输出图元的最终颜色。

5 uniform存储限制符

5.1 uniform存储限制符

在shader运行之前,uniform变量可以在应用程序中进行指定,该变量不会在图片处理过程中发生变化。uniform变量在所有可用的着色阶段之间都是共享的,是全局变量。

任何类型包括基本数据类型和聚合类型、结构体和数组都可以设置为uniform变量。

在shader运行的过程中,不能修改uniform变量的值。

比如说,我们在片段着色器中声明一个uniform变量用于设置图元的最终颜色值,那么在shader中进行以下声明:

#version 330 core

uniform vec4 FinalColor;

out vec4 FragColor;

void main()
{
    FragColor = FinalColor;
}

5.2 如何在应用程序中设置uniform变量

那么该如何在应用程序设置uniform变量FinalColor的值呢?

GLSL编译器在链接着色器程序时创建一个uniform变量列表,如果我们要在应用程序中设置FinalColor的值,则首先需要获得FinalColor变量在uniform变量列表中的索引值,而这个索引值可以通过glGetUniformLocation()函数获取。

在获得FinalColor在uniform变量列表中的索引值之后,可以通过glUniform()或者glUniformMatrix()系列函数设置相关的uniform的值,这样就完成了在应用程序中设置uniform的值,而这个值可以传进shader中被使用。

设置的FinalColor的过程如下:

GLint index = glGetUniformLocation(shaderProgram,"FinalColor");
vec4 color = vec4(1.0,0.0,0.0,1.0);
glUniform4fv(index,color);

6 buffer存储限制符

buffer修饰符指定随后块作为着色器与应用程序共享的一块内存缓存,这块内存缓存对于着色器是可读也是可写的,缓存块的大小可以在着色器编译和程序链接完成后设置。

如果需要在应用程序中共享一大块缓存给着色器,最好的就是使用buffer变量。buffer变量与uniform变量比较类似,但是不同的是可以在着色器中对buffer进行修改。

7 shared存储限制符

shared只能用于计算着色器中,用于建立本地工作组内共享的内存,使用的频率较低。