在片段着色器中访问3D数组 [英] Access to 3D array in fragment shader

查看:103
本文介绍了在片段着色器中访问3D数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用PyOpenGL从Python程序向标量着色器提供对标量数据的3维数组的访问.

I'm trying to provide access to a 3-dimensional array of scalar data to a fragment shader, from a Python program using PyOpenGL.

在片段着色器中,我声明了一个统一的3d采样器

In the fragment shader, I declare the a 3d sampler uniform

uniform sampler3D vol;

在Python程序中,我有以下代码来设置标量3d纹理

and in the Python program I have the following code to set up a scalar 3d texture

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)

但是,无论我从采样器的哪个位置获取值,例如

However, no matter where from the sampler I take values, e.g.

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

看来我总是得到黑色(0、0、0).

it appears that I always obtain black (0, 0, 0).

我在做什么错了?

我知道片段着色器的基本设置有效,即,如果我写color = vec3(1, 0, 0),我会得到红色像素.

I know that the basic setup of my fragment shader works, i.e. if I write color = vec3(1, 0, 0) I get red pixels.

我还知道没有OpenGL错误,因为我正在运行由glutInit()处理的选项-glerror的程序,这导致OpenGL错误被转换为Python异常.

I also know that there are no OpenGL errors, because I'm running the program with the option -glerror processed by glutInit(), which leads to OpenGL errors being translated into Python exceptions.

推荐答案

这是因为您的GL_RED纹理格式被固定到了<0,1> !!!

That is because your GL_RED texture format is clamped to range <0,1> !!!

要解决此问题,您需要使用非钳制纹理格式或禁用钳制...以下示例适用于我的GL实现:

To remedy you need to use non clamped texture format or disable clamping ... Here examples that are working on my GL implementations:

  • GPU ray casting (single pass) with 3d textures in spherical coordinates
  • GLSL back raytrace through 3D volume

此处是从两者中提取的格式:

here formats extracted from both:

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

对于标量数据,我将使用第一个选项.还有更多格式没有被限制,只是尝试看看...

For scalar data I would use the first option. There are more formats that are not clamped just try and see...

从未使用禁用钳位功能,但是在研究类似问题(不确定是否可行)时看到了这段代码:

I have never used the disabling of clamping feature but saw this code somewhere while researching similar issues (not sure if it works):

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

理论上讲,您可以使用任何纹理格式...

With that theoretically you could use any texture format...

要验证您可以使用此功能,

To verify you can use this:

我也看不到纹理集的任何参数.我希望像这样:

Also I do not see any parameters of the texture set. I would expect something like this:

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

避免插值弄乱您的数据以获得不精确的纹理坐标...

to avoid interpolation messing your data for non exact texture coordinates ...

这篇关于在片段着色器中访问3D数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆