GLSL-入门

GLSL

OpenGL的着色器使用GLSL语言编写,类C风格。一个着色器由变量声明和main函数组成, 能声明的变量数量是有限的,具体由硬件决定。

顶点着色器样例

1
2
3
4
5
6
7
8
9
10
11
12
13
#version 330 core
// 定义两个属性,通过location指定该属性的索引值
layout(location = 0) in vec4 vPosition;
layout(location = 1) in vec4 aTextureCoord;
// 定义一个全局常量
uniform mat4 uTextureMatrix;
// 输出一个属性给片段着色器
out vec2 yuvTexCoords;
void main() {
// 输出顶点坐标
gl_Position = uTextureMatrix * vPosition;
yuvTexCoords = aTextureCoord;
}

片段着色器样例

1
2
3
4
5
6
7
8
9
#version 330 core
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;
uniform samplerExternalOES yuvTexSampler;
in vec2 yuvTexCoords;
out vec4 fragColor;
void main() {
fragColor = texture(yuvTexSampler,yuvTexCoords);
}

uniform

Uniform是一种从CPU中向GPU中的着色器发送数据的方式,uniform是全局的,在每个着色器对象中都是独一无二的,可以被任意着色器访问;uniform会一直保存数据直到被更新。

通过glGetUniformLocation获取uniform的位置,使用glUniform4f设置uniform的值。

1
2
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

in、out

in关键字表示该变量为着色器的输入,out关键字表示该变量为着色器的输出。借助in、out着色器之间可以发送数据,顶点着色器定义同名的out变量,片段着色器定义同名的in变量就可以接收数据(示例中的yuvTexCoords)。

片段插值(Fragment Interpolation)

光栅化时会根据每个片段在图元上所处的相对位置决定这些片段的位置,基于这些位置,它会插值所有片段着色器的输入变量。

数据类型

GLSL中包含C语言中大部分的基础数据类型: int、float、double、uint、bool。包含两种容器类型Vector、Matrix。

Vector

GLSL中Vector是一个可以包含2、3、4个分量的容器,分量的类型可以是任意的基础数据类型。

  • vecn: 包含n个float分量的向量
  • bvecn: 包含n个bool分量的向量
  • ivecn: 包含n个int分量的向量
  • uvecn: 包含n个uint分量的向量
  • dvecn: 包含n个double分量的向量

向量的分量可以通过vec.x、vec.y、vec.z、vec.w来获取。

内建变量

顶点着色器

  • gl_VertexID: 输入变量,用于保存顶点的整数索引。
  • gl_InstanceID: 输入变量,用于保存实例化绘图调用中图元的实例编号。
  • gl_Position: 输出变量,输出顶点位置的裁剪坐标。该值在裁剪和视口阶段用于执行相应的图元裁剪以及从裁剪坐标到屏幕坐标的顶点位置转换。
  • gl_PointSize: 输出变量,输出点精灵尺寸。
  • gl_FrontFacing: 不能直接写入,根据顶点位置和图元类型生成。
  • gl_DepthRange: 窗口坐标的深度范围。
    该变量类型为struct gl_DepthRangeParameters{
    highp float near;
    highp float far;
    highp float diff;
    }

片段着色器:

  • gl_FragCoord: 只读变量,保存片段的窗口相对坐标。
  • gl_FrontFacing: 只读变量,片段是正面图元的一部分时为true,否则为false。
  • gl_PointCoord: 只读变量,保存点精灵的纹理坐标,该坐标在点光栅化期间自动生成。
  • gl_FragDepth:输出变量,用于覆盖片段的固定功能深度值。
  • gl_FragColor:输出变量,输出该片段的颜色。(该变量在3.0中已删除,需要自行定义)

精度限定符

顶点着色器有默认的精度,是highp,但是片段着色器没有默认的精度。

  • highp
  • mediump
  • lowp

采样器

  • texture2D(sampler2D, vec2 coord):从标准纹理中获取纹理数据。
  • textureCube(samplerCube, vec3 coord:从立方体贴图纹理中获取纹理数据。
    3.0中上面两个函数被合成了一个函数
  • texture(sampler,coord): 内建函数,从纹理贴图中读取,sampler是绑定到纹理单元的采样器,制定纹理为读取来源。coord是从纹理贴图中读取的2d纹理坐标。该函数返回一个代表从纹理贴图中读取颜色的vec4,默认格式为RGBA。