目录
典型着色器结构
数据类型
顶点着色器特性
片段着色器特性
从顶点着色器向片段着色器发送数据
从CPU中的应用向GPU中的着色器发送数据
GLSL规范:https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.1.20.pdf
GLSL是类C语言
着色器是各自独立的小程序,但是最终各个着色器是要link到一起构成一个整体程序的
典型着色器结构
- 开头总是版本声明
- 使用in关键字定义输入变量
- 定义out关键字定义输出变量
- 定义uniform
- main函数
#version version_number
in type in_variable_name;
in type in_variable_name;out type out_variable_name;uniform type uniform_name;int main()
{// 处理输入并进行一些图形操作...// 输出处理过的结果到输出变量out_variable_name = weird_stuff_we_processed;
}
数据类型
GLSL中包含了C的基本数据类型int float double uint bool,还包含了两个容器类型向量(Vector)和矩阵(Matrix),由于向量可以是一维的,所以直接使用向量和矩阵两个数据类型即可。

顶点着色器特性
顶点着色器的每个输入变量叫做顶点属性。
能声明的顶点属性是有限制的,一般由硬件来决定。
OpenGL确保至少有16个包含4分量的顶点属性可用。
顶点着色器的输入是从顶点数据中直接接收数据,即从VBO中直接接收数据,
下面代码定义的顶点数据vertices[]将会通过VBO,传输给顶点着色器的输入vec3 posVertex
static const float vertices[] ={-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,-0.5f, 0.5f, 0.0f
};
glGenBuffers(1,&VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3* sizeof (float),(void*)0);
glEnableVertexAttribArray(0);//顶点着色器程序
#version 330
layout(location = 0) in vec3 posVertex;
void main()
{gl_Position = vec4(posVertex, 1.0f);
}
片段着色器特性
片段着色器必须要定义一个vec4的输出,因为片段着色器需要生成一个最终输出的颜色。如果在片段着色器中定义输出颜色,OpenGL会把物体渲染为黑色或者白色。
从顶点着色器向片段着色器发送数据
- 在顶点着色器中定义一个类型的变量
- 在片段着色器中定义一个同类型和名字的变量
在link着色器的时候,当类型和名字都一样的时候,OpenGL就会把两个变量链接到一起
//顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos; // 位置变量的属性位置值为0out vec4 vertexColor; // 为片段着色器指定一个颜色输出void main()
{gl_Position = vec4(aPos, 1.0); // 注意我们如何把一个vec3作为vec4的构造器的参数vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // 把输出变量设置为暗红色
}/*************************************************************///片段着色器
#version 330 core
out vec4 FragColor;in vec4 vertexColor; // 从顶点着色器传来的输入变量(名称相同、类型相同)void main()
{FragColor = vertexColor;
}
从CPU中的应用向GPU中的着色器发送数据
OpenGL通过将着色器中变量定义前加入uniform关键字,来声明改变量中的数据可以从CUP传入。
uniform特性:
- uniform是全局的。
- uniform定义的变量必须在每个着色器对象中是独一无二的。
- uniform可以被任意着色器在任意位置访问。
uniform的使用:
在一个着色器中添加uniform关键字至类型和变量名前来声明一个GLSL的uniform
#version 330 core
out vec4 FragColor;//1.在OpenGL程序代码中设定这个变量
uniform vec4 ourColor; void main()
{FragColor = ourColor;
}
/******************************************************************/float greenValue = (sin(timeValue) / 2.0f) + 0.5f;
//2.获取uniform "ourColor"的位置
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
//3.更新ourColor前必须调用glUseProgram
glUseProgram(shaderProgram);
//4.通过glUniform4f更新GPU中的数据
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);















