计算着色器中的图像存储到深度纹理
imageStore in compute shader to depth texture
我一辈子都无法锻炼如何在计算着色器中使用 imageStore
写入深度纹理,我已经对照几个示例检查了我在做什么(例如 this and this),但我仍然找不到错误。我可以将纹理作为帧缓冲区写入,并且在调用 glTexImage2D()
时,但出于某种原因,执行此计算着色器不会影响命名纹理(我正在通过渲染到屏幕进行检查)。
如果上述情况适用,您可以直接跳到下面接受的答案。
下面我以更清晰的格式提取了相关代码,它是一个更大项目的一部分,该项目将常见的 GL 操作包装在 类 中,并进行了一系列错误检查。但我自己写了 the project,所以我知道什么叫什么不叫。
我有我的计算着色器,这很简单,它应该将 0.5f
写入每个像素,(在我的调试渲染中将输出为青色)。
#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)
最后我使用
启动着色器
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);
我尝试了一些调整,但无论我做什么,纹理仍然在渲染,但是我首先在初始化时配置它。
没有发生 GL 错误(我有一个预处理器宏,我用它包装了所有 gl fn),虽然我实际执行的代码比上面提供的代码更抽象,但我相信没有导致 vars 的错误lost/changed.
I can't for the life of me workout how to write to a (depth) texture using imageStore within a compute shader
那是因为你不能。
Image Load/Store can only be used to read/write color image formats。深度 and/or 模板格式无法使用它。
不,您不能使用 glCopyImageSubData
在彩色图像和深度图像之间进行复制。计算着色器可以读取 depth/stencil 格式,但只能通过 sampler
s,不能通过 image
变量。
我一辈子都无法锻炼如何在计算着色器中使用 imageStore
写入深度纹理,我已经对照几个示例检查了我在做什么(例如 this and this),但我仍然找不到错误。我可以将纹理作为帧缓冲区写入,并且在调用 glTexImage2D()
时,但出于某种原因,执行此计算着色器不会影响命名纹理(我正在通过渲染到屏幕进行检查)。
如果上述情况适用,您可以直接跳到下面接受的答案。
下面我以更清晰的格式提取了相关代码,它是一个更大项目的一部分,该项目将常见的 GL 操作包装在 类 中,并进行了一系列错误检查。但我自己写了 the project,所以我知道什么叫什么不叫。
我有我的计算着色器,这很简单,它应该将 0.5f
写入每个像素,(在我的调试渲染中将输出为青色)。
#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)
最后我使用
启动着色器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);
我尝试了一些调整,但无论我做什么,纹理仍然在渲染,但是我首先在初始化时配置它。
没有发生 GL 错误(我有一个预处理器宏,我用它包装了所有 gl fn),虽然我实际执行的代码比上面提供的代码更抽象,但我相信没有导致 vars 的错误lost/changed.
I can't for the life of me workout how to write to a (depth) texture using imageStore within a compute shader
那是因为你不能。
Image Load/Store can only be used to read/write color image formats。深度 and/or 模板格式无法使用它。
不,您不能使用 glCopyImageSubData
在彩色图像和深度图像之间进行复制。计算着色器可以读取 depth/stencil 格式,但只能通过 sampler
s,不能通过 image
变量。