Доступ к 3D массиву в фрагментном шейдере - PullRequest
3 голосов
/ 10 мая 2019

Я пытаюсь предоставить доступ к 3-мерному массиву скалярных данных для фрагментного шейдера из программы Python, использующей PyOpenGL.

В фрагментном шейдере я объявляю униформу трехмерного сэмплера

uniform sampler3D vol;

и в программе Python у меня есть следующий код для настройки скалярной 3d текстуры

vol = numpy.random.rand(3, 3, 3).astype(np.float32)
texture = glGenTextures(1)
glUniform1i(glGetUniformLocation(program, "vol"), 0)
glActiveTexture(GL_TEXTURE0 + 0)
glBindTexture(GL_TEXTURE_3D, texture)
glTexImage3D(GL_TEXTURE_3D, 0, GL_RED, 3, 3, 3, 0, GL_RED, GL_FLOAT, vol)
glEnable(GL_TEXTURE_3D)

Однако, независимо от того, откуда из сэмплера я беру значения, например

color = texture(vol, vec3(0, 0, 0));

кажется, что я всегда получаю черный (0, 0, 0).

Что я делаю не так?

Я знаю, что базовая настройка моего фрагментного шейдера работает, т.е. если я пишу color = vec3(1, 0, 0), я получаю красные пиксели.

Я также знаю, что нет ошибок OpenGL, потому что я запускаю программу с опцией -glerror, обработанной glutInit(), что приводитв ошибки OpenGL, переводимые в исключения Python.

Ответы [ 2 ]

2 голосов
/ 10 мая 2019

Это потому, что ваш GL_RED формат текстуры ограничен диапазоном <0,1> !!!

Чтобы исправить это, вам нужно использовать нефиксированный формат текстуры или отключить фиксацию ... Вот примеры, которые работают над моими реализациями GL:

здесь форматы извлекаются из обоих:

glTexImage3D(GL_TEXTURE_3D, 0, GL_R16F, xs,ys,zs, 0, GL_RED, GL_FLOAT, dat);

glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, size, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pdata);

Для скалярных данных я бы использовал первый вариант. Есть больше форматов, которые не зажаты, просто попробуйте и посмотрите ...

Я никогда не использовал отключение функции фиксации, но где-то видел этот код при исследовании подобных проблем (не уверен, работает ли он):

glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE);
glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FALSE);
glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE);

Теоретически вы можете использовать любой формат текстур ...

Для проверки вы можете использовать это:

Также я не вижу никаких параметров набора текстур. Я бы ожидал что-то вроде этого:

glBindTexture(GL_TEXTURE_3D,txrvol);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);

, чтобы избежать неправильной интерполяции ваших данных из-за неточных координат текстуры ...

1 голос
/ 11 мая 2019

Я выяснил проблему: очевидно, что GL_TEXTURE_3D по умолчанию имеет отображение, я предоставил только уровень 0, и (насколько я не уверен в этом) выбран другой уровень.Проблема решена с помощью glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0).

...