我正在尝试通过使用PyOpenGL的Python程序提供对标量数据的3维数组的访问,以实现片段着色器。
在片段着色器中,我声明了一个统一的3d采样器
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异常。
答案 0 :(得分:2)
这是因为您的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 :(得分:1)
我发现了问题:显然GL_TEXTURE_3D默认情况下是mipmapped的,我只提供了级别0,并且(我不清楚)选择了另一个级别。 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0)
解决了这个问题。