Uniforms, Uniform Blocks & Host Communication
Unused uniforms are optimized away (location = -1) — not an error.
15.1 Plain uniforms
Unused uniforms are optimized away (location = -1) — not an error.
uniform float uTime;
uniform vec2 uResolution;
uniform vec3 uLightPos;
uniform mat4 uMVP;
uniform sampler2D uTexture;
uniform Light uLight; // structs: set each member: "uLight.position"
uniform vec3 uColors[4]; // arrays: "uColors[0]" ...glUseProgram(prog);
GLint loc = glGetUniformLocation(prog, "uTime"); // cache locations after linking
glUniform1f(loc, (float)glfwGetTime());
glUniform3f(glGetUniformLocation(prog, "uLightPos"), 1.0f, 4.0f, 2.0f);
glUniformMatrix4fv(glGetUniformLocation(prog, "uMVP"), 1, GL_FALSE, glm::value_ptr(mvp));
glUniform1i(glGetUniformLocation(prog, "uTexture"), 0); // sampler → texture unit 0
glProgramUniform1f(prog, loc, t); // DSA: no glUseProgram needed (4.1+)15.2 Uniform Buffer Objects (UBOs)
Share uniforms across programs and update them efficiently:
layout (std140, binding = 0) uniform CameraBlock {
mat4 view;
mat4 projection;
vec4 cameraPos; // use vec4 instead of vec3 to avoid padding surprises
float time;
};GLuint ubo; glGenBuffers(1, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, sizeof(CameraData), nullptr, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo); // binding point 0
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(CameraData), &camData); // update per frame
// Pre-4.20: glUniformBlockBinding(prog, glGetUniformBlockIndex(prog, "CameraBlock"), 0);15.3 std140 vs std430 layout rules
float, int, uint, bool vec3, vec4 16 (vec3 occupies 12, next scalar can pack after it) array element (scalar/vec2) 16 (rounded up to vec4) 4 × vec4 columns (16 each) rounded up to 16 largest member alignment
Rule of thumb: avoid vec3 in buffers (use vec4), avoid scalar arrays in std140 (pack into vec4 arrays), and mirror the layout with aligned C structs (alignas(16)). std430 (SSBOs, and UBOs with GL_EXT_scalar_block_layout in Vulkan) is tighter.
layout (std140) uniform Example {
float a; // offset 0
vec3 b; // offset 16 (aligned to 16)
float c; // offset 28 (fits after vec3's 12 bytes)
float arr[3]; // offset 32, stride 16 each! → 48 bytes total
mat4 m; // offset 80
};15.4 Other ways to feed data
Vertex attributes (per-vertex/per-instance data).
Textures / buffer textures (samplerBuffer) for large read-only arrays.
SSBOs (§27) for large read/write data.
Push constants (Vulkan, §32) for small, frequently changing data.
Specialization constants (Vulkan) / #define injection for compile-time options.