【发布时间】:2019-04-24 16:54:03
【问题描述】:
我无法在我的 GLSL 片段着色器中获取 sampler3D 值。
我正在用 GLSL 编写着色器,并希望将 sampler3D(3d 纹理)作为体积数据并进行体积渲染。但是,似乎我无法将 3d 纹理绑定到我的着色器的 sampler3D。 texture3D() 总是在着色器端返回 (0,0,0,0)。但在我的应用程序端,我可以使用 glGetTexImage 来获取数据。
应用端(dS是Shader类对象):
dS.use();
dS.setInt("volumeData", 0);
uint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_3D, texture);
float data[64];
for (int i = 0; i < 64; ++i) data[i] = 1.0f;
glTexImage3D(GL_TEXTURE_3D, 0, GL_R16F, 4, 4, 4, 0, GL_RED, GL_FLOAT, data);
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_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_3D, 0);
float read[64];
glBindTexture(GL_TEXTURE_3D, texture);
glGetTexImage(GL_TEXTURE_3D, 0, GL_RED, GL_FLOAT, read);
std::cout << read[0] << "," << read[63] << std::endl; // 1,1
glBindTexture(GL_TEXTURE_3D, 0);
// When drawing.
dS.use();
dS.setMat4("model", glm::mat4(1.0f));
dS.setMat4("view", view);
dS.setMat4("projection", projection);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, texture);
cube.draw();
顶点着色器
#version 330 core
// for snow rendering
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
片段着色器
#version 330
out vec4 FragColor;
uniform sampler3D volumeData;
void main()
{
ivec3 size = textureSize(volumeData, 0);
float c = texture3D(volumeData, vec3(0)).x;
if (size.x == 1)
FragColor = vec4(1.0, 0.0, c, 1.0);
else if (size.x > 2)
FragColor = vec4(0.0, 1.0, 0.0, 1.0);
else if (size.x == 0)
FragColor = vec4(0.0, 0.0, 1.0, 1.0);
else
FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
我只得到一个红色立方体,表示size.x == 1,texture3D返回0,预计size.x == 4,texture3D返回1.0
我对 2d 纹理使用了类似的方法,并且效果很好。所以我想我的着色器类是正确的。而且我还尝试在执行任何 3d 纹理操作之前添加 glEnable(GL_TEXTURE_3D)。
我不确定这是否有帮助:我使用 glfw-3.2.1 WIN64 并且很高兴。
【问题讨论】:
-
"如果 sampler3D 工作,那么至少 textureSize 不应该返回 (0,0,0)。" 除非是
textureSize坏了,而不是采样器。为什么不删除所有不需要的位并验证是否可以从纹理中获取数据? -
@NicolBolas,我添加了 textureSize,因为我尝试使用 texture3D 从纹理中获取数据,但失败了。所以我把textureSize和texture3D结合起来看是因为我用错了UVW坐标还是因为sampler3D错了。
-
当纹理中的值都相同时,没有正确或错误的纹理坐标。此外,
texture3D是一个旧函数;你应该只使用texture。 “它失败了”是什么意思?你得到了什么颜色? -
@NicolBolas,“失败”意味着 texture() 或 texture3D() 仅返回 (0,0,0,0)。然后我使用了textureSize(),发现大小总是(1,1,1)。所以我认为这是因为我无法将 3d 纹理绑定到这个统一的 sampler3D。
-
@NicolBolas,我解决了,我只是用GL_TEXTURE_2D设置了MIN和MAG过滤器,导致mipmap不完整。这真是一个愚蠢的错字。很抱歉浪费了您的时间。