Uniform 是在着色器程序运行期间保持不变的全局变量(由CPU设置),用于从应用程序向着色器(Vertex/Fragment等)传递数据。
- 它是 只读变量(在 shader 中不能修改)
- 生命周期为 一次绘制调用(Draw Call)
- 所有顶点/片段共享同一个
uniform值
Uniform
GLSL中声明
layout (location = 0) uniform mat4 uProjectionMatrix;
layout (location = 1) uniform vec3 uLightPosition;
layout (location = 2) uniform float uBrightness;获取位置
手动获取
若Uniform在声明时,显示声明了layout (location=x),那么location值便是该Uniform的位置。
根据Uniform名获取
GLint glGetUniformLocation(GLuint program, const GLchar *name);- 参数:
program—— Shader Program IDname—— 要查询的Uniform名(大小写敏感)
- 返回值:对应Uniform的位置。
- 若返回
-1,表示Uniform不存在 或 未被使用 示例:
- 若返回
// 获取Uniform位置(在渲染循环外获取更高效)
GLint projLoc = glGetUniformLocation(shaderProgram, "uProjectionMatrix"); // 返回 0
GLint lightLoc = glGetUniformLocation(shaderProgram, "uLightPosition"); // 返回 1
GLint brightLoc = glGetUniformLocation(shaderProgram, "uBrightness"); // 返回 2
注意事项
glGetUniformLocation实际上只依赖于 ShaderProgram 参数,可以不需要glUseProgram- 避免在渲染循环中频繁查询uniform位置,应在初始化阶段完成
- 若uniform未被着色器使用,可能被编译器优化移除,此时
glGetUniformLocation返回-1
传递数据
值传递
void glUniformXX (GLint location, ...)- 参数:
location—— Uniform的位置...—— 传入数据
- 无返回值
指针传递(Uniform数组)
void glUniformXXV (
GLint location,
GLsizei count,
const GLfloat *value
)- 参数:
count—— 数组长度value—— 数组指针
- 无返回值
矩阵传递
void glUniformMatrixXXV (
GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value
)- 参数:
transpose—— 指定在将矩阵值加载到统一变量时是否进行转置
- 无返回值
示例
glUseProgram(shaderProgram); // 先激活着色器程序
// 传递矩阵(4x4)
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
// 传递3维向量
glUniform3f(lightLoc, 1.0f, 2.0f, 3.0f);
// 传递浮点数
glUniform1f(brightLoc, 0.8f);
常见数据类型和上传函数
| GLSL 类型 | 对应 OpenGL 上传函数 |
|---|---|
float |
glUniform1f |
vec2 |
glUniform2f / glUniform2fv |
vec3 |
glUniform3f / glUniform3fv |
vec4 |
glUniform4f / glUniform4fv |
int |
glUniform1i |
sampler2D |
glUniform1i(传入纹理单元编号) |
mat4 |
glUniformMatrix4fv |