2014-04-28 3 views
0

В настоящее время я столкнулся с проблемой, тесно связанной с конвейером OpenGL, и использованием шейдеров.Как получить цвет с плавающей запятой из GLSL

Действительно, я работаю над проектом, одним из шагов которого является чтение пикселей из изображения, которое мы генерируем с использованием OpenGL, с максимальной точностью: я имею в виду, что вместо чтения целых чисел я хотел бы читать float номера. (Итак, вместо чтения значения (134, 208, 108) для пикселя я хотел бы получить, например, что-то вроде (134.180, 207.686, 108.413).)

Для этого проекта я использовал обе вершины и фрагментарные шейдеры для рендеринга моей сцены. Я предполагаю, что цвет, вычисленный и возвращенный фрагментарным шейдером, представляет собой вектор из 4 поплавков (по одному на компонент RGBA), принадлежащий к «непрерывному» [0, 1] внутреннему. Но как я могу получить его в своем файле на C++? Есть ли способ сделать это?

Я думал о вызове функции glReadPixels() только после того, как оказав свою сцену в буфер, установив аргумент формата в GL_RGBA, и тип данных пиксельных данных в GL_FLOAT. Но я чувствую, что значения, связанные с пикселями, которые мы читаем, уже были добавлены к целому числу, потому что числа, которые я наконец получил, соответствуют интервалу [0, 255], зажатому в [0, 1], без какого-либо повышения точности. Более пристальный взгляд на функции OpenGL усиливает эту идею: я думаю, что действительно есть что-то между рендерингом моей сцены и вызовом glReadPixels().

У вас есть представление о том, как я могу достичь своей цели?

+0

Существует 'glClampColor (...)', который может использоваться для изменения поведения по умолчанию для чтения из цветовых буферов. Это не особенно полезно, хотя в большинстве случаев, и то, что вы действительно хотите прежде всего, - это рисовать в буфере с плавающей точкой. –

+0

Дорогой Антон, большое спасибо за ваш ответ! Тем не менее, я боюсь, что этот совет не работает. Либо я устанавливаю параметр 'clamp' в' GL_TRUE', либо 'GL_FALSE', я получаю те же результаты, всего 256 возможных значений для каждого канала. У вас есть другая идея? – Mukyu

+0

Вы рендеритесь в фреймбуфер по умолчанию (т. Е. Задний буфер устройства). Если это так, цвета, вероятно, сохраняются 1 байт на канал. Вам нужно создать свой собственный фреймбуфер (см. 'GlGenFramebuffers',' glBindFramebuffer' и т. Д.) И связать с ним текстуру с плавающей точкой (с помощью 'glFramebufferTexture2D'). – GuyRT

ответ

0

Формат GL_RGBA, возвращаемый фрагментарным шейдером, хранит компоненты пикселей в 8-битных целых числах. Вы должны использовать формат с плавающей точкой, такой как GL_RGBA16F или GL_RGBA32F, где 16 и 32 являются глубинами для каждого компонента.

+1

Фрагментные шейдеры всегда выводят компоненты с плавающей запятой. Это действительно только после смешивания, что вещи преобразуются в беззнаковый нормализованный (фиксированный) формат, такой как 'GL_RGBA' для хранения. –

+0

Вы правы, я упрощен – user3556781

+0

Большое спасибо за ваш ответ, но для 'glReadPixels' нет' GL_RGBA16F', только 'GL_STENCIL_INDEX',' GL_DEPTH_COMPONENT' и 'GL_DEPTH_STENCIL', кроме' GL_RGBA' и других. Но три первых не имеют ничего общего с последним, не так ли? – Mukyu

Смежные вопросы