FAQ: Difference between revisions

From WebGL Public Wiki
Jump to navigation Jump to search
CipaX (talk | contribs)
No edit summary
 
(17 intermediate revisions by 6 users not shown)
Line 3: Line 3:
== What is the recommended way to initialize WebGL? ==
== What is the recommended way to initialize WebGL? ==


It is recommended that you check for success or failure to initialize. If WebGL fails to initialize it is recommended you distinguish between failure because the browser doesn't support WebGL and failure because for some other reason. If the browser does not support WebGL then present the user with a link to "http://get.webgl.org". If WebGL failed for some other reason present the user with a link to "http://get.webgl.org/troubleshooting/"
It is recommended that you check for success or failure to initialize. If WebGL fails to initialize it is recommended you distinguish between failure because the browser doesn't support WebGL and failure for some other reason. If the browser does not support WebGL then present the user with a link to "http://get.webgl.org". If WebGL failed for some other reason present the user with a link to "http://get.webgl.org/troubleshooting/"


[https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/demos/common/webgl-utils.js There is a wrapper that will do all of this for you here].
You can determine if the browser supports WebGL by checking for the existence of WebGLRenderingContext.
 
<pre>
if (window.WebGLRenderingContext) {
  // browser supports WebGL
}
</pre>
 
If the browser supports WebGL and canvas.getContext("webgl") returns null then WebGL failed for some reason other than user's browser (no GPU, out of memory, etc...)
 
<pre>
  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 ctx = canvas.getContext("webgl");
    if (!ctx) {
      // browser supports WebGL but initialization failed.
      window.location = "http://get.webgl.org/troubleshooting";
    }
  }
</pre>
 
Note: You MUST check that the browser supports WebGL to know that getting null from canvas.getContext() means
 
[https://github.com/KhronosGroup/WebGL/blob/master/sdk/demos/common/webgl-utils.js There is a wrapper that will do all of this for you here].


Example using the wrapper
Example using the wrapper
Line 31: Line 57:
== What is the recommended way to implement a rendering loop? ==
== What is the recommended way to implement a rendering loop? ==


It is HIGHLY recommended you use ''requestAnimationFrame'' if it is available. [https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/demos/common/webgl-utils.js There is a small cross browser wrapper available here].
It is HIGHLY recommended you use ''requestAnimationFrame'' if it is available. [https://github.com/KhronosGroup/WebGL/blob/master/sdk/demos/common/webgl-utils.js There is a small cross browser implementationr available here].


Example using the wrapper.
Example using the wrapper.
Line 39: Line 65:
<script type="text/javascript" src="localpath/webgl-utils.js"></script>
<script type="text/javascript" src="localpath/webgl-utils.js"></script>
<script>
<script>
  window.onload = init;
   function init() {
   function init() {
     canvas = document.getElementById("c");
     canvas = document.getElementById("c");
Line 48: Line 76:
   function render() {
   function render() {
     // request render to be called for the next frame.
     // request render to be called for the next frame.
     WebGLUtils.requestAnimationFrame(canvas, render);
     window.requestAnimFrame(render, canvas);
 
    // get the current animation time.
    var currentAnimationTime = WebGLUtils.animationTime();


     ...
     ...
Line 64: Line 89:


== What is the recommended way to handle lost context? ==
== What is the recommended way to handle lost context? ==
See [[HandlingContextLost|Handling Context Lost]].
== How do I make my content rendered in hi-res on HI-DPI machines? ==
See [[HandlingHighDPI|Handling High DPI displays in WebGL]].


== Why don't textures work in my vertex shader on browser/machine/os XXX? ==
== Why don't textures work in my vertex shader on browser/machine/os XXX? ==
Line 90: Line 121:
== Why do I get an error with gl.framebufferTexture2D on certain machines/browsers? ==
== Why do I get an error with gl.framebufferTexture2D on certain machines/browsers? ==


There is a bug in many NVidia drivers that requires that textures passed to framebufferTexture2D be renderable. In other words, they either must have all required mips or else must set filtering to not require mips. Since the texture is not renderable without those settings, set the texture parameters before calling framebufferTexture2D
There is a bug in many NVidia drivers that requires that textures passed to framebufferTexture2D be complete. In other words, they either must have all required mip levels or else filtering must be set to not require more than the base mip level. Since the texture is not complete without these settings, set the texture parameters before calling framebufferTexture2D


<pre>
<pre>
var fbo gl.createFramebuffer();
var fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);


var tex gl.createTexture();
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.RGBA, null);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.RGBA, null);


// Turn off the need for mips.
// Turn off the need for mips.
gl.texParameter(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);


// Set wrapping to CLAMP_TO_EDGE
// Set wrapping to CLAMP_TO_EDGE
gl.texParamater(gl.TEXTURE_2D, gl.WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParamater(gl.TEXTURE_2D, gl.WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);


gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
</pre>
</pre>
== Why do I get poor performance with specific vertex attribute types on some GPUs? ==
There's an obscure slow-down on some ATI/AMD configs when using single-byte vertex attributes (e.g. passing size=1 and type=UNSIGNED_BYTE or BYTE to vertexAttribPointer). A simple workaround is to use size=4, or use type=FLOAT so that the vertex attribute size is a multiple of 4 bytes. This doesn't seem to be a WebGL problem, but a problem in the underlying GPU driver.
Configurations where this problem has been reproduced:
# 2011 MacBook Pro OSX 10.7.5 with AMD Radeon HD 6750M or HD 6770M

Latest revision as of 12:23, 2 March 2014

Programming

What is the recommended way to initialize WebGL?

It is recommended that you check for success or failure to initialize. If WebGL fails to initialize it is recommended you distinguish between failure because the browser doesn't support WebGL and failure for some other reason. If the browser does not support WebGL then present the user with a link to "http://get.webgl.org". If WebGL failed for some other reason present the user with a link to "http://get.webgl.org/troubleshooting/"

You can determine if the browser supports WebGL by checking for the existence of WebGLRenderingContext.

if (window.WebGLRenderingContext) {
  // browser supports WebGL
}

If the browser supports WebGL and canvas.getContext("webgl") returns null then WebGL failed for some reason other than user's browser (no GPU, out of memory, etc...)

  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 ctx = canvas.getContext("webgl");
    if (!ctx) {
      // browser supports WebGL but initialization failed.
      window.location = "http://get.webgl.org/troubleshooting";
    }
  }

Note: You MUST check that the browser supports WebGL to know that getting null from canvas.getContext() means

There is a wrapper that will do all of this for you here.

Example using the wrapper

<html>
<body>
<script type="text/javascript" src="localpath/webgl-utils.js"></script>
<script>
  function init() {
    canvas = document.getElementById("c");
    gl = WebGLUtils.setupWebGL(canvas);
    if (!gl) {
      return;
    }
    ...
  }

  window.onload = init;
</script>
<canvas id="c"></canvas>
</body>
</html>

What is the recommended way to implement a rendering loop?

It is HIGHLY recommended you use requestAnimationFrame if it is available. There is a small cross browser implementationr available here.

Example using the wrapper.

<html>
<body>
<script type="text/javascript" src="localpath/webgl-utils.js"></script>
<script>
  window.onload = init;

  function init() {
    canvas = document.getElementById("c");
    ...
    // render the first frame.
    render();
  }

  function render() {
    // request render to be called for the next frame.
    window.requestAnimFrame(render, canvas);

    ...
    // render scene
    ...
  }
</script>
<canvas id="c"></canvas>
</body>
</html>

What is the recommended way to handle lost context?

See Handling Context Lost.

How do I make my content rendered in hi-res on HI-DPI machines?

See Handling High DPI displays in WebGL.

Why don't textures work in my vertex shader on browser/machine/os XXX?

WebGL conforms to the OpenGL ES 2.0 spec in this regard. Implementations advertise how many textures can be accessed in a vertex shader with

var numTexturesAvailableInVertexShader = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS)

That value is allowed to be 0. In which case your code must take appropriate action.

Why don't my textures render?

WebGL conforms to the OpenGL ES 2.0 spec in this regard. Textures that are non-power-of-two (NPOT) do not render unless texture filtering is set so it does not require mips and texture wrapping is set to CLAMP_TO_EDGE. The default parameters of a texture require mips and are set to wrap so you must set the texture parameters appropriately.

gl.bindTexture(gl.TEXTURE_2D, someNPOTTexture);

// Turn off the need for mips.
gl.texParameter(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

// Set wrapping to CLAMP_TO_EDGE
gl.texParamater(gl.TEXTURE_2D, gl.WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParamater(gl.TEXTURE_2D, gl.WRAP_T, gl.CLAMP_TO_EDGE);

Why do I get an error with gl.framebufferTexture2D on certain machines/browsers?

There is a bug in many NVidia drivers that requires that textures passed to framebufferTexture2D be complete. In other words, they either must have all required mip levels or else filtering must be set to not require more than the base mip level. Since the texture is not complete without these settings, set the texture parameters before calling framebufferTexture2D

var fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);

var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.RGBA, null);

// Turn off the need for mips.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

// Set wrapping to CLAMP_TO_EDGE
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);

Why do I get poor performance with specific vertex attribute types on some GPUs?

There's an obscure slow-down on some ATI/AMD configs when using single-byte vertex attributes (e.g. passing size=1 and type=UNSIGNED_BYTE or BYTE to vertexAttribPointer). A simple workaround is to use size=4, or use type=FLOAT so that the vertex attribute size is a multiple of 4 bytes. This doesn't seem to be a WebGL problem, but a problem in the underlying GPU driver.

Configurations where this problem has been reproduced:

  1. 2011 MacBook Pro OSX 10.7.5 with AMD Radeon HD 6750M or HD 6770M