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:
- A mandatory clause disallowing usage of cross-domain elements as WebGL textures in the general case.
- 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.
About Benoit Jacob
I am a software engineer at Mozilla Corp., working on Gecko, specifically the Graphics and WebGL parts. I work from Mozilla's Toronto office.
6 comments