38

Can anyone who has used three.js tell me if its possible to detect webgl support, and, if not present, fallback to a standard Canvas render?

Juan Mellado
  • 14,693
  • 5
  • 43
  • 53
Bachalo
  • 5,885
  • 22
  • 86
  • 175

3 Answers3

61

Yes, it's possible. You can use CanvasRenderer instead of WebGLRenderer.

About WebGL detection:

1) Read this WebGL wiki article: http://www.khronos.org/webgl/wiki/FAQ

 if (!window.WebGLRenderingContext) {
    // the browser doesn't even know what WebGL is
    window.location = "http://get.webgl.org";
  } else {
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("webgl");
    if (!context) {
      // browser supports WebGL but initialization failed.
      window.location = "http://get.webgl.org/troubleshooting";
    }
  }

2) Three.js already has a WebGL detector: https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js

renderer = Detector.webgl? new THREE.WebGLRenderer(): new THREE.CanvasRenderer();

3) Check also the Modernizr detector: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/webgl.js

Juan Mellado
  • 14,693
  • 5
  • 43
  • 53
  • 17
    Method 1/3 will fail if the browser supports WebGL but cannot use it for some reason (like the driver being blacklisted), which is why Method 2 uses a function with a try/catch block and also checks that the context can actually be created. – Joan Rieu Jul 22 '13 at 16:31
  • 1
    Worth noting that `Detector.js`has moved and is now at https://github.com/mrdoob/three.js/blob/master/examples/js/WebGL.js – ngalstyan May 07 '20 at 01:45
13

Juan Mellado's pointer to the Three.js detector was super useful, but I prefer not to bring the whole file into my project. So here is the extracted Detector.webgl() function.

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

And it is used similar to his example:

renderer = webglAvailable() ? new THREE.WebGLRenderer() : new THREE.CanvasRenderer();
Abtin Forouzandeh
  • 5,057
  • 4
  • 23
  • 28
1

Unfortunatelly, just detecting WebGL support does not automatically mean it will be any good. WebGL can be backed by software renderer like "google swiftshader" or partial emulation like "mesa 3D". Especially with a good 2D renderer like Mesa 2D it makes sense to manually choose canvas even when WebGL seems available.

user185953
  • 65
  • 6