Могу ли я прочитать значение одного пикселя из текстуры глубины WebGL в JavaScript?

Короче говоря

Я хотел бы прочитать значение одного пикселя из текстуры глубины WebGL 2 в JavaScript. Это вообще возможно?

Сценарий

Я визуализирую сцену в WebGL 2. Рендерер получает текстуру глубины, в которую он записывает буфер глубины. Эта текстура глубины используется в шейдерах постобработки и т.п., поэтому она доступна нам.

Однако мне нужно прочитать значение одного пикселя в JavaScript, а не в шейдере. Если бы это была обычная текстура RGB, я бы сделал

function readPixel(x, y, texture, outputBuffer) {
    const frameBuffer = gl.createFramebuffer();
    gl.bindFramebuffer( gl.FRAMEBUFFER, frameBuffer );
    gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0 );
    gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, outputBuffer);
}

Это запишет пиксель в x, y в outputBuffer.

Однако возможно ли вообще сделать то же самое с текстурой глубины? Если я просто передам текстуру глубины моей функции выше, в выходном буфере будут только нули, и я получу предупреждение WebGL GL_INVALID_FRAMEBUFFER_OPERATION: Framebuffer is incomplete.. Проверка состояния фреймбуфера показывает FRAMEBUFFER_INCOMPLETE_ATTACHMENT.

Естественно, текстура глубины не является текстурой RGBA, но есть ли какие-то другие значения, которые мы можем дать ей, чтобы получить наше значение глубины, или это невозможно?

Мотивация

Я знаю, что этот вопрос задавался несколько раз на StackOverflow и в других местах в той или иной форме, но всегда есть некоторые вариации, из-за которых я сбиваюсь с толку, получая прямой ответ «да» или «нет» на вопрос в форме я прошу его здесь. Кроме того, многие вопросы и источники очень старые, только WebGL 1, с некоторыми упоминаниями webgl_depth_texture что-то изменить и т. д. и т. д.

Если ответ отрицательный, я буду рад любым предложениям о том, как еще легко получить этот пиксель глубины. Поскольку эта операция не выполняется для каждого кадра, я предпочитаю простоту производительности. Вариант использования — выбор, и классическое пересечение лучей невозможно. (Я также знаю, что я могу кодировать скалярное значение глубины в пиксель RGB и из него, но в первую очередь мне нужно иметь доступ к пикселю из кода js.)

Я приветствую любые идеи.


person Berthur    schedule 26.05.2021    source источник


Ответы (1)


Нет возможности, чтобы WebGL 2.0 основывался на OpenGL ES 3.0.
В Спецификация OpenGL ES 3.2 — 4.3.2 Чтение Пиксели четко указаны:

[...] Второй - это формат, выбранный реализацией из числа определенных в таблице 3.2, исключая форматы DEPTH_COMPONENT и DEPTH_STENCIL [...]

person Rabbid76    schedule 26.05.2021
comment
Спасибо, это уже полезная информация. Однако для неспециалиста это само по себе не означает, что вы не можете прочитать текстуру глубины. Можно надеяться, что вы могли бы, например. как-то обрабатывать его как значение RGB, или конвертировать, или что-то еще. Знаете ли вы, что это совершенно невозможно (без использования специального шейдера для чтения, упаковки и записи в текстуру RGBA)? - person Berthur; 26.05.2021
comment
@Berthur Это означает, что вы не можете это прочитать. Однако я не хочу копировать всю главу спецификации в ответ. Это одно из различий между OpenGL ES и (настольным) OpenGL. - person Rabbid76; 26.05.2021