I am attempting to detect WebGL support across multiple browsers and I\'ve encountered the following scenario. The current version of Firefox appears to report positive supp
[Oct 2014] I've updated modernizrs example to match their current implementation, which is a cleaned up version from http://get.webgl.org/ further below.
Modernizr does,
var canvas;
var ctx;
var exts;
try {
canvas = createElement('canvas');
ctx = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
exts = ctx.getSupportedExtensions();
}
catch (e) {
return;
}
if (ctx !== undefined) {
Modernizr.webglextensions = new Boolean(true);
}
for (var i = -1, len = exts.length; ++i < len; ){
Modernizr.webglextensions[exts[i]] = true;
}
canvas = undefined;
Chromium points to http://get.webgl.org/ for the canonical support implementation,
try { gl = canvas.getContext("webgl"); }
catch (x) { gl = null; }
if (gl == null) {
try { gl = canvas.getContext("experimental-webgl"); experimental = true; }
catch (x) { gl = null; }
}
// this code will detect WebGL version until WebGL Version maxVersionTest
var
maxVersionTest = 5,
canvas = document.createElement('canvas'),
webglVersion = (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')) ? 1 : null,
canvas = null; // free context
// range: if maxVersionTest = 5 makes [5, 4, 3, 2]
Array.apply(null, Array(maxVersionTest - 1))
.map(function (_, idx) {return idx + 2;})
.reverse()
.some(function(version){
// cant reuse canvas, potential to exceed contexts or mem limit *
if (document.createElement('canvas').getContext('webgl'+version))
return !!(webglVersion = version);
});
console.log(webglVersion);
* re "potential to exceed contexts or mem limit" see https://bugs.chromium.org/p/chromium/issues/detail?id=226868
In addition to @Andrew answer, there is also experimental mode which can be supported. I have written following snippet of code:
var canvasID = 'webgl',
canvas = document.getElementById(canvasID),
gl,
glExperimental = false;
function hasWebGL() {
try { gl = canvas.getContext("webgl"); }
catch (x) { gl = null; }
if (gl === null) {
try { gl = canvas.getContext("experimental-webgl"); glExperimental = true; }
catch (x) { gl = null; }
}
if(gl) { return true; }
else if ("WebGLRenderingContext" in window) { return true; } // not a best way, as you're not 100% sure, so you can change it to false
else { return false; }
}
Change canvasID
variable according to your ID.
Tested on Chrome, Safari, Firefox, Opera and IEs (8 to 10). In case of Safari remember that it's available, but you need to enable WebGL explicitly (enable the developer menu and enable Web GL option after).
In order to detect browsers that support WebGL, but leaving out older browsers with may not support it well (as needed in WebGL detected as supported when it is actually not for ruling out Android 4.4.2 devices), I am adding a tighter, though unrelated check:
function hasWebGL() {
var supported;
try {
var canvas = document.createElement('canvas');
supported = !! window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
} catch(e) { supported = false; }
try {
// let is by no means required, but will help us rule out some old browsers/devices with potentially buggy implementations: http://caniuse.com/#feat=let
eval('let foo = 123;');
} catch (e) { supported = false; }
if (supported === false) {
console.log("WebGL is not supported");
}
canvas = undefined;
return supported;
},
As seen in http://www.browserleaks.com/webgl#howto-detect-webgl
This is a proper javascript function to detect WebGL support, with all kind of experimental WebGL context names and with checking of special cases, such as blocking WebGL functions by NoScript or TorBrowser.
It will report one of the three WebGL capability states:
- WebGL is enabled — return TRUE, or return
- WebGL object, if the first argument was passed
- WebGL is disabled — return FALSE, you can change it if you need>
- WebGL is not implimented — return FALSE
function webgl_detect(return_context)
{
if (!!window.WebGLRenderingContext) {
var canvas = document.createElement("canvas"),
names = ["webgl2", "webgl", "experimental-webgl", "moz-webgl", "webkit-3d"],
context = false;
for(var i=0;i< names.length;i++) {
try {
context = canvas.getContext(names[i]);
if (context && typeof context.getParameter == "function") {
// WebGL is enabled
if (return_context) {
// return WebGL object if the function's argument is present
return {name:names[i], gl:context};
}
// else, return just true
return true;
}
} catch(e) {}
}
// WebGL is supported, but disabled
return false;
}
// WebGL not supported
return false;
}
From MDN:
// Run everything inside window load event handler, to make sure
// DOM is fully loaded and styled before trying to manipulate it.
window.addEventListener("load", function() {
var paragraph = document.querySelector("p"),
button = document.querySelector("button");
// Adding click event handler to button.
button.addEventListener("click", detectWebGLContext, false);
function detectWebGLContext () {
// Create canvas element. The canvas is not added to the
// document itself, so it is never displayed in the
// browser window.
var canvas = document.createElement("canvas");
// Get WebGLRenderingContext from canvas element.
var gl = canvas.getContext("webgl")
|| canvas.getContext("experimental-webgl");
// Report the result.
if (gl && gl instanceof WebGLRenderingContext) {
paragraph.innerHTML =
"Congratulations! Your browser supports WebGL.";
} else {
paragraph.innerHTML = "Failed to get WebGL context. "
+ "Your browser or device may not support WebGL.";
}
}
}, false);
body {
text-align : center;
}
button {
display : block;
font-size : inherit;
margin : auto;
padding : 0.6em;
}
<p>[ Here would go the result of WebGL feature detection ]</p>
<button>Press here to detect WebGLRenderingContext</button>