addAttribute(name, size, type, normalized, offset) {
		this.attributes.push({
			name: name,
			size: size,
			type: type,
			normalized: normalized,
			offset: offset,
		});

		switch (type) {
			case this.gl.BYTE:
				this.vertexByteSize += size * Int8Array.BYTES_PER_ELEMENT;
				break;
			case this.gl.UNSIGNED_BYTE:
				this.vertexByteSize += size * Uint8Array.BYTES_PER_ELEMENT;
				break;
			case this.gl.SHORT:
				this.vertexByteSize += size * Int16Array.BYTES_PER_ELEMENT;
				break;
			case this.gl.UNSIGNED_SHORT:
				this.vertexByteSize += size * Uint16Array.BYTES_PER_ELEMENT;
				break;
			case this.gl.INT:
				this.vertexByteSize += size * Int32Array.BYTES_PER_ELEMENT;
				break;
			case this.gl.UNSIGNED_INT:
				this.vertexByteSize += size * Uint32Array.BYTES_PER_ELEMENT;
				break;
			case this.gl.FLOAT:
				this.vertexByteSize += size * Float32Array.BYTES_PER_ELEMENT;
				break;
			default:
				throw new Error("Invalid GL Attribute type");
		}
		this.vertexSize = this.vertexByteSize / Float32Array.BYTES_PER_ELEMENT;
	}
add vertex attribute property definition to the compositor
@param {string} name - name of the attribute in the vertex shader
@param {number} size - number of components per vertex attribute. Must be 1, 2, 3, or 4.
@param {GLenum} type - data type of each component in the array
@param {boolean} normalized - whether integer data values should be normalized into a certain range when being cast to a float
@param {number} offset - offset in bytes of the first component in the vertex attribute array