opengl - 在计算着色器中写入空 3D 纹理

标签 opengl glsl volume-rendering

我正在尝试创建一个空的 3D 纹理,其尺寸和格式在运行时加载。然后我想修改该纹理的值,然后使用光线追踪器对其进行体积渲染。我知道我的渲染功能工作正常,因为我可以毫无问题地渲染尺寸和格式所来自的体积。空卷也会呈现,但我无法向其中写入任何数据,因此它一直都是白色的。

//My function that creates the blank texture initially
//Its part of a larger class that reads in a populated volume and a transfer function,
//I'm just initialising it in this way so it is identical to the other volume, but empty
GLuint Texture3D::GenerateBlankTexture(VolumeDataset volume)
{
GLuint tex;

glEnable(GL_TEXTURE_3D);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_3D, tex);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
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);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);


// Reverses endianness in copy
if (!volume.littleEndian)
    glPixelStoref(GL_UNPACK_SWAP_BYTES, true);

if (volume.elementType == "MET_UCHAR")
{
    //          texture format, ?, channels, dimensions,                        ?, pixel format, data type, data
    glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, volume.xRes, volume.yRes, volume.zRes, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
    glBindImageTexture(0, tex, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R8);
}

else if (volume.elementType == "SHORT")
{
    glTexImage3D(GL_TEXTURE_3D, 0, GL_R16F, volume.xRes, volume.yRes, volume.zRes, 0, GL_RED, GL_UNSIGNED_SHORT, NULL);
    glBindImageTexture(0, tex, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R16F);
}
else if (volume.elementType == "FLOAT")
{
    glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, volume.xRes, volume.yRes, volume.zRes, 0, GL_RED, GL_FLOAT, NULL);
    glBindImageTexture(0, tex, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32F);
}
glPixelStoref(GL_UNPACK_SWAP_BYTES, false);

GLenum err = glGetError();

glBindTexture(GL_TEXTURE_3D, 0);

return tex;
}

创建体积后,我将其读入显示函数中的计算着色器:

glUseProgram(Compute3DShaderID);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, tex_output);

glDispatchCompute((GLuint)volume.xRes/4, (GLuint)volume.yRes/4, (GLuint)volume.zRes/4);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

在我的着色器中,我要做的就是根据颜色在体积中的位置更改颜色:

#version 430
layout (local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
layout (r8, binding = 0) uniform image3D tex_output;

void main()
{
    ivec3 dims = imageSize (tex_output);
    ivec3 pixel_coords = ivec3(gl_GlobalInvocationID.xyz);

    vec4 pixel = vec4(pixel_coords.x/dims.x, pixel_coords.y/dims.y, pixel_coords.y/dims.y, 1.0);


    imageStore (tex_output, pixel_coords, pixel);
}

我确信该错误与写入访问被拒绝有关,但我无法准确指出它是什么。

注意:我使用 GL_RED 等,因为这是体积数据,这就是我在体积渲染器的其余部分中使用它的方式,并且它似乎工作正常。

最佳答案

所以,愚蠢的错误。事实证明我的着色器工作正常。我没有预料到的是,我试图写入体积的值在我的传递函数上映射为白色。一旦我拉出了传递函数的原理图,并使用应该可以正常工作的值进行测试,我就得到了实际的颜色。

以后任何人看到这个问题,如果你的代码不起作用,它应该如下所示:

创建纹理,并使用 glTexImage3D 将其设置为图像纹理。然后,当您希望使用它时,调用 glBindImageTexture 并绘制,确保将“layered”设置为 GL_TRUE,因为它是 3D 纹理。还要确保您绑定(bind)到正确的绑定(bind)(在上面的代码中,我绑定(bind)到 0,但我后来添加了绑定(bind)到 1 的第二个纹理),如果您要使用第二组纹理和着色器,请取消绑定(bind).

如果您遇到问题,请将其设置为计算中的每次迭代都会为最终值添加 0.01,以便您可以实时看到颜色变化。

关于opengl - 在计算着色器中写入空 3D 纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45282300/

相关文章:

opengl - 在openGL中重新编译着色器

c++ - glBindImageTexture 的 GL_TEXTURE_BINDING_2D?

c++ - 如何使用 GLSL 在体积渲染中进行混合?

python - OpenGL utf-8 字符串渲染

java - OpenGL:设置位置而不是翻译?

opengl - OpenGL 有预着色器吗?

java - OpenGL - 特定深度的像素颜色

c++ - 让纹理在 OpenGL 3.2 中工作

algorithm - 计算体射线转换中的梯度

hadoop - Hadoop 中的 JoGL?用于图形的 Hadoop?