OpenGL Core Details
Graphics Command Buffers

컴퓨트 쉐이더

컴퓨트 쉐이더는 일반적인 렌더링 파이프 라인과 다르게 그래픽 카드상에서 동작하는 프로그램입니다. 이것은 대규모 병렬 GPGPU 알고리즘 또는 게임 렌더링의 일부를 가속시키기 위해 사용할 수 있습니다. 효과적으로 사용하기 위해서는 종종 GPU 아키텍처 및 병렬 알고리즘에 대한 아래와 같은 더 깊은 지식이 필요합니다. DirectCompute, OpenCL, CUDA

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

  • Windows and Windows Store, with a DirectX 11 graphics API and Shader Model 5.0 GPU.
  • 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, so no compute shaders there yet.
  • Modern consoles (Sony PS4 and Microsoft XboxOne).

컴퓨트 쉐이더 에셋

일반 쉐이더와 유사한 컴퓨트 쉐이더는 프로젝트에서 *.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);
}

위의 샘플에서는 흥미로운 것과는 거리가 멀어 보이는, 단지 출력 텍스처를 빨간색으로 채웁니다.

언어는 표준 DirectX 11 HLSL이며, 예외로 #pragma kernel FillWithRed지시문을 사용합니다. 하나의 컴퓨트 쉐이더 에셋은 최소한 하나의 실행 가능한 “compute kernel”을 포함할 필요가 있으며, 그 함수는 #pragma 지시어를 사용하여 지정합니다. 파일에 여러 개의 커널을 포함할 수 있으며, 여러 # pragma kernel행을 추가할 뿐입니다.

Please note when using multiple #pragma kernel lines that comments of the style // text are not permitted on the same line as the #pragma kernel directives and will cause compilation errors.

#pragma kernel행은 옵션으로, 커널을 컴파일하는 동안 여러 전처리기 매크로를 추가하여 계속 정의할 수 있습니다. 샘플로는 :

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

컴퓨트 쉐이더 실행

스크립트 안에서 ComputeShader형식의 변수를 정의하여 에셋에 대한 참조를 할당하고, 그 다음은 ComputeShader.Dispatch 함수를 사용하여 수행할 수 있습니다. 자세한 내용은 스크립트 레퍼런스의 ComputeShader class를 참조하십시오.

컴퓨트 쉐이더와 밀접한 관련이 있는 것이 ComputeBuffer 클래스이며 모든 데이터 버퍼를 정의합니다(DirectX 11 용어로는 “structured buffer”). Render Texture도 “random access”플래그 (DirecX 11 용어로는 “unordered access view”)가 설정되어 있으면 컴퓨트 쉐이더에서 쓸 수 있습니다. RenderTexture.enableRandomWrite를 참조하십시오.

컴퓨트 쉐이더에서 텍스처 샘플러

텍스처와 샘플러는 Unity에서 오브젝트들로 분류되지 않기에, 컴퓨트 쉐이더에서 사용하기 위해서는 Unity 특유의 규칙을 따라야 합니다 :

  • 네이밍은 텍스처 이름과 동일하게 하거나 또는 “sampler”를 이름의 시작에 부여한 이름(예를 들어 Texture2D MyTex의 경우 SamplerState samplerMyTex) 중 하나를 합니다.
  • 또한, “미리 정의된” 샘플러를 사용합니다. 이름에 “Linear” 또는 “Point”(필터 모드로), “Clamp” 또는 “Repeat”(Wrap 모드로)를 붙여야 합니다. 예를 들어, “SamplerState MyLinearClampSampler”`- 이라 하면 필터로 Linear, Wrap 모드로 Clamp가 사용됩니다.

Cross-platform support

As with regular shaders, Unity is capable of translating compute shaders from HLSL to GLSL. Therefore for the easiest cross-platform builds it is recommended to write compute shaders in HLSL.

OpenGL compute differences from D3D

In order to achieve shaders working on multiple different platforms one should consider these limitations:

  • D3D and OpenGL have different data layout rules. Automatically translated GLSL shaders use std430 layout on compute buffers. Therefore for example using float3 based structured buffers will cause compatibility issues as DX allows tight packing but OpenGL enforces padding to float4. Scalars, two-component and four-component vectors are safe to use as they are. Extra care should be taken when constructing structs.
  • OpenGL ES 3.1 guarantees support for only 4 simultaneous shader storage buffers. Actual implementations typically support a bit more but in general one should consider grouping related data in structs as opposed to having each data item in its own buffer.

HLSL-only or GLSL-only compute shaders

Typically compute shader files are written in HLSL, and compiled or translated into all needed platforms automatically. However it is possible to either prevent translation to GLSL (i.e. only keep HLSL platforms), or to write GLSL compute code manually.

  • Compute shader source surrounded by CGPROGRAM and ENDCG keywords will not be processed for OpenGL/GLSL platforms.
  • Compute shader source surrounded by GLSLPROGRAM and ENDGLSL keywords will be treated as GLSL source, and emitted verbatim. This will only work when targetting OpenGL/GLSL platforms.

Note that for cross-platform builds neither of the above is recommended, since it very much ties compute shader source into being excluded from some platforms.

OpenGL Core Details
Graphics Command Buffers