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's really being asked
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.
The full answer
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.
The mistakes people make
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.
What usually comes next
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.
A 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.
Interview question
When rendering a mesh in WebGL, why is vertex position data supplied as an attribute while a model-view-projection matrix is supplied as a uniform?
- a.The position buffer is bound with vertexAttribPointer so each vertex reads a distinct value, while the MVP matrix is uploaded once per draw call via gl.uniformMatrix4fv and remains constant for all vertices.Correct
- b.Uniforms vary per vertex when updated inside a loop before each gl.drawArrays call, making them suitable for per-vertex positions without buffer overhead.
- c.Attributes are optimized for infrequently changing data like transforms, whereas uniforms are streamed from buffers to provide unique values for every vertex invocation.
- d.Both inputs use gl.bufferData, but attributes are automatically interpolated across vertices while uniforms are sampled once per primitive by the fragment shader.
Why? this is the answer
Vertex positions must be attributes because they are fetched from a buffer per vertex via vertexAttribPointer, while an MVP matrix is a uniform set once per draw call with gl.uniformMatrix4fv and shared by all vertices. Option B is tempting but wrong because uniforms cannot vary per vertex within a single draw call, and attempting to update them per vertex from JavaScript would require thousands of individual draw calls.
Just read this? Test yourself on what you have been reading.
Read the original → webglfundamentals.org
- #webgl
- #shaders
- #graphics
- #glsl
- #frontend
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles