如何正确识别 IE11 WebGL 兼容性(clearStencil、shaders)

How to identify IE11 WebGL compatibility (clearStencil,shaders) correctly

在 IE11 版本 11.0.9600.16428 及以下版本中,某些 WebGL 方法无法正常工作(如此处所述:https://github.com/mrdoob/three.js/issues/3600

一个例子是方法clearStencil。问题是该方法存在,但无法正常工作。我想检测到这一点并给用户一些反馈。我尝试了 Three.js 中的 Detector.js,但它只检查浏览器和图形卡是否支持 WebGL,而不检查它们是否支持所有相关功能。

我试过像这样进行 WebGL 检查:

var supportsWebGL=function(){
    if(Detector.webgl){
        var _canvas = document.createElement( 'canvas' );
        var _gl = _canvas.getContext( 'webgl' ) || _canvas.getContext( 'experimental-webgl' );
        try{
            _gl.clearStencil( 0 );
        }catch(e){
            return false;
        }
        return true;
    }else{
        return false;
    }
}

在 IE11 (11.0.9600.16428) 中,方法 supportsWebGL return 是正确的,但给我这样的错误:

WEBGL11095: INVALID-OPERATION: clearStencil: Method not currently supported.

现在我希望我的方法 supportsWebGL 检测到不兼容和 return 错误。有人知道怎么做吗?

目前我能想到的最好的方法是检查浏览器及其版本。

使用此代码片段获取浏览器名称及其版本(仅主要版本):

var browserInformation = (function() {
var temporal = undefined;
var userAgent = navigator.userAgent;
var matches = userAgent.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if (/trident/i.test(matches[1])) {
    temporal = /\brv[ :]+(\d+)/g.exec(userAgent) || [];
    return 'Internet Explorer ' + (temporal[1] || '');
}
if (matches[1] === 'Chrome') {
    temporal = userAgent.match(/\bOPR\/(\d+)/);
    if (temporal != null)
        return 'Opera ' + temporal[1];
}
matches = matches[2] ? [matches[1], matches[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((temporal = userAgent.match(/version\/(\d+)/i)) != null)
    matches.splice(1, 1, temporal[1]);
return matches.join(' ');})();

此代码段将 return 格式为 [浏览器名称版本] 的字符串,即 Internet Explorer 11.

我找到了一种使用 _gl.getError()

的方法
var supportsWebGL=function(){
    if(Detector.webgl){
        var _canvas = document.createElement( 'canvas' );
        var _gl = _canvas.getContext( 'webgl' ) || _canvas.getContext( 'experimental-webgl' );
        var errors=undefined;        
        try{
            _gl.clearStencil( 0 );
            errors=_gl.getError();
        }catch(e){
            return false;
        }
        return errors==0;
    }else{
        return false;
    }
}

只有当 errors 等于零时,该方法才会 return true。如果您有其他方法要检查,只需将它们添加到 try/catch 块。

如果您需要不使用 Three.js 的解决方案,请查看:

var supportsWebGL=function(){
    if(!window.WebGLRenderingContext)return false;
    try{
        var _canvas = document.createElement( 'canvas' );
        var _gl = _canvas.getContext( 'webgl' ) || _canvas.getContext( 'experimental-webgl' );
        _gl.clearStencil( 0 );
        var errors=_gl.getError();
        return errors==0;
    }catch(e){
        return false;
    }
}