Compute Shader Base

컴퓨터 셰이더는 렌더링 파이프라인에 포함 되지 않는 셰이더로 GPU의 병렬 처리 능력을 활용하여 물리 계산, AI, 이미지 처리, 시뮬레이션등에 사용 할수 있습니다.

유니티에서는 .compute 이름으로 저장이 되며, HLSL(High-Level Shader Language)을 사용 합니다.

컴퓨터 셰이더의 기본 구조


Computer Shader의 기본 구조에 대해서 알아 보겠습니다.

#pragma kernel CSMain

[numthreads(8, 8, 1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // GPU에서 실행될 코드
}

krnel
  • GPU에서 실행되는 하나의 "진입 함수(entry point)"를 의미합니다.
  • 각 커널은 GPU에서 병렬로 실행될 작업 단위입니다.
  • 여기서는 CSMain이 커널 이름입니다.
  • 커널은 한파일안에 여러개 정의 할수 있습니다.

여러개 정의한 예
#pragma kernel Init
#pragma kernel Update

RWStructuredBuffer<float> data;

[numthreads(64, 1, 1)]
void Init(uint id : SV_DispatchThreadID)
{
    data[id] = 0.0;
}

[numthreads(64, 1, 1)]
void Update(uint id : SV_DispatchThreadID)
{
    data[id] += 1.0;
}

C#에서 컴퓨터 셰이더 실행 하기

public ComputeShader shader;  //인스펙트에서 .compute 셰이더 파일 드래그

int kernel = computeShader.FindKernel("CSMain");
computeShader.Dispatch(kernel, 10, 10, 1);

커널을 찾고 Dispatch로 함수를 실행한다.
Dispatch는 "GPU에게 이 커널을 몇 개의 Thread Group으로 실행할지 지시하는 명령"입니다.

Dispatch 함수

첫번째 파라메터: 커널(kernel)
두번째, 세번째, 네번째 파라메터 : Thread Group의 개수 (X, Y, Z)

셰이더에 있는 다음의 숫자는 그룹안에서 실행되는 쓰레드의 갯수입니다.
여기서는 8*8*1로 64개의 쓰레드

[numthreads(8, 8, 1)]

Dispatch에서는 Group 50개 실행

Dispatch(10, 5, 1);


총 64 × 50 = 3200 쓰레드
1) SV_GroupThreadID
그룹 Thread ID
범위: 0 ~ numthreads-1

2) SV_GroupID
그룹 ID
범위: 0 ~ Dispatch-1

3) SV_DispatchThreadID (가장 중요)
전체 기준 전역 ID
계산식은 다음과 같다.

SV_DispatchThreadID = SV_GroupID * numthreads + SV_GroupThreadID