问题描述
我一生都无法锻炼如何在计算着色器中使用imageStore
写入深度纹理,我已经针对几个示例检查了我正在做的事情(例如和这),但我仍然无法找出问题所在.我可以在调用glTexImage2D()
时将其作为Framebuffer写入纹理,但是由于某种原因,执行此计算着色器不会影响命名的纹理(我正在通过渲染到屏幕进行检查).
I can't for the life of me workout how to write to a depth texture using imageStore
within a compute shader, I've checked what I'm doing against several examples (e.g. this and this), but I still can't spot the fault. I can write to the texture as a Framebuffer, and when calling glTexImage2D()
, but for some reason executing this compute shader doesn't affect the named texture (which i'm checking via rendering to screen).
如果符合上述条件,您可以直接跳到下面接受的答案.
下面,我以更清晰的格式提取了相关代码,它是一个更大的项目的一部分,该项目将常见的GL操作包装在类中,并进行了一系列错误检查.但是我自己写了项目,所以我知道是什么,不是被呼叫.
Below I've extracted the relevant code in a clearer format, it's part of a much larger project, which wraps common GL operations in classes with a bunch of error checking. But I've written the project myself, so I know what is and isn't being called.
我有我的计算着色器,这非常简单,它应该向每个像素写入0.5f
(在我的调试渲染中,该输出将输出为青色).
I have my compute shader, this is very simple, it should write 0.5f
to every pixel, (which in my debugging render would output as cyan).
#version 430
layout(local_size_x=16,local_size_y=16) in;
uniform uvec2 _imageDimensions;
uniform layout (r32f) writeonly image2D _imageOut;
void main ()
{
if(gl_GlobalInvocationID.x<_imageDimensions.x
&&gl_GlobalInvocationID.y<_imageDimensions.y)
{
imageStore(_imageOut, ivec2(gl_GlobalInvocationID.xy), vec4(0.5f));
}
}
我使用创建纹理
glm::uvec2 shadowDims = glm::uvec2(4096);
GLuint shadowOut;
glGenTextures(1, &shadowOut);
glBindTexture(GL_TEXTURE_2D, shadowOut);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, shadowDims.x, shadowDims.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
我使用配置着色器
glUseProgram(computeShader)
//Dimensions
GLint location = glGetUniformLocation(computeShader, "_imageDimensions");
glUniform2uiv(location, 1, glm::value_ptr(shadowDims));
//Image unit
const int IMAGE_UNIT = 0;
location = glGetUniformLocation(computeShader, "_imageOut");
glUniform1iv(location , 1, &IMAGE_UNIT);
glUseProgram(0)
最后我用以下命令启动着色器
and finally I launch the shader with
glUseProgram(computeShader)
glBindImageTexture(IMAGE_UNIT, shadowOut, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32F);
//Split the image into work groups of size 16x16
glm::uvec2 launchConfig = shadowDims/ glm::uvec2(16) + glm::uvec2(1);
glDispatchCompute(launchConfig.x, launchConfig.y, 1);
//Synchronise written memory
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
我尝试了一些调整,但是无论我做什么,纹理仍会呈现,但是我首先在初始化时对其进行配置.
I've tried a few tweaks, but whatever I do, the texture remains rendering however I first configure it at initialisation.
没有发生GL错误(我有一个预处理器宏,将所有gl fn包装在其中),尽管我实际执行的代码比上面提供的代码抽象得多,但我相信不会有导致var丢失的错误/改变了.
There are no GL errors occurring (I have a preprocessor macro I wrap all gl fn's with), and although my actual executed code is more abstract than that provided above, i'm confident there's no bugs causing vars to be lost/changed.
推荐答案
那是因为您不能.
图像加载/存储只能用于读取/写入彩色图像格式.深度和/或模具格式不能使用它.
Image Load/Store can only be used to read/write color image formats. Depth and/or stencil formats cannot use it.
不,您不能使用glCopyImageSubData
在彩色和深度图像之间进行复制.计算着色器只能读取sampler
而不是image
变量,从而可以读取深度/模板格式.
And no, you cannot use glCopyImageSubData
to copy between color and depth images. Compute shaders can read depth/stencil formats, but only through sampler
s, not through image
variables.
这篇关于imageStore在计算着色器中以深度纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!