检测WebGL支持的正确方法?

时间:2022-06-01 04:23:05

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 support using the following check, even when the visitor's video card is black-listed and/or WebGL is disabled:

我正在尝试跨多个浏览器检测WebGL支持,我遇到了以下场景。当前版本的Firefox似乎通过以下检查报告了积极的支持,即使访问者的视频卡被黑列表和/或WebGL禁用:

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

I've tried instructing my users to enable WebGL using the following steps. This has worked in some cases, but not always. Obviously, this is not something I can request of the general public:

我已经尝试指示我的用户使用以下步骤启用WebGL。这在某些情况下行得通,但并不总是这样。显然,我不能要求公众这样做:

  1. Type about:config in Firefox’s address bar
  2. 在Firefox的地址栏中输入about:config
  3. To enable WebGL, set webgl.force-enabled to true
  4. 要启用WebGL,请设置WebGL。force-enabled为真

This has led me to create my own method for detecting support, which uses jQuery to inject a canvas element to detect support. This pulls on a number of techniques I found in various WebGL libraries and plugins. The trouble is, it is extremely difficult to test (any comments on whether the link below works for you are much appreciated!). To make this an objective question, I would like to know if there's a universally accepted way to detect WebGL support across all browsers.

这使我创建了自己的检测支持的方法,它使用jQuery注入一个canvas元素来检测支持。这利用了我在各种WebGL库和插件中发现的许多技术。麻烦的是,测试是极其困难的(对于下面的链接是否适合您的任何评论都非常感谢!)为了使这成为一个客观的问题,我想知道是否有一种普遍接受的方法来检测所有浏览器的WebGL支持。

TEST URL:

测试网址:

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

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

7 个解决方案

#1


31  

[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.

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

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,

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

#2


27  

The excellent Three library has, in fact, a mechanism for detecting the following:

优秀的三库实际上有一种机制可以检测以下内容:

  1. WebGL support
  2. WebGL支持
  3. File API support
  4. 文件API支持
  5. Workers support
  6. 工人的支持

For WebGL, particularly, here is the code that is used:

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

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

That code snippet is part of a Detector class which may also display the corresponding error messages to the user.

该代码片段是检测器类的一部分,该类还可以向用户显示相应的错误消息。

#3


16  

As seen in http://www.browserleaks.com/webgl#howto-detect-webgl

见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.

这是一个用于检测WebGL支持的合适的javascript函数,具有各种实验性的WebGL上下文名称,并检查特殊情况,例如通过NoScript或TorBrowser来阻塞WebGL函数。

It will report one of the three WebGL capability states:

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

  • WebGL is enabled — return TRUE, or return
  • WebGL是启用的-返回TRUE,或者返回。
  • WebGL object, if the first argument was passed
  • 对象,如果第一个参数被传递
  • WebGL is disabled — return FALSE, you can change it if you need>
  • WebGL是禁用的——返回FALSE,如果需要>,您可以修改它
  • WebGL is not implimented — return FALSE
  • WebGL没有被限制-返回错误
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;
}

#4


8  

In addition to @Andrew answer, there is also experimental mode which can be supported. I have written following snippet of code:

除了@Andrew answer之外,还有可以支持的实验模式。我写了以下代码片段:

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.

根据您的ID更改canvasID变量。

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).

在Chrome、Safari、Firefox、Opera和IEs(8 - 10)上测试。如果Safari记住它是可用的,但是您需要显式地启用WebGL(启用developer菜单并在之后启用WebGL选项)。

#5


2  

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:

为了检测支持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;
},

#6


0  

// 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

* re“可能超出上下文或mem限制”参见https://bugs.chromium.org/p/chromium/issues/detail?id=226868

#7


0  

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>

#1


31  

[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.

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

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,

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

#2


27  

The excellent Three library has, in fact, a mechanism for detecting the following:

优秀的三库实际上有一种机制可以检测以下内容:

  1. WebGL support
  2. WebGL支持
  3. File API support
  4. 文件API支持
  5. Workers support
  6. 工人的支持

For WebGL, particularly, here is the code that is used:

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

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

That code snippet is part of a Detector class which may also display the corresponding error messages to the user.

该代码片段是检测器类的一部分,该类还可以向用户显示相应的错误消息。

#3


16  

As seen in http://www.browserleaks.com/webgl#howto-detect-webgl

见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.

这是一个用于检测WebGL支持的合适的javascript函数,具有各种实验性的WebGL上下文名称,并检查特殊情况,例如通过NoScript或TorBrowser来阻塞WebGL函数。

It will report one of the three WebGL capability states:

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

  • WebGL is enabled — return TRUE, or return
  • WebGL是启用的-返回TRUE,或者返回。
  • WebGL object, if the first argument was passed
  • 对象,如果第一个参数被传递
  • WebGL is disabled — return FALSE, you can change it if you need>
  • WebGL是禁用的——返回FALSE,如果需要>,您可以修改它
  • WebGL is not implimented — return FALSE
  • WebGL没有被限制-返回错误
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;
}

#4


8  

In addition to @Andrew answer, there is also experimental mode which can be supported. I have written following snippet of code:

除了@Andrew answer之外,还有可以支持的实验模式。我写了以下代码片段:

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.

根据您的ID更改canvasID变量。

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).

在Chrome、Safari、Firefox、Opera和IEs(8 - 10)上测试。如果Safari记住它是可用的,但是您需要显式地启用WebGL(启用developer菜单并在之后启用WebGL选项)。

#5


2  

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:

为了检测支持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;
},

#6


0  

// 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

* re“可能超出上下文或mem限制”参见https://bugs.chromium.org/p/chromium/issues/detail?id=226868

#7


0  

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>