В WebGL вы передаете пару format/type в readPixels. Для данного
внутреннего формата текстуры (прикрепленной к framebuffer), только 2 комбинации
format/type являются действительными.
Из спецификации:
Для нормализованных поверхностей рендеринга с фиксированной точкой принимается комбинация format
RGBAи typeUNSIGNED_BYTE. Для поверхностей рендеринга со знаковыми целыми числами принимается комбинация formatRGBA_INTEGERи typeINT. Для поверхностей рендеринга с беззнаковыми целыми числами принимается комбинация formatRGBA_INTEGERи typeUNSIGNED_INT.
Вторая комбинация определяется реализацией что, вероятно, означает, что вы не должны использовать ее в WebGL, если хотите, чтобы ваш код был переносимым. Вы можете спросить, какая комбинация format/type, запросив
// предполагая, что framebuffer привязан с текстурой для чтения
const format = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
const type = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
Также обратите внимание, что форматы текстур, которые являются рендерируемыми, что означает, что вы можете прикрепить их к framebuffer и рендерить в них,
также в некоторой степени определяются реализацией.
WebGL2 перечисляет много форматов, но некоторые являются опциональными (LUMINANCE, например) и некоторые
не являются рендерируемыми по умолчанию, но могут быть сделаны рендерируемыми через расширение. (RGBA32F, например).
Таблица ниже живая. Вы можете заметить, что она дает разные результаты в зависимости от машины, ОС, GPU или даже браузера. Я знаю, что на моей машине Chrome и Firefox дают разные результаты для некоторых значений, определяемых реализацией.