【问题标题】:Compute shader not modifying 3d texture计算着色器不修改 3d 纹理
【发布时间】:2013-06-12 07:09:43
【问题描述】:

我想将我的 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);

注意:voxels 馈入glTexImage3D 包含 CPU 初始化数据。

【问题讨论】:

  • 你试过用真实图片格式代替GL_RED吗?
  • @Nicol 当我使用GL_R8UI 时,即使没有计算着色器,我也看不到任何东西。我使用sampler3D 进行渲染,这有什么不同吗?既然GL_RED在表1中列出了here,我觉得可以用吗?你说的是internalFormat 参数,对吧?
  • 但你不知道GL_RED 的真正含义。它可能会给你GL_R8。它可能会给你GL_R16。当您不选择特定格式时,您就放弃了选择格式的权利。当您使用 GL_R8UI 时它停止工作,因为您可能没有将像素传输设置为 upload integral data instead of normalized floats
  • @Nicol 谢谢你的解释。我将其更改为无符号归一化整数(问题中的更新代码),因为我喜欢在其他着色器中使用浮点数。不幸的是,它仍然不起作用。

标签: opengl glsl


【解决方案1】:

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

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

成功了。

【讨论】:

  • 我为此浪费了半天时间。谢谢!!!我想我永远也想不通。
  • 刚刚也经历了一次疯狂的旅行。这非常令人困惑,因为它确实适用于 Nvidia GM107,但不适用于 GK110b(均为最新驱动程序)。 :-/
猜你喜欢
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-27
  • 1970-01-01
  • 2015-03-02
  • 2019-02-03
相关资源
最近更新 更多