OpenGL 코어 세부 정보(OpenGL Core Details)
그래픽스 커맨드 버퍼

컴퓨트 셰이더(Compute shaders)

컴퓨트 셰이더는 일반 렌더링 파이프라인과 별도로 그래픽 카드에서 실행되는 프로그램입니다. 컴퓨트 셰이더는 대량 병렬 GPGPU 알고리즘 또는 게임 렌더링의 일부를 가속시키기 위해 사용할 수 있습니다. 효율적으로 사용하려면 GPU 아키텍처와 병렬 알고리즘에 대한 깊은 지식뿐만 아니라 DirectCompute, OpenGL Compute, OpenCL, CUDA 또는 OpenCL에 대한 지식도 필요합니다.

Unity 의 컴퓨트 셰이더는 DirectX 11 DirectCompute 기술과 거의 일치합니다. 컴퓨트 셰이더가 작동하는 플랫폼은 다음과 같습니다.

  • DirectX 11 또는 DirectX 12 그래픽스 API 와 Shader Model 5.0 GPU 가 적용된 Windows 및 Windows 스토어

  • Metal 그래픽스 API 를 사용하는 Mac OS 및 iOS

  • Vulkan API 가 적용된 Android, Linux 및 Windows 플랫폼

  • 최신 OpenGL 플랫폼( Linux 또는 Windows 의 경우 OpenGL 4.3, Android 의 경우 OpenGL ES 3.1). Mac OS X 는 OpenGL 4.3 을 지원하지 않습니다.

  • 최신 콘솔(Sony PS4 및 Microsoft Xbox One)

컴퓨트 셰이더 지원은 SystemInfo.supportsComputeShaders를 사용하여 런타임에 쿼리할 수 있습니다.

컴퓨트 셰이더 에셋

일반 셰이더와 유사하게, 컴퓨트 셰이더는 프로젝트에 있는 에셋 파일로, 파일 확장자는 .compute 입니다. DirectX 11 스타일 HLSL 언어로 작성되어 있으며, 어떤 기능을 컴퓨트 셰이더 커널로 컴파일할 것인지 나타내는 최소한의 #pragma 컴파일 지시자를 포함합니다.

다음은 출력 텍스처를 빨간색으로 채우는 컴퓨트 셰이더 파일의 기본 예제입니다.

// test.compute

#pragma kernel FillWithRed

RWTexture2D<float4> res;

[numthreads(1,1,1)]
void FillWithRed (uint3 dtid : SV_DispatchThreadID)
{
    res[dtid.xy] = float4(1,0,0,1);
}

The language is standard DX11 HLSL, with the only exception of a #pragma kernel FillWithRed directive. One compute shader Asset file must contain at least onecompute kernel that can be invoked, and that function is indicated by the #pragma directive. There can be more kernels in the file; just add multiple #pragma kernel lines.

여러 #pragma kernel 행을 사용하는 경우 #pragma kernel 지시문과 동일한 행에 스타일 // text 주석을 사용할 수 없으므로 컴파일 오류가 발생하면 이를 사용해야 합니다.

#pragma kernel 행에는 선택적으로 해당 커널을 컴파일하는 동안 정의할 수 있는 많은 사전 처리기 매크로가 올 수 있습니다. 예를 들어 다음과 같습니다.

# pragma kernel KernelOne SOME_DEFINE DEFINE_WITH_VALUE=1337
# pragma kernel KernelTwo OTHER_DEFINE
// ...

컴퓨트 셰이더 불러오기

스크립트에서 ComputeShader 타입의 변수를 정의하고 에셋에 대한 레퍼런스를 할당하면 ComputeShader.Dispatch 함수를 사용하여 불러올 수 있습니다. 자세한 내용은 ComputeShader 클래스의 Unity 문서를 참조하십시오.

Closely related to compute shaders is a ComputeBuffer class, which defines arbitrary data buffer (“structured buffer” in DX11 lingo). {Render Textures](../ScriptReference/RenderTexture.html) can also be written into from compute shaders, if they have “random access” flag set (“unordered access view” in DX11). See RenderTexture.enableRandomWrite to learn more about this.

컴퓨트 셰이더의 텍스처 샘플러

텍스처와 샘플러는 Unity 에서 별개의 오브젝트가 아니므로, 컴퓨트 셰이더에서 사용하려면 다음과 같은 Unity 관련 규칙 중 하나를 따라야 합니다.

  • 텍스처 이름과 동일한 이름을 사용하고 처음에는 sampler를 사용해야 합니다(예: Texture2D MyTex; SamplerState samplerMyTex). 이 경우, 샘플러는 텍스처의 filter/wrap/aniso 설정으로 초기화됩니다.

  • 미리 정의된 샘플러를 사용해야 합니다. 이를 위해 이름은 Linear 또는 Point(필터 모드의 경우) 및 Clamp 또는 Repeat(랩 모드의 경우)가 있어야 합니다. 예를 들어 SamplerState MyLinearClampSampler는 선형 필터 모드와 클램프 랩 모드가 있는 샘플러를 만듭니다.

크로스 플랫폼 지원

일반 셰이더와 마찬가지로 Unity 는 컴퓨트 셰이더를 HLSL 에서 다른 셰이더 언어로 트랜스폼할 수 있습니다. 따라서 가장 쉬운 크로스 플랫폼 빌드를 위해 HLSL 에 컴퓨트 셰이더를 작성해야 합니다. 그러나 이를 수행할 때 고려해야 할 몇 가지 요소가 있습니다.

크로스 플랫폼 베스트 프랙티스

DirectX 11(DX11)은 다른 플랫폼(Metal 또는 OpenGL ES 등)에서는 지원하지 않는 많은 작업을 지원합니다. 따라서 항상 DX11 이 아닌 지원이 적은 플랫폼에서 셰이더가 잘 정의된 동작을 수행하도록 해야 합니다. 다음은 고려해야 할 몇 가지 사항입니다.

  • 범위를 벗어난 메모리 액세스가 잘못되었습니다. DX11 은 읽을 때 일관되게 0 을 반환할 수 있으며 문제없이 일부 쓰기를 읽을 수 있지만 지원이 적은 플랫폼은 GPU 를 충돌시킬 수 있습니다. DX11 특정 해킹, 스레드 그룹 크기의 배수와 일치하지 않는 버퍼 크기, 버퍼의 시작 또는 끝에서 이웃하는 데이터 요소를 읽으려는 시도 및 유사한 비호환성을 주의해야 합니다.

  • 리소스를 초기화해야 합니다. 새 버퍼 및 텍스처의 내용은 정의되지 않습니다. 일부 플랫폼은 모두 0 을 제공하지만 다른 플랫폼에서는 NaN 을 포함할 수 있습니다.

  • 컴퓨트 셰이더가 선언한 모든 리소스를 바인딩해야 합니다. 셰이더가 분기로 인해 현재 상태의 리소스를 사용하지 않는다는 사실을 알고 있어도 리소스가 바인딩되어 있는지 확인해야 합니다.

플랫폼별 차이점

  • Metal(iOS 및 tvOS 플랫폼용)은 텍스처의 원자 연산(atomic operation)을 지원하지 않습니다. 또한 Metal 은 버퍼에서 GetDimensions 쿼리를 지원하지 않습니다. 필요한 경우 버퍼 크기 정보를 상수로 셰이더에 전달해야 합니다.

  • OpenGL ES 3.1(Android, iOS, tvOS, Tizen 플랫폼용)은 한 번에 4 개의 컴퓨트 버퍼만 지원합니다. 실제 구현은 보통 더 많은 것을 지원하지만 일반적으로 OpenGL ES 용으로 개발하는 경우에는 각 데이터 항목을 자체 버퍼에 두는 대신 관련 데이터를 구조체로 그룹화하는 것을 고려해야 합니다.

HLSL 전용 또는 GLSL 전용 컴퓨트 셰이더

일반적으로 컴퓨트 셰이더 파일은 HLSL로 작성되고 필요한 모든 플랫폼으로 자동 컴파일되거나 번역됩니다. 그러나 다른 언어로의 이동(즉, HLSL 플랫폼만 유지)을 방지하거나 GLSL 컴퓨트 코드를 수동으로 작성할 수 있습니다.

다음 정보는 크로스 플랫폼 빌드가 아닌 HLSL 전용 또는 GLSL 전용 컴퓨트 셰이더에만 적용됩니다. 이 정보로 인해 일부 플랫폼에서 컴퓨트 셰이더 소스가 제외될 수 있기 때문입니다.

  • CGPROGRAMENDCG 키워드로 둘러싸인 컴퓨트 셰이더 소스는 HLSL 이 아닌 플랫폼에서 처리되지 않습니다.

  • GLSLPROGRAMENDGLSL 키워드로 둘러싸인 컴퓨트 셰이더 소스는 GLSL 소스로 취급되며 축약됩니다. 이는 OpenGL 또는 GLSL 플랫폼을 타겟으로 할 때만 적용됩니다. 자동으로 변환된 셰이더는 버퍼의 HLSL 데이터 레이아웃을 따르지만 수동으로 작성된 GLSL 셰이더는 GLSL 레이아웃 규칙을 따릅니다.


  • 2017–05–18 제한적인 편집 리뷰를 거쳐 페이지 수정됨 - 피드백 작성

  • 5.6 에서 추가됨: SystemInfo.supportsComputeShaders, macOS, iOS(Metal 사용), Android, Linux, Windows(Vulkan) 플랫폼

OpenGL 코어 세부 정보(OpenGL Core Details)
그래픽스 커맨드 버퍼