In WebGL, what is the difference between attributes and uniforms?

Tests per-vertex versus per-draw-call data flow. Attributes vary per vertex from buffers; uniforms are constant per draw call. Cite vertex positions as attributes and an MVP matrix as uniform.
WHAT THIS TESTS: This question tests whether you understand the WebGL rendering pipeline at the data-flow level, specifically how vertex shaders receive inputs and the critical distinction between data that changes per vertex and data that changes per draw call. Interviewers want to see that you know attributes require buffer setup, enableVertexAttribArray, and vertexAttribPointer, while uniforms are set directly with gl.uniform calls. They also want to know you can reason about performance and API usage in concrete terms.
A GOOD ANSWER COVERS: First, define an attribute as a shader input that is pulled from a bound buffer and consumed once per vertex, meaning a 1000-vertex triangle list triggers 1000 distinct attribute fetches. Second, define a uniform as a shader global that is constant for every vertex and fragment during a single draw call, set via gl.uniform4fv or similar after looking up its location with getUniformLocation. Third, explain the practical setup difference: attributes need gl.createBuffer, gl.bufferData, gl.enableVertexAttribArray, and gl.vertexAttribPointer to describe stride and offset, whereas uniforms need no buffer and are set immediately before gl.drawArrays or gl.drawElements. Fourth, give a concrete pair of examples.
COMMON WRONG ANSWERS: A major red flag is saying attributes and uniforms are just two ways to pass data into shaders without explaining the frequency of change or the buffer machinery. Another mistake is claiming uniforms can vary per vertex; they cannot. Some candidates also confuse vertex shader outputs varying with fragment shader inputs, or suggest uniforms are faster for everything without acknowledging that per-vertex data belongs in buffers. Failing to mention that uniforms are scoped to the current program set by gl.useProgram is another subtle gap.
LIKELY FOLLOW-UPS: The interviewer may ask how you would animate a mesh, leading to a discussion of updating buffer data with gl.bufferSubData versus passing time as a uniform. They might ask about instanced rendering and how gl.vertexAttribDivisor changes the attribute frequency. Another follow-up is how to handle per-vertex colors versus a single object color, or the difference between uniforms and textures for large constant data.
ONE CONCRETE EXAMPLE: When rendering a rotating 3D crate, you would store the crate's eight corner positions in a Float32Array, upload it to a gl.ARRAY_BUFFER, and bind it to an attribute named a_position with three components per vertex. This lets each vertex start at a different point in model space. You would compute the combined model-view-projection matrix on the CPU each frame and upload it to a uniform named u_mvpMatrix using gl.uniformMatrix4fv. Every vertex shader invocation reads a different a_position but the same u_mvpMatrix, transforming the whole crate consistently. If you wanted each face to have a different tint, you might add a vec3 a_color attribute, but if the entire crate shares one material, you would use a vec3 u_color uniform instead.
Source: webglfundamentals.org
Read the original → webglfundamentals.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.