Learn more about Russian war crimes in Ukraine.

WebGL canvas size vs. CSS size vs. viewport vs. clipspace vs. world space

There are lots of different widths and heights in WebGL! This post tries to clarify the pipeline which transforms your world coordinates into physical pixels. Start with a canvas:

<canvas id="foo" width="150" height="100"></canvas>

The width and height attributes on the <canvas> element specify how many canvas pixels you have to play with. This canvas is a widthxheight array of logical pixels (RGBA points). You use a 2D context or a WebGL context to draw to the canvas:

const fooEl = document.getElementById("foo");
const gl = fooEl.getContext("webgl");

Your context ultimately edits a that array of RGBA points. These are not physical pixels! You get a bit closer to physical pixels by controlling the canvas’s CSS:

canvas#foo { width: 300px; height: 200px; }

The CSS width and height specify how that canvas pixel array will be displayed. The units above are CSS pixels, which still are not physical pixels. The CSS sizes default to the same as the width and height attributes. (This may be undesirable: high-DPI screens can have four physical pixels per CSS pixel, making your canvas blurry. To deal with these screens, you can set the CSS sizes to double the canvas sizes.)

In WebGL, you draw to the canvas using shaders. Your vertex shader does not use canvas space or CSS space; it uses yet another space: “clip space”. Clip space is a square between (-1,-1) and (1,1). That is, the clip space square is two units wide and centered on the origin. (Okay, you could say clip space is a cube. Ignore that for now.)

Drawing in clip space is transformed to the canvas pixel array by a “viewport”. The viewport defaults to stretching the two-unit square to the full width and height of the canvas pixel array. A new viewport can be set with gl.viewport(x,y,width,height). (You’ll want to do this if you change the canvas array size.)

In summary, to draw to the screen in WebGL, there’s a very long line of transformations:

vertex attributes --[vertex shader]--> clip space --[viewport]--> canvas space --[CSS]--> HTML frame space --[browser, OS, hardware]--> physical pixel space

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 . All content copyright James Fisher 2017. This post is not associated with my employer. Found an error? Edit this page.