计算着色器 - gl_GlobalInvocationID和local_size

时间:2018-03-17 12:11:25

标签: opengl compute-shader

在尝试实现一个天真的计算着色器,它将影响光线分配给一个群集时,我遇到了一个意外的(对于像我这样的菜鸟)行为:

我用glDispatchCompute(32,32,32)调用这个着色器;并且它应该为每个调用写一个[光计数器+ 8个索引]到" indices"缓冲。但是在调试时,我发现我对该缓冲区的写入在调用之间重叠,即使我使用了唯一的clusterId。我通过索引[outIndexStart]超过8和视觉闪烁的值来检测它。

根据文档,gl_GlobalInvocationID是gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID。但如果将所有本地大小设置为1,写入问题就会消失。为什么local_size会以这种方式影响此代码?我怎么能在这里选择它的价值?

{{1}}

1 个答案:

答案 0 :(得分:3)

让我们看看两个声明:

layout (local_size_x = 4, local_size_y = 4, local_size_z = 4) in;

const unsigned int clusterSize = 32;

这些说不同的事物。 local_size声明表示每个工作组将有4 * 4 * 4个调用,即64个。相比之下,您的clusterSize表示每个工作组只有32个调用。

如果您想解决此问题,请使用actual local size constant provided by the system

const unsigned int clusterSize = dot(gl_WorkGroupSize, uvec3(1, 1, 1));

你甚至可以这样做:

const uvec3 linearizeInvocation = uvec3{1, clusterSize, clusterSize * clusterSize};

...

unsigned int clusterId = dot(gl_GlobalInvocationID, linearizeInvocation);