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

Compute shaders

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

Compute shaders in Unity closely match DirectX 11 DirectCompute technology. Platforms where compute shaders work:

  • Windows and Windows Store, with a DirectX 11 or DirectX 12 graphics API and Shader Model 5.0 GPU

  • macOS and iOS using Metal graphics API

  • Android, Linux and Windows platforms with Vulkan API

  • Modern OpenGL platforms (OpenGL 4.3 on Linux or Windows; OpenGL ES 3.1 on Android). Note that Mac OS X does not support OpenGL 4.3

  • Modern consoles (Sony PS4 and Microsoft Xbox One)

Compute shader support can be queried runtime using SystemInfo.supportsComputeShaders.

Compute shader Assets

Similar to regular shaders, compute shaders are Asset files in your project, with a .compute file extension. They are written in DirectX 11 style HLSL language, with a minimal number of #pragma compilation directives to indicate which functions to compile as compute shader kernels.

Here’s a basic example of a compute shader file, which fills the output texture with red:

// 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.

When using multiple #pragma kernel lines, note that comments of the style // text are not permitted on the same line as the #pragma kernel directives, and cause compilation errors if used.

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

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

컴퓨트 셰이더 불러오기

In your script, define a variable of ComputeShader type and assign a reference to the Asset. This allows you to invoke them with ComputeShader.Dispatch function. See Unity documentation on ComputeShader class for more details.

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.

Texture samplers in compute shaders

Textures and samplers aren’t separate objects in Unity, so to use them in compute shaders you must follow one of the following Unity-specific rules:

  • Use the same name as the Texture name, with sampler at the beginning (for example, Texture2D MyTex; SamplerState samplerMyTex). In this case, the sampler is initialized to that Texture’s filter/wrap/aniso settings.

  • Use a predefined sampler. For this, the name has to have Linear or Point (for filter mode) and Clamp or Repeat (for wrap mode). For example, SamplerState MyLinearClampSampler creates a sampler that has Linear filter mode and Clamp wrap mode.

크로스 플랫폼 지원

As with regular shaders, Unity is capable of translating compute shaders from HLSL to other shader languages. Therefore, for the easiest cross-platform builds, you should write compute shaders in HLSL. However, there are some factors that need to be considered when doing this.

Cross-platform best practices

DirectX 11 (DX11) supports many actions that are not supported on other platforms (such as Metal or OpenGL ES). Therefore, you should always ensure your shader has well-defined behavior on platforms that offer less support, rather than only on DX11. Here are few things to consider:

  • Out-of-bounds memory accesses are bad. DX11 might consistently return zero when reading, and read some writes without issues, but platforms that offer less support might crash the GPU when doing this. Watch out for DX11-specific hacks, buffer sizes not matching with multiple of your thread group size, trying to read neighboring data elements from the beginning or end of the buffer, and similar incompatibilities.

  • Initialize your resources. The contents of new buffers and Textures are undefined. Some platforms might provide all zeroes, but on others, there could be anything including NaNs.

  • Bind all the resources your compute shader declares. Even if you know for sure that the shader does not use resources in its current state because of branching, you must still ensure a resource is bound to it.

Platform-specific differences

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

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

HLSL-only or GLSL-only compute shaders

Usually, compute shader files are written in HLSL, and compiled or translated into all necessary platforms automatically. However, it is possible to either prevent translation to other languages (that is, only keep HLSL platforms), or to write GLSL compute code manually.

The following information only applies to HLSL-only or GLSL-only compute shaders, not cross-platform builds. This is because this information can result in compute shader source being excluded from some platforms.

  • Compute shader source surrounded by CGPROGRAM and ENDCG keywords is not processed for non-HLSL platforms.

  • Compute shader source surrounded by GLSLPROGRAM and ENDGLSL keywords is treated as GLSL source, and emitted verbatim. This only works when targeting OpenGL or GLSL platforms. You should also note that while automatically translated shaders follow HLSL data layout on buffers, manually written GLSL shaders follow GLSL layout rules.


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

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

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