Python 在片段着色器中访问3D阵列

Python 在片段着色器中访问3D阵列,python,opengl,glsl,fragment-shader,Python,Opengl,Glsl,Fragment Shader,我试图通过使用PyOpenGL的Python程序向片段着色器提供对标量数据的三维数组的访问 在片段着色器中,我声明了一个3d采样器 uniform sampler3D vol; 在Python程序中,我有以下代码来设置标量3d纹理 vol = numpy.random.rand(3, 3, 3).astype(np.float32) texture = glGenTextures(1) glUniform1i(glGetUniformLocation(program, "vol"), 0) g

我试图通过使用PyOpenGL的Python程序向片段着色器提供对标量数据的三维数组的访问

在片段着色器中,我声明了一个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错误,因为我正在运行由
glutInit()
处理的选项
-glerror
,这导致OpenGL错误被转换为Python异常。

这是因为
glu RED
纹理格式被钳制到
范围

要解决此问题,您需要使用非钳制纹理格式或禁用钳制。。。以下是我的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);
对于标量数据,我将使用第一个选项。还有更多的格式不是钳制的,只是试试看

我从未使用过禁用夹紧功能,但在研究类似问题时在某处看到了此代码(不确定是否有效):

理论上你可以使用任何纹理格式

要验证您是否可以使用此选项:

我也没有看到纹理集的任何参数。我希望这样:

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);

为了避免插值对非精确纹理坐标的数据造成混乱…

我解决了问题:显然,默认情况下,GL_texture_3D是mipmapped,我只提供了级别0,并且(我不清楚)选择了另一个级别。问题是通过
glTexParameteri(GL\u TEXTURE\u 3D,GL\u TEXTURE\u MAX\u LEVEL,0)解决的

禁用夹紧的可能性当然很有趣,但我不明白这是怎么回事:我传递的数据是间隔[0,1]中的随机值,颜色成分在同一范围内指定…。。@A.Donda您是否验证生成的纹理不仅仅是零?您还检查了GLSL编译和链接日志中的错误吗?您是否在所有3个轴上都尝试了最近的
glu
过滤?所有这些都可能导致错误的输出…我找到了答案,看看我自己的答案。该解决方案向我建议,纹理不是将非图像数据获取到片段着色器中的最佳方式。你能建议一个更好的方法吗?我从4.3中看到,支持多维数组制服…这很奇怪,因为我以这种方式传递非纹理数据,没有
glTexParameteri(GL\u texture\u 3D,GL\u texture\u MAX\u LEVEL,0)
。可能是特定于驱动程序的,我使用的是nVidia gfx卡,甚至可能是特定于环境的,因为您使用的是不同的语言,还使用LIB(不仅仅是GL/GLSL),所以他们可能会自行更改一些设置。顺便说一句,
-glerror
选项仅处理GL错误,还是同时处理GLSL错误?我只是好奇我没有用GLUT@Spektre,我有一辆GeForce GTX 1060,配备官方驾驶员是的,它还报告GLSL编译错误。谢谢你的帮助!
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);