UDN
Search public documentation:

ComputeShaderKR
English Translation
日本語訳
中国翻译

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 홈 > 언리얼 엔진 3의 DirectX 11 > 컴퓨트 셰이더
UE3 홈 > 그래픽 프로그래밍 > 컴퓨트 셰이더

컴퓨트 셰이더


컴퓨트 셰이더 사용하기


주: 이 기능은 컴퓨트 셰이더(compute shader) 기능이 지원되는 Direct3D 11 이 필요합니다. (활성화시키는 법은 DirectX 11 Rendering KR 참고)

C++

"Unordered Access View" (UAV) 로 약간의 데이터를 출력하고자 컴퓨트 셰이더를 사용하려면, RHICreateTargetableSurface (RHI 타게팅가능 표면 생성) 호출시 TargetSurfCreate_UAV (타겟 표면 생성_UAV) 옵션을 설정해 줘야 합니다.

컴퓨트 셰이더는 픽셀 셰이더처럼 생성 및 바운드되며, FGlobalBoundShaderState (F 글로벌 바운드 셰이더 스테이트) 오브젝트와 SetGlobalBoundShaderState (글로벌 바운드 셰이더 스테이트 설정) 호출이 필요치 않습니다. 셰이더는 SF_Compute 빈도(frequency)로 생성해야 합니다. 지오메트리를 그리는 대신 RHIDispatchComputeShader (RHI 컴퓨트 셰이더 디스패치) 함수를 호출해야 합니다.

예제 코드 스니펫:

RenderTargets[TranslucencyBuffer].Surface = RHICreateTargetableSurface(
   TranslucencyBufferSizeX,
   TranslucencyBufferSizeY,
   TranslucencyBufferSurfaceFormat,
   RenderTargets[TranslucencyBuffer].Texture,
   TargetSurfCreate_Dedicated | TargetSurfCreate_UAV,
   TEXT("TranslucencyBuffer"));

...

class FTestComputeShader : public FGlobalShader
{
   DECLARE_SHADER_TYPE(FTestComputeShader,Global);

   static UBOOL ShouldCache(EShaderPlatform Platform)
   {
      return Platform == SP_PCD3D_SM5;
   }

   /** 디폴트 생성자 */
   FTestComputeShader() {}

public:
   FShaderResourceParameter      TestResourceParameter;
   FShaderResourceParameter      ComputeShaderOutParameter;
   FShaderParameter            TestParameter;

   /** 초기화 생성자 */
   FTestComputeShader(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
      :   FGlobalShader(Initializer)
   {
      TestResourceParameter.Bind(Initializer.ParameterMap, TEXT("TestResourceParameter"), TRUE);
      TestParameter.Bind(Initializer.ParameterMap, TEXT("TestParameter"), TRUE);
      ComputeShaderOutParameter.Bind(Initializer.ParameterMap, TEXT("ComputeShaderOut"), TRUE);
   }

   static const TCHAR* GetSourceFilename()
   {
      return TEXT("TestComputeShader");
   }

   static const TCHAR* GetFunctionName()
   {
      return TEXT("MainCS");
   }

   // FShader 인터페이스
   virtual UBOOL Serialize(FArchive& Ar)
   {
      UBOOL bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
      Ar << TestResourceParameter << TestParameter << ComputeShaderOutParameter;

      return bShaderHasOutdatedParameters;
   }
};
IMPLEMENT_SHADER_TYPE2(, FTestComputeShader, SF_Compute, 0, 0);

...

TShaderMapRef<FTestComputeShader> ComputeShader(GetGlobalShaderMap());

FVector4 Value((rand() % 0xff) / 255.0f, 1, 2, 3);

SetShaderValue(ComputeShader->GetComputeShader(), ComputeShader->TestParameter, Value);

SetTextureParameter(
   ComputeShader->GetComputeShader(),
   ComputeShader->TestResourceParameter,
   TStaticSamplerState<SF_Point>::GetRHI(),
   GSceneRenderTargets.GetSceneColorTexture() );

if(ComputeShader->ComputeShaderOutParameter.IsBound())
{
   // 목적지 UAV 설정
   RHISetUAVParameter(
      ComputeShader->GetComputeShader(),
      ComputeShader->ComputeShaderOutParameter.GetBaseIndex(),
      GSceneRenderTargets.GetTranslucencyBufferSurface()
      );
}

RHIDispatchComputeShader(ComputeShader->GetComputeShader(), 8, 8, 1);

RHICopyToResolveTarget(GSceneRenderTargets.GetTranslucencyBufferSurface(), FALSE, FResolveParams());

HLSL

예제 코드 스니펫:

sampler2D TestResourceParameter;
float4 TestParameter;
RWTexture2D<float4> ComputeShaderOut;

[numthreads(8, 8, 1)]
void MainCS(
   uint3 DTid : SV_DispatchThreadID,
   uint3 GTid : SV_GroupThreadID,
   uint3 Gid : SV_GroupID )
{
   uint2 TileXY = Gid.xy;
   uint2 TexelXY = DTid.xy;

   // 텍스처 룩업
   ComputeShaderOut[TexelXY] = TestParameter.x * tex2Dlod(TestResourceParameter, float4(TexelXY * (1.0f / 1000.0f), 0, 0) );
}