OpenGL 3D纹理“闪耀”

时间:2015-08-04 13:36:04

标签: opengl textures glsl

出于测试目的,我想显示3D纹理的第一个切片。但是,似乎还显示了其他切片。

我的顶点着色器:

#version 130

attribute vec4 position;

varying vec2 texcoord;

void main()
{
    gl_Position = position;
    texcoord = position.xy * vec2(0.5) + vec2(0.5);
}

片段着色器:

#version 130

uniform sampler3D textures[1];

varying vec2 texcoord;

void main()
{
    gl_FragColor = texture3D(textures[0], vec3(texcoord.x, texcoord.y, 0));
}

我使用

绑定我的C ++代码中的纹理
     glTexImage3D(GL_TEXTURE_3D,0,GL_LUMINANCE,rows-1,cols-1,dep-  1,0,GL_RED,GL_UNSIGNED_SHORT, vol.data());

enter image description here

这是它的样子;整个头部不应该是可见的,只有它的上半部分。

1 个答案:

答案 0 :(得分:3)

当您对GL_LINEAR和/或GL_TEXTURE_MIN_FILTER纹理参数使用线性过滤(值GL_TEXTURE_MAG_FILTER)时,样本的值通常由最接近您的两个切片确定第三个纹理坐标。

如果第三维中3D纹理的大小为d,则纹理坐标空间中第一个切片的位置为0.5 / d。如果您在纹理坐标空间中拍摄具有一定厚度的每个切片,则这是最容易理解的。由于您有d个切片,并且纹理坐标范围为[0.0, 1.0],因此每个切片的厚度为1.0 / d。因此,第一个切片从0.0延伸到1.0 / d,其中心位于0.5 / d

当您使用0.0作为第3个纹理坐标时,这不是第一个切片的中心,线性采样开始起作用。由于0.0位于纹理的边缘,因此环绕模式变得至关重要。默认的换行模式为GL_REPEAT,这意味着边缘处的采样就像重复纹理一样。使用此设置,第一个切片的邻居是最后一个切片,纹理坐标0.0恰好位于第一个切片和最后一个切片之间的中间位置。

结果是纹理坐标0.0的线性采样将为您提供第一个切片和最后一个切片的平均值。

虽然GL_REPEAT是包装模式的默认设置,但它很少是您想要的,除非您的纹理确实包含重复模式。在这种情况下,它肯定不是正确的设置。你需要的是:

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