OpenGL 3D纹理问题

4

我正在尝试在OpenGL中使用3D纹理来实现体积渲染。每个体素都有一个RGBA颜色值,并且目前被渲染为面向屏幕的四边形(用于测试目的)。但是,我似乎无法让采样器在着色器中给出颜色值。四边形始终呈黑色。当我更改着色器以生成颜色(基于xyz坐标)时,则可以正常工作。以下是我使用的代码加载纹理:

glGenTextures(1, &tex3D);
glBindTexture(GL_TEXTURE_3D, tex3D);
unsigned int colours[8];

colours[0] = Colour::AsBytes<unsigned int>(Colour::Blue);
colours[1] = Colour::AsBytes<unsigned int>(Colour::Red);
colours[2] = Colour::AsBytes<unsigned int>(Colour::Green);
colours[3] = Colour::AsBytes<unsigned int>(Colour::Magenta);
colours[4] = Colour::AsBytes<unsigned int>(Colour::Cyan);
colours[5] = Colour::AsBytes<unsigned int>(Colour::Yellow);
colours[6] = Colour::AsBytes<unsigned int>(Colour::White);
colours[7] = Colour::AsBytes<unsigned int>(Colour::Black);

glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colours);

颜色数组包含正确的数据,即前四个字节的值为0,0,255,255表示蓝色。在渲染之前,我将纹理绑定到第二个纹理单元,代码如下:

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_3D, tex3D);

使用以下代码进行渲染:

shaders["DVR"]->Use();
shaders["DVR"]->Uniforms["volTex"].SetValue(1); 
shaders["DVR"]->Uniforms["World"].SetValue(Mat4(vl_one));
shaders["DVR"]->Uniforms["viewProj"].SetValue(cam->GetViewTransform() * cam->GetProjectionMatrix());

QuadDrawer::DrawQuads(8);

在之前我曾经使用这些类来设置着色器参数,它们运行良好。quaddrawer绘制八个实例化的四边形。顶点着色器代码如下:

#version 330

layout(location = 0) in vec2 position;
layout(location = 1) in vec2 texCoord;

uniform sampler3D volTex;
ivec3 size = ivec3(2, 2, 2);
uniform mat4 World; 
uniform mat4 viewProj;

smooth out vec4 colour;

void main()
{
    vec3 texCoord3D;

    int num = gl_InstanceID;

    texCoord3D.x = num % size.x;
    texCoord3D.y = (num / size.x) % size.y;
    texCoord3D.z = (num / (size.x * size.y));

    texCoord3D /= size;
    texCoord3D *= 2.0;
    texCoord3D -= 1.0;

    colour = texture(volTex, texCoord3D);
    //colour = vec4(texCoord3D, 1.0);   

    gl_Position = viewProj * World * vec4(texCoord3D, 1.0) + (vec4(position.x, position.y, 0.0, 0.0) * 0.05);

}

取消注释设置颜色值等于纹理坐标的行是有效的,可以使四边形变为彩色。片元着色器非常简单:
#version 330

smooth in vec4 colour;
out vec4 outColour;

void main()
{
    outColour = colour;
}

所以我的问题是,我做错了什么,为什么采样器从3D纹理中没有得到任何颜色值?
【编辑】 想通了,但无法自我解答(新用户):
在我发布这篇文章的同时,我就想通了,我会把答案放上来帮助其他人(这不是一个特定的3D纹理问题,我之前也遇到过这个问题)。我没有为纹理生成mipmaps,并且默认的放大/缩小过滤器也没有设置为GL_LINEAR或GL_NEAREST。砰!没有纹理。对于2D纹理也会发生相同的事情。

1
我已将您的答案移至维基答案,如果您想接受它。感谢您发布您的解决方案。 - Tim
为了使纹理正确渲染,它必须是“完整的”(包括纹理图像和缩小/放大过滤器)。请参考OpenGL规范中的“纹理完整性”。 - mbaitoff
1个回答

3
当我发布这篇文章的时候,我就已经想到了答案,我会把答案贴上来帮助其他遇到同样问题的人(这不是一个特定的3D纹理问题,而且我之前也犯过这个错误,呃!)。我没有为纹理生成mipmaps,并且默认的放大/缩小过滤器也没有设置为GL_LINEAR或GL_NEAREST。嘭!没有纹理。2D纹理也会发生同样的事情。

我其实也遇到了同样的问题。我在使用GL_TEXTURE_2D创建3D纹理时不小心创建了mipmaps,导致纹理变成了黑色。 - Danvil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接