I encountered a magical phenomenon today. I set a 100 * 100 , and then used ComputeShader to fill it with some colors, but there was a black border.

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);
}

The final image we get is like this, you can see that there is a black border.

image.png

I tried it, if I change the 8 in shader.Dispatch(0, _renderTexture.width / 8, _renderTexture.height / 8, 1);

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

You will find that this black border has become wider.

image.png

After I checked the relevant documents, I understood that the three parameters of the Dispatch method are 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.

That is to say 100*100 is divided 12 times horizontally and vertically. There are 12*12 small grids, and each grid is executed by a thread group.

But 100 divided by 8 is not evenly divisible, so there will be more pixels that cannot be allocated to the thread group. So there is a black border.

As shown in the figure below, this image is 100x100, each white small grid is 8x8, 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 black border Causes.

image.png

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

Think about it again, why does the black border become bigger if you fill in 9 in Dispatch?

As shown below
image.png

The white grid is the thread group, the size is 9*9 , and the entire width is 100*100 , so there are 11 white grids horizontally and vertically, and the blue side is empty at the end. This blue border is the unassigned zone of the thread group.

The red grid is that the number of threads in the thread group is 8*8 It cannot cover the work area of the entire thread group, so it can only complete part of the work in this area, and the rest of the work will be done by the threads in the second thread group. , This is very strange, but it can explain why the black border becomes wider.

There are 11 red grids in the horizontal direction. It can be seen that the empty area on the right and the blue area together constitute a black border (a region that cannot be processed).

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

image.png

The remaining white areas and blue areas are black borders that cannot be processed.

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

If I set numthread to 9*9 , according to the current understanding, it should produce a black border like a blue area.

image.png


krosshj
152 声望16 粉丝

Developer, Gamer, Artist