Learn more about Russian war crimes in Ukraine.

GLSL varying variables

Above you see a square where each corner has a color and the rest of the square gets its color by interpolating between these corners. The square is drawn using WebGL. There is one draw call, with four vertices: the four corners. Each vertex is assigned a color attribute, and WebGL interpolates between these colors using a varying variable.

// Vertex shader
attribute vec2 a_coord;
attribute vec4 a_color;
varying vec4 v_color;
void main(void) {
  gl_Position = vec4(a_coord, 0.0, 1.0);
  v_color = a_color;
}
// Fragment shader
precision mediump float;
varying vec4 v_color;
void main(void) {
  gl_FragColor = v_color;
}

Notice the declaration of varying vec4 v_color in both shaders. Each call to the vertex shader can assign to v_color. This passes information to the fragment shader. In each call to the fragment shader, the value of v_color comes from prior vertex shader calls. The precise value for a fragment is an interpolation of the value from nearby vertices.

To pass in the initial color, I use another attribute in the vertex shader, a_color. Here’s how we pass in the two attributes, a_coord and a_color:

const coordLoc = gl.getAttribLocation(prog, "a_coord");
const colorLoc = gl.getAttribLocation(prog, "a_color");

const vertexBuf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
  -1,1,  -1,-1,  1,-1,  1, 1,
]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(coordLoc);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuf);
gl.vertexAttribPointer(coordLoc, 2, gl.FLOAT, false, 0, 0);

const colorBuf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
  1,0,0,1, 0,1,0,1, 0,0,1,1, 1,1,0,1,
]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(colorLoc);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuf);
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);

It’s not clear to me exactly what the interpolation algorithm is. It seems to be linear.

Notice that OpenGL has no hardcoded concepts of “vertex color” or “interpolating colors”. Instead, OpenGL has hardcoded “vertex attributes” and “interpolated attributes” (varyings). We can use varying for more things than color, e.g. normals.

What can computers do? What are the limits of mathematics? And just how busy can a busy beaver be? This year, I’m writing Busy Beavers, a unique interactive book on computability theory. You and I will take a practical and modern approach to answering these questions — or at least learning why some questions are unanswerable!

It’s only $19, and you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

After months of secret toil, I and Andrew Carr released Everyday Data Science, a unique interactive online course! You’ll make the perfect glass of lemonade using Thompson sampling. You’ll lose weight with differential equations. And you might just qualify for the Olympics with a bit of statistics!

It’s $29, but you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

More by Jim

Tagged #programming, #graphics, #webgl. All content copyright James Fisher 2017. This post is not associated with my employer. Found an error? Edit this page.