async function loadFrames(src, frameData) {
  if (typeof frameData === 'string') {
    const response = await fetch(frameData, {
      method: 'GET',
      mode: 'cors',
      cache: 'default'
    });
    frameData = await response.json();
  }

  const texture = await loadTexture(src);
  const frames = frameData.frames;
  Object.entries(frames).forEach(([key, frame]) => {
    const {
      x,
      y,
      w,
      h
    } = frame.frame;
    let sourceRect = [x, y, w, h];
    const rotated = frame.rotated;

    if (rotated) {
      sourceRect = [sourceRect[0], sourceRect[1], sourceRect[3], sourceRect[2]];
    }

    loadedTextures[key] = {
      image: texture,
      sourceRect,
      rotated
    };
  });
  return texture;
}
u3d-json compatible: https://www.codeandweb.com/texturepacker
  {
    frames: {
      key: {
        frame: {x, y, w, h},
        trimmed: ...,
        rotated: true|false,
        spriteSourceSize: {x, y, w, h},
        sourceSize: {w, h}
      }
    }
  }