Using CORS to load WebGL textures from cross-domain images

In Firefox, as well as in Chrome, it is now possible to load cross-domain images into WebGL textures, if they have been approved by CORS.

Most prominently, this feature allows for impressive 3D mapping applications such as Google MapsGL and Nokia Maps 3D.

What happened

Earlier this year, the Editor’s Draft WebGL specification got updated in response to a security concern. The additions were:

  1. A mandatory clause disallowing usage of cross-domain elements as WebGL textures in the general case.
  2. A non-normative clause specifically allowing cross-domain elements that have CORS approval. For that occasion, the HTML specification on the <img> element got updated to add a new crossorigin attribute.

The first got implemented in Firefox 5, the second is now in Firefox 8.

How to use this feature

There are two CORS modes: “anonymous” and “use-credentials”. We’ll focus on “anonymous” as it’s the common case. A great example of images served with anonymous CORS is Google Maps imagery, such as:

http://khm0.googleapis.com/kh?v=95&x=0&y=0&z=0

In order to load it with CORS as a WebGL texture, we set the crossOrigin attribute on it:

var earthImage = new Image();
earthImage.crossOrigin = "anonymous";

Now we load it as usual:

    earthImage.onload = function() {
      // whatever you usually to do load WebGL textures
    };
    earthImage.src = "http://khm0.googleapis.com/kh?v=95&x=0&y=0&z=0";

That’s it! Aside from setting the crossOrigin attribute, we didn’t have to do anything. Here is the full self-contained example.

The HTTP headers

If we study the HTTP headers for this image (using, for example, Firefox’s Web Console), we find that the Request Headers contain

Origin: null

which is the effect of having set this crossOrigin attribute on the img element. And the Response Headers contain

Access-Control-Allow-Origin: null

which is the effect of the server supporting CORS for this file.

Doing this in HTML

Of course, one could also set this attribute in HTML, in which case it’s case-insensitive:

<img src="http://khm0.googleapis.com/kh?v=95&x=0&y=0&z=0" crossorigin="anonymous">

And since “anonymous” is both the missing-value-default and the invalid-value-default for the crossorigin attribute, we can pass any invalid value for it, or even just omit its value:

<img src="http://khm0.googleapis.com/kh?v=95&x=0&y=0&z=0" crossorigin>

Coming soon: CORS approval for Canvas 2D drawImage

What if you first draw a CORS-approved cross-domain image onto a 2D
canvas, and then use that canvas as the source of a WebGL texture? The
good news is that this will work in Firefox 9, which is hitting the Beta
channel soon. This fix means that demos like this will work really
nicely in Firefox 9.

View full post on Mozilla Hacks – the Web developer blog

2 thoughts on “Using CORS to load WebGL textures from cross-domain images

  1. Benoit Jacob

    @Henri: I think it’s smart! Hopefully though, we’ll manage to evangelize content providers to support CORS so that that won’t be needed in the future.

Leave a Reply