Opengl 计算着色器不修改3d纹理

Opengl 计算着色器不修改3d纹理,opengl,glsl,Opengl,Glsl,我想将3D纹理的初始化从CPU移动到GPU。作为测试,我编写了一个着色器,将所有体素设置为常量,但纹理根本没有修改。我如何让它工作 计算着色器: #version 430 layout(local_size_x=1, local_size_y=1, local_size_z=1) in; layout(r8, location = 0) uniform image3D volume; void main() { imageStore(volume, ivec3(gl_WorkGroupI

我想将3D纹理的初始化从CPU移动到GPU。作为测试,我编写了一个着色器,将所有体素设置为常量,但纹理根本没有修改。我如何让它工作

计算着色器:

#version 430

layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(r8, location = 0) uniform image3D volume;

void main()
{
  imageStore(volume, ivec3(gl_WorkGroupID), vec4(0));
}
调用:

glEnable(GL_TEXTURE_3D);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &volume_tid);
glBindTexture(GL_TEXTURE_3D, volume_tid);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, volume_dims[0], volume_dims[1], volume_dims[2], 0, GL_RED, GL_UNSIGNED_BYTE, voxels);

ShaderProgram computeVolumeShader;
computeVolumeShader.loadShader(GL_COMPUTE_SHADER, "compute_volume.glsl");
computeVolumeShader.link();
computeVolumeShader.use();
computeVolumeShader.uniform("volume", 0);
glBindImageTexture(0, volume_tid, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8);
glDispatchCompute(volume_dims[0], volume_dims[1], volume_dims[2]);
glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8);
computeVolumeShader.unUse();
glMemoryBarrier(GL_ALL_BARRIER_BITS);

注意:
glTexImage3D
中输入的体素包含CPU初始化的数据。

。因此,显然3D纹理必须绑定为分层,否则着色器无法修改w>0的任何uvw坐标

glBindImageTexture(0, volume_tid, 0, /*layered=*/GL_TRUE, 0, GL_READ_WRITE, GL_R8);

你试过使用真实的图像格式而不是
GL\u RED
?@Nicol当我使用
GL\u R8UI
时,即使没有计算着色器,我也看不到任何东西。我使用
sampler3D
进行渲染,这有区别吗?由于
GL\u RED
列在表1中,我认为可以使用它吗?你说的是
internalFormat
参数,对吧?但你不知道
GL\u RED
实际上意味着什么。它可能会为您提供
GL\u R8
。它可能会为您提供
GL\u R16
。如果不选择特定格式,则放弃了选择格式的权利。当您使用
GL_R8UI
时,它停止工作,因为您可能没有将像素传输设置为。@Nicol感谢您的解释。我将其更改为无符号规范化整数(问题中的更新代码),因为我喜欢在其他着色器中使用浮点数。不幸的是,它仍然不起作用。我为此损失了半天时间。非常感谢。我想我永远也想不到这一点。我只是花了一段疯狂的旅程。这是超级令人困惑的,因为它在Nvidia GM107上工作,但在GK110b(都是最新的驱动程序)上工作-/