Как прочитать весь диапазон 32-битной целочисленной текстуры в GLSL

Я успешно загружаю и загружаю данные в целочисленную текстуру с R32UI в качестве внутреннего формата. Пишу текстурой 1000x600. Я задаю каждому пикселю уникальное значение (x + y * высота). При обратном чтении текстуры значения верны.

Проблема в шейдере / рендеринге. При использовании «texture ()» в «usampler2D» диапазон [0 - 255] расширяется до [0 - 2 ^ 32-1]. Похоже, что к значению текселя применяется модуль 256, затем делится на 256, а затем умножается на 2 ^ 32-1.

Визуальный:

введите описание изображения здесь

Фрагментный шейдер

#version 430

in vec2 gTextCoord;

layout(binding = 0) uniform usampler2D uInputImg;

out vec4 FragColor;

void main() 
{ 
    FragColor = vec4(vec3(texture(uInputImg, gTextCoord).rgb) / 4294967295.0, 1);
}

Загрузка:

int id = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
GL11.glTexImage2D(
    GL11.GL_TEXTURE_2D, 
    0, 
    GL30.GL_R32UI, 
    width, 
    height, 
    0, 
    GL30.GL_RED_INTEGER, 
    GL11.GL_UNSIGNED_INT, 
    data);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

Обвязка:

GL13.glActiveTexture(GL13.GL_TEXTURE0 + binding);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);

Я хотел бы получить значение, которое я повлиял на каждый тексель. Является ли это возможным ? Если да, то что мне не хватает? Если нет, то что такое блокирование и какие есть альтернативы?

Спасибо.


person agrum    schedule 16.04.2015    source источник
comment
Какие текстурные фильтры вы используете? Для целочисленных текстур необходимо использовать GL_NEAREST.   -  person derhass    schedule 19.04.2015
comment
Я пользовался линейным, но два дня назад перешел на ближайший. Получил тот же результат, но мне повезло, что текстура и буфер кадра 1: 1.   -  person agrum    schedule 20.04.2015


Ответы (1)


Думаю, проблема в точности с плавающей запятой.

В основном вы используете очень большое число с плавающей запятой (4 миллиарда) в делении и ожидаете в результате очень маленькое (0-1). Но большой поплавок настолько неточен по сравнению с диапазоном (0–1), что полученный результат - просто шум.

Что вам нужно сделать, так это приблизить эти два диапазона. Вместо этого вы можете использовать 16-битную текстуру int или разделить образец текстуры целочисленным делением перед преобразованием его в float (а затем разделить на меньшее float).

person Jerem    schedule 16.04.2015
comment
Если я применяю горизонтальный градиент к своей текстуре (левый пиксель 0, правый пиксель 255), визуально получается идеальный градиент. Тем не менее, все тот же фрагментный шейдер. Я делю «texture ()» на 4 миллиарда, и это дает мне хороший диапазон [0, 1]. Попробую с R16UI. - person agrum; 17.04.2015
comment
Я думаю, что работа с горизонтальным градиентом - это просто совпадение, вы просто отбираете сэмплы, кратные приведенному выше шаблону шума, поэтому, похоже, он работает. - person Jerem; 17.04.2015