c++ - OpenGL Compute Shader 渲染到 3D 纹理似乎没有做任何事情
问题描述
我编写了一个小着色器来设置 3D 体积的颜色值。
#version 430
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout (r8, binding = 0) uniform image3D destTex;
void main()
{
imageStore(destTex, ivec3(gl_GlobalInvocationID.xyz), vec4(0.33, 0, 1.0, 0.5));
}
它编译和链接没有错误。
创建卷并像这样调度计算着色器
generateShader->use();
glEnable(GL_TEXTURE_3D);
glGenTextures(1, &densityTex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, densityTex);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_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);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, chunksize + 1, chunksize + 1, chunksize + 1, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glBindImageTexture(0, densityTex, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R8);
glDispatchCompute(chunksize + 1, chunksize + 1, chunksize + 1);
// make sure writing to image has finished before read
glMemoryBarrier(GL_ALL_BARRIER_BITS);
asdf(0); //Here I print the content of my texture.
//Strangely it contains the values 205 everywhere and independent of what I set in the shader: vec4(0.33, 0, 1.0, 0.5)
glBindTexture(GL_TEXTURE_3D, 0);
打印图像数据的方法如下:
void Chunk::asdf(int slice) {
GLubyte* image;
image = new GLubyte[(chunksize + 1) * (chunksize + 1) * (chunksize + 1)];
glGetTexImage(GL_TEXTURE_3D, 0, GL_R8, GL_UNSIGNED_BYTE, image);
std::cout << "Reading texels" << std::endl;
for (int i = 0; i < (chunksize + 1); i++) {
for (int j = 0; j < (chunksize + 1); j++) {
int start = (((chunksize + 1) * (chunksize + 1) * slice) + (i * (chunksize + 1)) + j);
std::cout << "Texel at " << i << " " << j << " " << slice << " has color " << (float)image[start] << std::endl;
}
}
delete[] image;
}
这段代码有什么问题?在 GPU 上设置数据后,我需要一些特殊的方法来检索数据吗?另外,我不太明白如何在 GPU 中设置该值,因为在使用 imageStore 时,必须设置一个 vec4 值,但纹理只包含一个红色通道(如果我使用 RGBA 格式则没有区别)
编辑: 事实证明我没有解决问题。我为自己编写了一个着色器来将我的 3D 纹理的内容渲染到屏幕上。似乎我的打印功能(asdf)没有得到正确的纹理值,因为如果渲染到屏幕上,颜色值是不同的
如您所见,它看起来仍然不太正确,但我认为这是另一个问题的主题?
解决方案
glGetTexImage(GL_TEXTURE_3D, 0, GL_R8, GL_UNSIGNED_BYTE, image);
这不会将任何数据复制到image
,而只会产生GL_INVALID_ENUM
错误。GL_R8
只是不是一个有效的format
参数。您很可能是指GL_RED
这里(请注意,这与您使用glTexImage3D
的format
参数相同。GL_R8
只是 的枚举internalFormat
,并且它与您在 OpenGL 客户端看到的任何内容都无关,另请参阅此问题)。
作为一个更普遍的建议,我真的建议大家在开发过程中使用OpenGL 的调试输出功能,这样就不会忽视任何 OpenGL 错误。
推荐阅读
- python - 如何从具有帐户密钥的api获取请求
- java - JasperSoft 报告未在 java jar 文件中运行
- mysql - 如何使用 SQL 加入 postmeta 表并获取自定义字段日期之前的帖子
- azure - 我想使用 Azure 数据工厂从谷歌仪表板获取数据
- android - 如何以编程方式查找安装在 Android 手机中的社交共享应用程序列表?
- javascript - 如何匹配在字符串末尾终止的子字符串?
- spring - 如果消息失败并由 AfterRollbackProcessor 处理,如何在 Spring Kafka 中提交偏移量
- asp.net-mvc - .net core中DICOM图像的数据解析和发送
- google-app-engine - 具有独立 FE 和 BE 服务的 Google Cloud
- ios - 发送 Http Post 请求在 IoS 中返回 500 状态码