Opengl 慢速计算着色器,全局与本地工作组?

Opengl 慢速计算着色器,全局与本地工作组?,opengl,graphics,glsl,Opengl,Graphics,Glsl,我创建了这个简单的计算着色器,以通过3D纹理并将alpha值设置为大于0到1: #version 440 core layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; layout(binding = 0, RGBA8) uniform image3D voxelTexture; void main() { ivec3 pos = ivec3(gl_GlobalInvocationID); vec

我创建了这个简单的计算着色器,以通过3D纹理并将alpha值设置为大于0到1:

#version 440 core

layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(binding = 0, RGBA8) uniform image3D voxelTexture;

void main() {

    ivec3 pos = ivec3(gl_GlobalInvocationID);
    vec4 value = imageLoad(voxelTexture, pos);
    if(value.a > 0.0) {
        value.a = 1.0;
        imageStore(voxelTexture, pos, value);
    }
}
我使用纹理尺寸作为工作组计数调用它,大小=128:

opacityFixShader.bind();
glBindImageTexture(0, result.mID, 0, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA8);
glDispatchCompute(size, size, size);
opacityFixShader.unbind();
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
使用GTX 1080 Ti在RenderDoc中计时会导致3.722毫秒,这似乎太长了。我觉得我没有充分利用compute,我应该增加本地组大小还是什么

我觉得我没有充分利用compute,我应该增加本地组大小还是什么

当然可以。每个工作组中由实现定义的调用量将捆绑在一起,作为一个扭曲/波前/子组/您喜欢的任何调用,并在实际SIMD硬件单元上执行。出于所有实际目的,对于工作组的本地大小,您应该使用64的倍数,否则您将浪费大量潜在的GPU电源

您的工作负载将完全由内存访问控制,因此您还应该考虑优化访问以提高缓存效率。由于您使用3D纹理,我实际上建议您使用3D局部大小,如4x4x4或8x8x8,这样您就可以从您的GPU最可能用于内部存储3D纹理数据的3D数据组织中获益

旁注:

你确定吗。如果以后要从纹理中采样,则这将是错误的屏障

此外:

我已经创建了这个简单的计算着色器来遍历3D纹理并将alpha值设置为大于0到1


你为什么这么做?这可能是一个典型的X-Y问题。把整个计算过程都花在这上面首先可能是个坏主意,而且它永远不会很好地利用GPU的计算资源。此操作也可能在实际使用纹理的着色器中完成,并且实际上可能是免费的,因为该着色器也很可能由纹理访问的延迟控制。另一个需要考虑的问题是,你可以通过一些纹理过滤来访问纹理,并且即使在你的预处理之后仍然得到alpha值在0到1之间(但是也许你想要完全一样)。< /P>如果我使用8x8x8,这是否意味着我应该调用<代码> GLISTHCHCHEM(大小/ 8,大小/ 8,大小/ 8)< /代码>?我使用的是
glMemoryBarrier(GL\u SHADER\u IMAGE\u ACCESS\u BARRIER\u BIT)
,因为我在同一3D纹理上运行另一个计算着色器,这需要完成之前的工作,所以我认为这是正确的调用?alpha值主题是体素圆锥体跟踪的一部分,当使用alpha通道作为原子平均计数器时,这是一个常见问题,如
size/8
所述,将是最自然的方法,是的。“之后,我在同一3D纹理上运行另一个计算着色器,这需要完成之前的工作,”好吧,这不符合要求。如果你在第二个着色器中通过ima加载/存储访问纹理,那么它是正确的屏障,如果你将其作为纹理采样(正如我在回答中所写),则不是。啊,我的错,我应该澄清,是的,第二个计算着色器只执行加载/存储操作,因此它是正确的屏障。谢谢
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);