Learn more about Russian war crimes in Ukraine.

Why is my WebGL texture upside-down?

To get a texture into your WebGL program, you use texImage2D, and since you’re on the web, you’ll probably use an <img> element or similar as the source for the texture. If you do, you’ll be in for a confusing surprise when you render the texture: it’s upside-down! The Y-axis is flipped! Here’s why, and how to fix it. But if you’re just here for the solution, you want:

gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

The WebGL texImage2D function is a thin wrapper over the underlying glTexImage2D C function. This C function does not take an HTMLImageElement source; it just takes a const void * data. It expects the pixels in that array to be stored in bottom-to-top order:

The first element corresponds to the lower left corner of the texture image. Subsequent elements progress left-to-right through the remaining texels in the lowest row of the texture image, and then in successively higher rows of the texture image. The final element corresponds to the upper right corner of the texture image.

Despite this, the spec for the WebGL texImage2D function says:

The first pixel transferred from the source to the WebGL implementation corresponds to the upper left corner of the source.

So, the browser copies pixels from the <img> in top-to-bottom order, even though OpenGL expects them in bottom-to-top order! I can think of no reason for this perverse behavior except that it’s a mistake in the design of WebGL.

Happily, the spec basically admits that it’s a mistake, and provides a way to fix this behavior:

This behavior is modified by the UNPACK_FLIP_Y_WEBGL pixel storage parameter, except for ImageBitmap arguments, as described in the abovementioned section.

So, it’s highly likely that you want this for every program you write:

const gl = displayCanvasEl.getContext("webgl");
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

Strangely, you won’t find this advice on MDN or elsewhere.

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