code: function(callback) {
      var v = gl.getParameter(gl.VIEWPORT);
      framebuffer = framebuffer || gl.createFramebuffer();
      renderbuffer = renderbuffer || gl.createRenderbuffer();
      gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
      gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
      if (this.width != renderbuffer.width || this.height != renderbuffer.height) {
        renderbuffer.width = this.width;
        renderbuffer.height = this.height;
        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height);
      }
      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.id, 0);
      gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer);
      if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
        throw new Error('Rendering to this texture is not supported (incomplete framebuffer)');
      }
      gl.viewport(0, 0, this.width, this.height);
  
      callback();
  
      gl.bindFramebuffer(gl.FRAMEBUFFER, null);
      gl.bindRenderbuffer(gl.RENDERBUFFER, null);
      gl.viewport(v[0], v[1], v[2], v[3]);
    }
docs: ### .drawTo(callback)  Render all draw calls in `callback` to this texture. This method sets up a framebuffer with this texture as the color attachment and a renderbuffer as the depth attachment. It also temporarily changes the viewport to the size of the texture.  Example usage:  texture.drawTo(function() { gl.clearColor(1, 0, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); });