Правильный способ обнаружения поддержки WebGL?

Я пытаюсь обнаружить поддержку WebGL в нескольких браузерах, и я столкнулся со следующим сценарием. Текущая версия Firefox, похоже, сообщает о положительной поддержке, используя следующую проверку, даже когда видеокарта посетителя выбрана с черным списком и/или WebGL отключена:

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

Я попробовал проинструктировать моих пользователей включить WebGL, выполнив следующие шаги. Это работало в некоторых случаях, но не всегда. Очевидно, это не то, что я могу запросить у широкой общественности:

  • Введите about: config в адресной строке Firefox.
  • Чтобы включить WebGL, установите webgl.force-enabled на true

Это привело меня к созданию моего собственного метода обнаружения поддержки, который использует jQuery для ввода элемента canvas для обнаружения поддержки. Это касается ряда методов, которые я нашел в различных библиотеках и плагинах WebGL. Беда в том, что это очень сложно проверить (любые комментарии о том, работает ли ссылка ниже для вас, очень ценятся!). Чтобы сделать этот объективный вопрос, , я хотел бы узнать, существует ли общепринятый способ обнаружения поддержки WebGL во всех браузерах.

ИСПЫТАНИЕ URL:

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

Ответ 1

[ Октябрь 2014]. Я обновил пример 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; }
}

Ответ 2

В превосходной Три библиотеки есть, по сути, механизм для обнаружения следующего:

  • Поддержка WebGL
  • Поддержка API файлов.
  • Поддержка рабочих.

Для 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

Ответ 3

Как видно из http://www.browserleaks.com/webgl#howto-detect-webgl

Это правильная функция javascript для обнаружения поддержки WebGL со всеми типами экспериментальных имен WebGL и с проверкой особых случаев, таких как блокирование функций WebGL с помощью NoScript или TorBrowser.

Он сообщит об одном из трех состояний возможностей 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 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

В дополнение к ответу @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; }
}

Измените переменную canvasID в соответствии с вашим идентификатором.

Протестировано в Chrome, Safari, Firefox, Opera и IE (от 8 до 10). В случае Safari помните, что он доступен, но вам нужно включить WebGL явно (включите меню разработчика и включите опцию Web GL после).

Ответ 5

Чтобы обнаружить браузеры, поддерживающие 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

// 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 "потенциал для превышения контекста или лимита mem" см. https://bugs.chromium.org/p/chromium/issues/detail?id=226868