我正在使用计算着色器,并且有一种奇怪的行为,我实在无法解释。我想知道你是否可以帮我弄清楚。
这是计算着色器的次优使用,但我想了解发生了什么......
我有一个64x64纹理,我想从我的着色器的单个调用中写出4个水平像素。因此,我使用以下着色器
调用vkCmdDispatch( 64 / 4, 1, 1 );
#version 450
layout (local_size_x = 1, local_size_y = 1) in;
layout (binding = 0, rgba8) uniform writeonly image2D resultImage;
void main()
{
const uint texPosX = gl_GlobalInvocationID.x * 4;
const uint texPosY = gl_GlobalInvocationID.y;
imageStore( resultImage, ivec2( texPosX + 0, texPosY ), vec4( 1.0f, 0.0f, 0.0f, 1.0f) );
imageStore( resultImage, ivec2( texPosX + 1, texPosY ), vec4( 0.0f, 1.0f, 0.0f, 1.0f) );
imageStore( resultImage, ivec2( texPosX + 2, texPosY ), vec4( 0.0f, 0.0f, 1.0f, 1.0f) );
imageStore( resultImage, ivec2( texPosX + 3, texPosY ), vec4( 1.0f, 1.0f, 1.0f, 1.0f) );
}
我希望这会在一行中写出4个像素(红绿蓝和白色)。我希望最终的图像看起来像垂直线条,图案类似{红色,绿色,蓝色,白色,红色,绿色,蓝色,白色......}
我得到的是垂直线条,图案为{红色,绿色,蓝色,白色,绿色,蓝色,白色,红色,蓝色等...... }所以它看起来像那里是价值观中的一个转变。
如果我改变了我将texPosX计算为const uint texPosX = gl_GlobalInvocationID.x * 5;
的方式(写入 5 像素而不是4),我会得到预期的结果。如果我像这样添加第五个写
imageStore( resultImage, ivec2( texPosX + 4, texPosY ), vec4( 1.0f, 1.0f, 1.0f, 1.0f) ); // purple color at fifth pixel
结果与之前完全相同,这意味着最后一次写入是"不可见"。我的图像真的是64x64,但似乎每次调用的像素数是5,最后一个不可见......据我所知,64/4 = 16个工作组,64/16 = 4每个工作组的像素数(因为我的本地组大小为1)。
我肯定错过了一些显而易见的东西,但我不知道它是什么。我以为我理解全局/本地工作组的大小,但似乎并非如此......
非常感谢你的帮助!