HLSL中的奇数线程程序(计算着色器)

时间:2017-07-12 13:29:42

标签: unity3d hlsl compute-shader

我正在使用Unity在GPU上启动HLSL内核。我正在使用的函数是ComputeShader.Dispatch,但是如果你不熟悉Unity,这个函数只会调度GPU上的着色器,它会作为参数,你想要的线程组的大小x,y和z

这是我的问题,我有时想要运行这个内核很多次。

我可以用奇怪的大小来调用Dispatch,但这样做意味着定义我的内核就像[numthreads(1,1,1)]一样,因为它是无效的。

如何管理线程以处理奇怪的纹理或其他不规则的形状?

非常感谢

1 个答案:

答案 0 :(得分:1)

执行此任务的标准方法是确保您不会执行越界读/写操作。

所以,让我们说你的小组数是

[numthreads(8,8,1)]

在任何情况下,即使您的纹理大小不是奇数,也不是8的倍数(在每个维度中),您也可以发生这种情况。

现在假设您要处理18 * 9

的纹理

您需要在每个维度中调度足够的线程以至少覆盖整个纹理:

X = 18/8(2.25),所以你需要3组(处理24个像素) Y = 9/8(1.125),你需要2组

所以你会把调度称为 context.Dispatch(3,2,1)

在计算着色器中,执行此操作的标准方法是在超出范围时进行早期返回。

Texture2D texture2d <string uiname="Texture";>;

uint Width;
uint Height;

[numthreads(8,8,1)]
void CS(uint3 tid : SV_DispatchThreadID)
{
    if (tid.x >= Width || tid.y >= Height)
        return;

    //Perform your processing
}

您需要将纹理大小发送到width / height参数,并且着色器不会处理纹理之外的任何内容。