function loadCubemapFromUrls(gl, tex, options, callback) {
    callback = callback || noop;
    var urls = options.src;
    if (urls.length !== 6) {
      throw "there must be 6 urls for a cubemap";
    }
    var format = options.format || gl.RGBA;
    var type = options.type || gl.UNSIGNED_BYTE;
    var target = options.target || gl.TEXTURE_2D;
    if (target !== gl.TEXTURE_CUBE_MAP) {
      throw "target must be TEXTURE_CUBE_MAP";
    }
    setTextureTo1PixelColor(gl, tex, options);
    // Because it's async we need to copy the options.
    options = utils.shallowCopy(options);
    var numToLoad = 6;
    var errors = [];
    var imgs;
    var faces = getCubeFaceOrder(gl, options);

    function uploadImg(faceTarget) {
      return function(err, img) {
        --numToLoad;
        if (err) {
          errors.push(err);
        } else {
          if (img.width !== img.height) {
            errors.push("cubemap face img is not a square: " + img.src);
          } else {
            savePackState(gl, options);
            gl.bindTexture(target, tex);

            // So assuming this is the first image we now have one face that's img sized
            // and 5 faces that are 1x1 pixel so size the other faces
            if (numToLoad === 5) {
              // use the default order
              getCubeFaceOrder(gl).forEach(function(otherTarget) {
                // Should we re-use the same face or a color?
                gl.texImage2D(otherTarget, 0, format, format, type, img);
              });
            } else {
              gl.texImage2D(faceTarget, 0, format, format, type, img);
            }

            restorePackState(gl, options);
            gl.generateMipmap(target);
          }
        }

        if (numToLoad === 0) {
          callback(errors.length ? errors : undefined, imgs, tex);
        }
      };
    }

    imgs = urls.map(function(url, ndx) {
      return loadImage(url, options.crossOrigin, uploadImg(faces[ndx]));
    });
  }
Loads a cubemap from 6 urls as specified in `options.src`. Will set the cubemap to a 1x1 pixel color
so that it is usable immediately unless `option.color === false`.
@param {WebGLRenderingContext} gl the WebGLRenderingContext
@param {WebGLTexture} tex the WebGLTexture to set parameters for
@param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.
@param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will
   be non null if there was an error.
@memberOf module:twgl/textures