[unity] understanding of ThreadGroup and numthreads in computeshader

Time:2021-7-30

Today, I encountered a magical phenomenon. I set up a100 * 100Then use computeshader to fill it with some colors, but the result has a black edge.

The code is as follows:

_renderTexture = new RenderTexture(100, 100, 24);
        _renderTexture.enableRandomWrite = true;

_renderTexture.Create();
        
shader.Dispatch(0, _renderTexture.width / 8, _renderTexture.height / 8, 1);
[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    Result[id.xy] = float4(float3(id) / 100, 1);
}

Finally, the image we get is like this. You can see that there is a black edge.

[unity] understanding of ThreadGroup and numthreads in computeshader

I tried if I wouldshader.Dispatch(0, _renderTexture.width / 8, _renderTexture.height / 8, 1);Replace 8 with 9.

shader.Dispatch(0, _renderTexture.width / 9, _renderTexture.height / 9, 1);

You will find that the black edge becomes wider.

[unity] understanding of ThreadGroup and numthreads in computeshader

After consulting the relevant documents, I understand that the three parameters of the dispatch method mean how many thread groups are divided in the three directions of XYZ. Go back to the previous 8. That is, 100 / 8 = 12.5 – > 12 thread groups are divided.

in other words100*100The images were divided 12 times horizontally and vertically12*12Each grid is executed by a thread group.

However, 100 divided by 8 is not an integral division, so some more pixels will not be allocated to the thread group. Therefore, there is a black edge.

As shown in the figure below, this image is 100×100, each white small grid is 8×8, and there are 12 small grids horizontally and vertically. There are some blue areas on the far right and bottom, which cannot be covered by the thread group. This is the reason for the black edge.

[unity] understanding of ThreadGroup and numthreads in computeshader

In the computeshader code[numthreads(8,8,1)]It is equivalent to specifying how many threads there are in each thread group. If we change 8 in numthreads to 9, the black edge can be solved.

Think about it again. Why does the black edge become larger if you fill in 9 during dispatch?

As shown in the figure below
[unity] understanding of ThreadGroup and numthreads in computeshader

The white grid is the thread group, and the size is9*9, the entire width is100*100Therefore, there are 11 white grids horizontally and vertically, and the last empty blue edge. The blue edge is an unassigned zone for the thread group.

The red grid shows the number of threads in the thread group8*8It cannot cover the working area of the whole thread group, so it can only complete part of the work in this area, and the rest will be completed by the threads in the second thread group. This is very strange, but it can explain the reason why the black edge becomes wider.

The horizontal direction of the red grid is 11. You can see that an empty area on the right and the blue area together form a black edge (an area that cannot be processed).

When I finish drawing, it seems that this situation will be formed.

[unity] understanding of ThreadGroup and numthreads in computeshader

The remaining white and blue areas are black edges that cannot be handled.

One of its features is found here:Work that cannot be completed by a thread group will be replaced by threads in other thread groups.I’m not sure if my understanding is correct, but it seems so.

If I set numthread to9*9, according to the current understanding, there should be a black edge such as a blue area.

[unity] understanding of ThreadGroup and numthreads in computeshader