web-dev-qa-db-ja.com

WebGLサポートを検出する適切な方法は?

複数のブラウザーでWebGLサポートを検出しようとしていますが、次のシナリオに遭遇しました。 Firefoxの現在のバージョンは、訪問者のビデオカードがブラックリストに載っていたり、WebGLが無効になっている場合でも、次のチェックを使用して肯定的なサポートを報告しているようです。

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-enabledをtrueに設定します

これにより、jQueryを使用してキャンバス要素を挿入してサポートを検出する独自のサポート検出メソッドを作成することになりました。これは、さまざまなWebGLライブラリとプラグインで見つかった多くのテクニックを利用しています。問題は、テストするのが非常に難しいことです(以下のリンクが機能するかどうかについてのコメントは大歓迎です!)。これを客観的な質問にするために、すべてのブラウザでWebGLサポートを検出するために広く受け入れられている方法があるかどうか知りたいです

テストURL:

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

49
Derek Hunziker

[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; }
}
34
Andrew

実際、優れたThreeライブラリには、次を検出するメカニズムがあります。

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

このコードスニペットは Detector クラスの一部であり、対応するエラーメッセージをユーザーに表示する場合もあります。

33
oabarca

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

これは、WebGLサポートを検出するための適切なjavascript関数であり、あらゆる種類の実験的なWebGLコンテキスト名、およびNoScriptまたはTorBrowserによるWebGL関数のブロックなどの特殊なケースのチェックを行います。

3つのWebGL機能状態のいずれかを報告します。

  • WebGLが有効になっています— TRUEを返す、または返す
  • WebGLオブジェクト、最初の引数が渡された場合
  • WebGLは無効になっています— FALSEを返します。必要に応じて変更できます>
  • WebGLは実装されていません— 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;
}
18
Juan Arias

@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に従ってcanvasID変数を変更します。

Chrome、Safari、Firefoxでテスト済みOperaおよびIE(8〜10)。Safariの場合は利用可能ですが、WebGLを明示的に有効にする必要があります(開発者メニューを有効にしてWebを有効にするGLオプションの後)。

8
Karol

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;
},
2
Jose Gómez
// 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

1
ekerner

[〜#〜] 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>
0