Как скопировать буфер глубины в текстуру на графическом процессоре?

Я хочу получить текущий буфер глубины для текстуры, чтобы получить к нему доступ в шейдере. По разным причинам я не могу сделать отдельный проход глубины, но мне нужно будет скопировать уже обработанную глубину.

glReadPixels будет задействовать процессор и потенциально убить производительность, и, насколько я знаю glBlitFramebuffer не может высечь глубину цвета, только глубину глубины.

Как это сделать на GPU?

3 ответа

Современный способ сделать это - использовать FBO. Прикрепите к нему текстуру цвета и глубины, выполните рендеринг, затем отключите FBO и используйте текстуры в качестве входных данных для шейдера, который будет отображаться в буфере кадров по умолчанию.

Все подробности о FBO, которые вам нужны, можно найти здесь.

Копировать буфер глубины в текстуру довольно просто. Если вы создали новую текстуру, для которой вы не назвали glTexImage *, вы можете использовать glCopyTexImage2D. Это скопирует пиксели из кадрового буфера в текстуру. Чтобы скопировать пиксели глубины, вы используете формат GL_DEPTH_COMPONENT. Я бы предложил GL_DEPTH_COMPONENT24.

Если вы ранее создали текстуру в формате компонента глубины (т. Е. В любое время после первого кадра), то вы можете напрямую скопировать данные этого изображения с помощью glCopyTexSubImage2D.

Также кажется, что у вас проблемы с доступом к текстурам компонентов глубины в вашем шейдере, так как вы хотите скопировать глубину в цвет (что недопустимо). Если да, то это проблема, которую вы должны исправить.

В любом случае копирование должно быть последним средством. Вы должны использовать объекты кадрового буфера всякий раз, когда это возможно. Просто визуализируйте прямо на вашу текстуру.

Лучшим способом было бы использование FBO для лучшей производительности и некоторых проблем со стилем кодирования. Если вы не заинтересованы, посмотрите на этот код. Это с тех дней, когда я был намного моложе!(И не знал, что существуют FBO)

int shadowMapWidth = 512;
int shadowMapHeight = 512;
glGenTextures(1, &m_depthTexture);

glBindTexture(GL_TEXTURE_2D, m_depthTexture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 512,512);
Другие вопросы по тегам