正确的方法来检测WebGL的支持?

我试图检测跨多个浏览器的WebGL支持,我遇到了以下情况。 即使当访问者的video卡被黑名单和/或WebGL被禁用,Firefox的当前版本也会使用以下检查来报告积极的支持:

if (window.WebGLRenderingContext) { // This is true in Firefox under certain circumstances, // even when WebGL is disabled... } 

我已经试过指导我的用户使用以下步骤启用WebGL。 这在某些情况下有效,但并不总是如此。 显然,这不是我可以向公众要求的东西:

  1. 在Firefox的地址栏中键入about:config
  2. 要启用WebGL,请将启用webgl.force的设置为true

这导致我创build了自己的方法来检测支持,它使用jQuery注入一个canvas元素来检测支持。 这拉扯了我在各种WebGL库和插件中find的许多技术。 麻烦的是,testing是非常困难的(关于下面的链接是否适合你的评论是非常感谢!)。 为了使这是一个客观的问题, 我想知道是否有一个普遍接受的方式来检测所有浏览器的WebGL支持

testingurl:

http://jsfiddle.net/Jn49q/5/

[ 2014年10月]我已经更新了modernizrs示例以匹配它们的当前实现 ,这是来自http://get.webgl.org/的清理版本。;

Modernizr呢 ,

 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指向http://get.webgl.org/为规范的支持实施,;

 try { gl = canvas.getContext("webgl"); } catch (x) { gl = null; } if (gl == null) { try { gl = canvas.getContext("experimental-webgl"); experimental = true; } catch (x) { gl = null; } } 

事实上,优秀的三库有一个检测以下内容的机制:

  1. WebGL支持
  2. 文件API支持
  3. 工人支持

对于WebGL,特别是,这里是使用的代码:

 function webgl_support() { try{ var canvas = document.createElement( 'canvas' ); return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); }catch( e ) { return false; } }; 

该代码片段是检测器类的一部分,其也可以向用户显示相应的错误消息。 看看: https : //github.com/mrdoob/three.js/blob/master/examples/js/Detector.js

http://www.browserleaks.com/webgl#howto-detect-webgl中可以看到;

这是一个正确的javascript函数来检测WebGL支持,所有types的实验性WebGL上下文名称和特殊情况下的检查,例如NoScript或TorBrowser阻止WebGL函数。

它将报告三个WebGL能力状态之一:

  • WebGL已启用 – 返回TRUE,或返回
  • WebGL对象,如果第一个参数被传递
  • WebGL被禁用 – 返回FALSE,你可以改变它,如果你需要>
  • WebGL没有实现 – 返回FALSE
 function webgl_detect(return_context) { if (!!window.WebGLRenderingContext) { var canvas = document.createElement("canvas"), names = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"], context = false; for(var i=0;i<4;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; } 

除了@Andrew的回答,还有可以支持的实验模式。 我已经写了下面的代码片段:

 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; } } 

根据您的ID更改canvasIDvariables。

经过Chrome,Safari,Firefox,Opera和IEs(8到10)的testing。 如果Safari记住它是可用的,但您需要显式启用WebGL(启用开发者菜单并启用Web GL选项)。

为了检测支持WebGL的浏览器,但是遗漏旧版本的浏览器可能并不能很好地支持它(当WebGL检测到支持的时候,它实际上并不排除Android 4.4.2设备),但是我增加了一个更紧密的无关的检查:

 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; }, 
 // 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); 

*“有可能超出上下文限制”请参阅https://bugs.chromium.org/p/chromium/issues/detail?id=226868