Unity ComputeShader笔记

#pragma kernel CSMain //定义核心函数
 
RWTexture2D<float4> Result;//这声明了一个变量,它包含的数据是shader程序将要用到的。我们不需要用到网格mesh数据,你需要像这样明确的声明,你的compute shader需要写入读出什么数据。数据类型名前面的“RW”指定了shader可以进行读写操作。
 
[numthreads(8,8,1)]//指定线程组的大小为一个(8*8*1)的三维数组。Tips:这个三维数组最大值不超过1024
void CSMain (uint3 id : SV_DispatchThreadID)
{
    Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0);
}

C#代码

public ComputeShader shader;
 
void RunShader()
{
  int kernelHandle = shader.FindKernel("CSMain");
 
  RenderTexture tex = new RenderTexture(256,256,24);
  tex.enableRandomWrite = true;
  tex.Create();
 
  shader.SetTexture(kernelHandle, "Result", tex);
  shader.Dispatch(kernelHandle, 256/8, 256/8, 1);
}

Dispatch (x, y, z) 与 numthreads (x, y, z) 的关系

Dispatch(x, y, z)是一个放置线程组的三维数组,numthreads(x, y, z)是一个放置线程的三维数组(就是前面所提的线程组)

如果你的GPU又64个核心,你的Dispatch(x, y, z)总长度恰好是64,那么每个核心将处理一个线程组。

单个线程组长度在不同硬件厂下分配的资源是不同的所以建议:AMD单个线程组长度使用64的倍数(wavefront架构),NVIDIA单个线程组长度使用32的倍数(SIMD32(Warp)架构)。所以为了保证兼容性最后单个线程组长度最好为32的倍数。

SV_GroupID、SV_GroupThreadID、SV_GroupIndex、SV_DispatchThreadID

SV_GroupID : 线程组 ID(三維,线程组的三维坐标)
SV_GroupThreadID : 线程组内线程ID (三維,线程在线程组内的三维坐标)
SV_GroupIndex : 线程在线程组内的下标(一维)
SV_DispatchThreadID : 唯一ID (可以理解为在图片上的坐标)

计算:
SV_GroupID = Dispatch(x,y,z)中的坐标位置
SV_GroupThreadID = numthreads(x, y, z)中的坐标位置
SV_GroupIndex = z*numthreads(x, y, z).x*numthreads(x, y, z).y + y*numthreads(x, y, z).x + x
SV_DispatchThreadID = (SV_GroupID.x*numthreads(x, y, z).x+SV_GroupThreadID.x,SV_GroupID.y*numthreads(x, y, z).y+SV_GroupThreadID.y+SV_GroupID.z*numthreads(x, y, z).z+SV_GroupThreadID.z)
 
 

 

 

posted @ 2023-12-21 17:01  修齐治平丶  阅读(123)  评论(0编辑  收藏  举报