function createUBOElements(uniformData) {
    var uboElements = uniformData.map(function (data) {
        return ({
            data: data,
            offset: 0,
            dataLen: 0,
            dirty: 0
        });
    });
    var size = 0;
    var chunkSize = 0;
    var offset = 0;
    for (var i = 0; i < uboElements.length; i++) {
        var uboElement = uboElements[i];
        size = GLSL_TO_STD40_SIZE[uboElement.data.type];
        if (uboElement.data.size > 1) {
            size = Math.max(size, 16) * uboElement.data.size;
        }
        uboElement.dataLen = size;
        // add some size offset..
        // must align to the nearest 16 bytes or internally nearest round size
        if (chunkSize % size !== 0 && chunkSize < 16) {
            // diff required to line up..
            var lineUpValue = (chunkSize % size) % 16;
            chunkSize += lineUpValue;
            offset += lineUpValue;
        }
        if ((chunkSize + size) > 16) {
            offset = Math.ceil(offset / 16) * 16;
            uboElement.offset = offset;
            offset += size;
            chunkSize = size;
        }
        else {
            uboElement.offset = offset;
            chunkSize += size;
            offset += size;
        }
    }
    offset = Math.ceil(offset / 16) * 16;
    return { uboElements: uboElements, size: offset };
}
logic originally from here: https://github.com/sketchpunk/FunWithWebGL2/blob/master/lesson_022/Shaders.js
rewrote it, but this was a great starting point to get a solid understanding of whats going on :)
@ignore
@param uniformData