텍스처 공유 퀵스타트

프로젝트에서 텍스처 공유 SDK와 언리얼 엔진 플러그인을 사용하는 방법을 살펴봅니다.

Choose your operating system:

Windows

macOS

Linux

이 가이드를 끝까지 읽고 나면 다음과 같은 작업을 할 수 있습니다.

  • 소스에서 텍스처 공유 SDK를 빌드합니다.

  • C++ SDK를 DirectX11 및 DirectX12와 통합합니다.

  • 언리얼 엔진 플러그인과 블루프린트를 사용합니다.

  • 언리얼 엔진에서 프로젝트의 렌더링된 뷰포트를 외부 애플리케이션으로 전송합니다.

  • 언리얼 세션 중 외부 애플리케이션에서 텍스처를 전송 및 수신합니다.

1단계 - SDK 사용하기

텍스처 공유 SDK를 사용하기 위해서는 소스에서 엔진을 다운로드하여 빌드해야 합니다. 엔진 소스 코드를 찾는 방법에 대한 자세한 내용은 언리얼 엔진 소스 코드 다운로드하기를 참고하세요.

Visual Studio에서 엔진을 빌드하더라도 기본적으로 TextureShareSDK 프로젝트는 빌드되지 않습니다.

텍스처 공유 SDK를 빌드하려면 다음 단계를 따릅니다.

  1. Visual Studio에서 UE4.sln 파일을 엽니다.

  2. 솔루션 탐색기(Solution Explorer) 패널에서 프로그램(Programs) > 텍스처 공유(TextureShare) 로 이동합니다. TextureShareSDK 프로젝트를 우클릭하여 빌드를 시작합니다.

    image alt text

  3. 프로젝트가 빌드를 완료하면 Engine\Binaries\Win64\TextureShareSDK 폴더에 .lib 파일과 .dll 파일이 생성됩니다.

C++ SDK 통합

텍스처 공유 API를 사용하면 텍스처 공유 프로세스를 세부적으로 제어할 수 있습니다.

텍스처 공유를 사용하기 위해서는 읽기 또는 쓰기 작업을 수행하기 전에 교환 당사자 간에 세션을 설정해야 합니다. 프로세스의 각 단계에서는 프로젝트를 위해 커스터마이징할 수 있는 다양한 동기화 상태를 제어할 수 있습니다.

텍스처 공유 API를 사용하는 C++ 애플리케이션은 다음 구조를 따릅니다.

  1. 클라이언트 애플리케이션은 텍스처 공유 오브젝트의 이름을 지정하여 이를 생성합니다.

  2. 텍스처는 여러 개의 텍스처를 보유할 수 있는 텍스처 공유 오브젝트에 등록되며 텍스처 등록이 완료된 후 텍스처 세션이 시작됩니다.

  3. 각 프레임에서 데이터가 작성될 수 있으며 다른 애플리케이션 또는 읽기에 전송될 수 있습니다. 데이터 버퍼는 읽기 또는 쓰기 작업 전에 잠겨야 하며 작업이 끝난 후에는 잠금이 해제되어야 합니다.

  4. 3단계는 세션이 끝날 때까지 모든 프레임에서 반복됩니다.

다음 섹션은 Engine/Source/Programs/TextureShare/Samples/ThirdParty/TextureShare_ClientD3D12 에 있는 DirectX12 샘플 프로젝트 `TextureShareD3D12Client.vcxproj`에서 텍스처 공유 API가 어떻게 사용되는지 보여줍니다.

이 예시에서는 DirectX12를 사용했지만 DirectX11를 사용하더라도 프로세스는 동일합니다. 일부를 수정하여 ThirdParty 폴더에 있는 DirectX11 샘플 프로젝트로 예시를 따라할 수도 있습니다.

파일 포함

  • 헤더 파일 TextureShareD3D12Client.h 및 `TextureShareDLL.h`을 포함합니다.

  • pragma 주석을 사용하여 스태틱 라이브러리 파일을 연결합니다. Visual Studio에서 Release 환경설정으로 빌드하는 경우에는 TextureShareSDK.lib`을 사용하고, **Debug** 환경설정으로 빌드하는 경우에는 TextureShareSDK-Win64-Debug.lib`을 사용합니다.

    #include "TextureShareD3D12Client.h"
    #include "TextureShareDLL.h"
    #ifdef _DEBUG
    #pragma comment( lib, "TextureShareSDK-Win64-Debug.lib" )
    #else
    #pragma comment( lib, "TextureShareSDK.lib" )
    #endif

초기화

다음 단계는 초기화 대상과 텍스처 공유 세션을 C++로 시작하는 방법을 설명합니다.

  1. DirectX API를 사용하여 렌더 파이프라인 및 에셋을 로드합니다.

    1. DirectX 디바이스를 생성합니다.

    2. GraphicsCommandList를 생성합니다.

    예시는 D3D12HelloTexture::LoadPipeline()D3D12HelloTexture::LoadAssets() 을 참고하세요.

  2. 텍스처 공유 항목을 생성합니다.

    1. 공유 이름을 설정합니다. 이름의 최대 길이는 128자입니다.

    2. `ETextureShareProcess::Client`를 사용하여 애플리케이션을 클라이언트로 설정합니다.

    3. 텍스처 공유 세션을 위해 동기화 정책을 정의합니다. 자세한 내용은 동기화 정책을 참고하세요. 이 예시에서는 모든 동기화 정책이 없음(None) 으로 설정되어 동기화 이벤트 시 차단이 발생하지 않습니다.

    4. 사용할 그래픽 API를 지정합니다. 현재는 DirectX11과 DirectX12만 지원됩니다.

      FTextureShareSyncPolicy DefaultSyncPolicy;
      DefaultSyncPolicy.ConnectionSync = ETextureShareSyncConnect::None;
      DefaultSyncPolicy.FrameSync = ETextureShareSyncFrame::None;
      DefaultSyncPolicy.TextureSync = ETextureShareSyncSurface::None;
      FTextureShareInterface::CreateTextureShare(ShareName.c_str(), ETextureShareProcess::Client, DefaultSyncPolicy, ETextureShareDevice::D3D12);
  3. 텍스처 공유 항목으로 텍스처를 등록합니다.

    1. 세션의 공유 이름을 설정합니다.

    2. 텍스처 이름을 설정합니다.

    3. 텍스처 해상도를 설정합니다.

    4. 텍스처 포맷 및 값을 정의합니다.

    5. 텍스처의 읽기 또는 쓰기 가능 여부를 설정합니다.

      ETextureShareFormat ShareFormat = ETextureShareFormat::Undefined;
      uint32 ShareFormatValue = 0;
      // 클라이언트 텍스처 포맷을 사용합니다
      if (InFormat != DXGI_FORMAT_UNKNOWN)
      {
          ShareFormat = ETextureShareFormat::Format_DXGI;
          ShareFormatValue = InFormat;
      }
      FTextureShareInterface::RegisterTexture(ShareName.c_str(), TextureName.c_str(), Width, Height, ShareFormat, ShareFormatValue, TextureOp);
  4. 텍스처 공유 세션 범위의 시작을 정의합니다.

    FTextureShareInterface::BeginSession(ShareName.c_str());

렌더 스레드

다음 단계는 렌더 스레드에서 공유된 메모리에 액세스하는 방법을 설명합니다. 아래 단계는 읽기 및 쓰기 작업을 사용하는 방법을 보여줍니다.

  1. 텍스처 공유 세션에서 프레임에 대해 범위의 시작을 정의합니다.

    FTextureShareInterface::BeginFrame_RenderThread(ShareName.c_str());
  2. 렌더 스레드에서 텍스처를 읽습니다.

    1. 텍스처를 잠급니다.

    2. 텍스처 메모리에 액세스합니다.

    3. 텍스처의 잠금을 해제합니다.

      if (FTextureShareInterface::IsValid(ShareName.c_str()))
      {
          ID3D12Resource* SharedResource;
          if (FTextureShareInterface::LockTextureD3D12_RenderThread(pD3D12Device, ShareName.c_str(), TextureName.c_str(), SharedResource))
          {
              if (!FTextureShareD3D12Helper::IsTexturesEqual(SharedResource, *InOutSRVTexture))
              {
                  // 공유된 텍스처 크기가 서버 측에서 변경되었습니다. 임시 텍스처를 삭제하고 새로운 임시 텍스처를 다시 생성합니다.
                  ReleaseTextureAndSRV(InOutSRVTexture);
              }
              if (!*InOutSRVTexture)
              {
                  // 임시 텍스처 및 SRV를 생성합니다
                  FTextureShareD3D12Helper::CreateSRVTexture(pD3D12Device, pD3D12HeapSRV, SharedResource, InOutSRVTexture, SRVIndex);
              }
              // 공유된 텍스처에서 임시 텍스처로 복사합니다.
              if (*InOutSRVTexture)
              {
                  FTextureShareD3D12Helper::CopyResource(pCmdList, SharedResource, *InOutSRVTexture);
              }
              // 공유된 리소스의 잠금을 해제합니다.
              FTextureShareInterface::UnlockTexture_RenderThread(ShareName.c_str(), TextureName.c_str());
          }
          else
          {
              // 사용하지 않은 텍스처의 연결을 해제합니다.
              ReleaseTextureAndSRV(InOutSRVTexture);
            }
      }
  3. 렌더 스레드의 텍스처에 씁니다.

    1. 세션이 유효한지 확인합니다.

    2. 텍스처를 잠급니다.

    3. 메모리에 액세스합니다.

    4. 텍스처의 잠금을 해제합니다.

        if (FTextureShareInterface::IsValid(ShareName.c_str()))
      {
          ID3D12Resource* SharedResource;
          if (FTextureShareInterface::LockTextureD3D12_RenderThread(pD3D12Device, ShareName.c_str(), TextureName.c_str(), SharedResource))
          {
                  FTextureShareD3D12Helper::CopyResource(pCmdList, InTexture, SharedResource);
                  FTextureShareInterface::UnlockTexture_RenderThread(ShareName.c_str(), TextureName.c_str());
          }
      }
  4. 프로젝션 및 카메라 버퍼와 같은 보조 버퍼에서 정보에 액세스하기 위해 프레임 데이터를 가져옵니다.

    FTextureShareSDKAdditionalData* OutFrameData;
    FTextureShareInterface::GetRemoteAdditionalData(ShareName.c_str(), *OutFrameData);
  5. 텍스처 공유 세션에서 프레임에 대해 범위의 끝을 정의합니다.

    FTextureShareInterface::EndFrame_RenderThread(ShareName.c_str());
  6. 표시할 프레임을 제시합니다.

정리

다음 단계는 애플리케이션을 종료할 때 텍스처 공유 세션을 종료하는 방법을 설명합니다.

  1. 텍스처 공유 세션 범위의 끝을 정의합니다.

    FTextureShareInterface::EndSession(ShareName.c_str());
  2. 텍스처 공유 항목을 삭제하고 메모리를 해제합니다.

    FTextureShareInterface::ReleaseTextureShare(ShareName.c_str());

2단계 - 언리얼 엔진에서 사용하기

다음 단계를 수행하여 텍스처 공유 플러그인을 사용하고 언리얼 엔진에서 텍스처 공유 블루프린트에 액세스합니다.

  1. 에디터 메인 메뉴의 편집(Edit) >플러그인(Plugins) 으로 이동하여 플러그인 에디터(Plugins Editor) 창을 엽니다.

  2. 플러그인 에디터의 기타(Misc) 섹션에서 텍스처 공유 플러그인을 찾습니다.

    image alt text

  3. 활성화됨(Enabled) 확인란을 클릭하고 에디터를 다시 시작합니다.

  4. 콘텐츠 브라우저(Content Browser) 에서 패널의 오른쪽 하단에 있는 뷰 옵션(View Options) 드롭다운을 확장합니다. 엔진 콘텐츠 표시(Show Engine Content)플러그인 콘텐츠 표시(Show Plugin Content) 박스를 선택합니다.

    image alt text

  5. 콘텐츠 브라우저 맨 위의 폴더 아이콘을 클릭하여 콘텐츠 경로를 선택합니다. 목록에서 텍스처 공유 콘텐츠(TextureShare Content) 를 찾아 선택합니다.

    image alt text

  6. Blueprints 폴더에는 씬에 직접 추가할 수 있는 블루프린트 오브젝트가 있습니다.

    • BP_TextureShare_Scene : 이 블루프린트는 전체 언리얼 씬의 렌더링된 프레임을 공유합니다.

    • BP_TextureShare_Postprocess : 이 블루프린트는 특정 텍스처 오브젝트를 전송 및 수신합니다.

    image alt text

  7. Materials 폴더에는 BP_TextureShare_Postprocess 블루프린트와 함께 사용할 수 있는 텍스처와 머티리얼이 있습니다.

    • RTT_TextureShare_Backbuffer : 텍스처 렌더 타깃 2D 에셋입니다.

    • M_TextureShare_RTTBackbuffer : RTT_TextureShare_Backbuffer 텍스처를 샘플링한 다음 이미시브 컬러 로 사용하는 머티리얼입니다.

    image alt text

이 퀵스타트의 나머지 단계에서는 각 블루프린트를 사용하는 방법과 블루프린트를 다른 DirectX 애플리케이션에 연결하는 방법을 설명합니다.

3단계 - 언리얼 씬을 텍스처로 DirectX 애플리케이션에 전송

언리얼 씬을 외부 DirectX 애플리케이션에 스트림하려면 다음 단계를 따릅니다.

  1. Engine/Source/Programs/TextureShare/Samples/ThirdParty/TextureShare_ClientD3D11 폴더를 찾은 다음 Visual Studio에서 샘플 프로젝트 `TextureShareD3D11Client.vcxproj`을 엽니다.

  2. Visual Studio에서 솔루션 환경설정(Solution Configuration)Release 로 설정합니다.

  3. Visual Studio에서 프로젝트를 빌드합니다.

  4. Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D11\Binaries\TextureShareD3D11Client-Win64-Release 폴더를 찾은 다음 `TextureShareD3D11Client.exe`애플리케이션을 실행합니다.

  5. 언리얼 엔진에서 언리얼 프로젝트를 열고 씬에 블루프린트 BP_TextureShare_Scene 오브젝트를 추가합니다.

  6. BP_TextureShare_Scene 오브젝트를 선택하고 디테일(Details) 패널을 엽니다.

  7. 공유 이름(Share Name) 파라미터가 샘플 프로젝트의 ShareName 변수와 같은 이름인 vp_1 으로 설정되어 있는지 확인합니다.

  8. 언리얼에서 재생(Play) 을 누릅니다. 언리얼 씬의 렌더링된 프레임은 클라이언트 애플리케이션에 텍스처로 스트리밍되고 회전 큐브에 적용됩니다.

image alt text

4단계 - 텍스처를 외부 DirectX 애플리케이션으로 전송

이전 단계에서는 별도의 프로세스에서 언리얼 씬을 텍스처로 공유하는 방법에 대해 설명했습니다. 프로젝트의 텍스처 오브젝트는 외부 애플리케이션으로도 전송할 수 있습니다.

언리얼 프로젝트의 텍스처 오브젝트를 샘플 DirectX 애플리케이션에 공유하려면 다음 단계를 따릅니다.

  1. Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12 폴더를 찾은 다음 Visual Studio에서 샘플 프로젝트 `TextureShareD3D12Client.vcxproj`을 엽니다.

  2. 솔루션 환경설정Release 로 설정합니다.

  3. 프로젝트를 빌드합니다.

  4. Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12\Binaries\TextureShareD3D12Client-Win64-Release 프로젝트를 위해 빌드된 실행 파일을 실행합니다. TextureShareD3D12Client.exe.

  5. 언리얼 엔진에서 언리얼 프로젝트를 열고 씬에 블루프린트 BP_TextureShare_Postprocess 오브젝트를 추가합니다.

  6. 씬에 추가한 BP_TextureShare_Postprocess 오브젝트를 선택하고 디테일 패널을 엽니다.

    image alt text

  7. Postprocess 섹션을 펼칩니다.

  8. Postprocess 섹션 아래의 전송(Send) 섹션을 펼칩니다. 두 개의 전송 배열 요소가 있습니다. ID는 샘플 프로젝트의 D3D12HelloTexture.cpp 파일에서 정의한 텍스처 이름과 일치해야 합니다.

    // 공유 및 텍스처 이름을 정의합니다
    std::wstring ShareName1 = L"vp_1";
    std::wstring ReceiveTextureNames[] = { L"SceneDepth" , L"BackBuffer" };
    1. 첫 번째 전송 요소의 IDSceneDepth 로 설정합니다.

    2. 두 번째 전송 요소의 IDBackBuffer 로 설정합니다.

    image alt text

  9. 언리얼 에디터 에서 재생 을 누릅니다.

  10. 텍스처 오브젝트로 두 전송 요소의 텍스처 파라미터를 업데이트합니다. 엔진은 텍스처를 클라이언트 애플리케이션으로 스트리밍하고 렌더링된 트라이앵글에 적용합니다.

이미지 대체 텍스트

5단계 - DirectX 애플리케이션에서 텍스처를 수신하고 언리얼에서 표시

이전 단계에서는 텍스처를 외부 DirectX 애플리케이션에 전송하는 방법을 설명했습니다. 이 섹션에서는 다른 애플리케이션에서 텍스처를 수신하는 방법을 설명합니다.

샘플 DirectX 애플리케이션에서 텍스처를 수신하려면 다음 단계를 따릅니다.

  1. Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12 폴더를 찾은 다음 Visual Studio에서 샘플 프로젝트 `TextureShareD3D12Client.vcxproj`을 엽니다.

  2. 솔루션 환경설정Release 로 설정합니다.

  3. 프로젝트를 빌드합니다.

  4. Engine\Source\Programs\TextureShare\Samples\ThirdParty\TextureShare_ClientD3D12\Binaries\TextureShareD3D12Client-Win64-Release 프로젝트를 위해 빌드된 실행 파일을 실행합니다. TextureShareD3D12Client.exe.

  5. 언리얼 엔진에서 언리얼 프로젝트를 열고 씬에 블루프린트 BP_TextureShare_Postprocess 오브젝트를 추가합니다.

  6. 씬에 추가한 BP_TextureShare_Postprocess 오브젝트를 선택하고 디테일 패널을 엽니다.

  7. 디폴트(Default) 아래의 디테일 패널에서 Postprocess 섹션을 펼칩니다.

  8. Postprocess 섹션 아래의 수신(Receive) 섹션을 펼칩니다. 한 개의 수신 배열 요소가 있습니다. 이 요소의 ID 는 샘플 프로젝트의 D3D12HelloTexture.cpp 파일에서 정의한 텍스처 이름과 일치해야 합니다.

    // 공유 및 텍스처 이름을 정의합니다
    std::wstring ShareName1 = L"vp_1";
    std::wstring SendBackbufferTextureName = L"InBackbuffer";

    image alt text

  9. 수신 요소의 RTT 파라미터를 TextureShare 플러그인에 제공된 RTT_TextureShare_Backbuffer 텍스처로 설정합니다.

    image alt text

이제 언리얼 프로젝트는 TextureShare를 사용하여 다른 애플리케이션에서 텍스처를 수신하도록 구성되었습니다.

아래 예시에서는 언리얼 엔진 세션이 시작됩니다. 언리얼은 TextureShareD3D12Client 애플리케이션으로 텍스처를 전송하고 이 애플리케이션에서 백버퍼를 수신합니다. 씬에서 벽에 걸린 사진은 RTT_TextureShare_Backbuffer 텍스처를 샘플링하여 수신하는 정보를 실시간으로 표시하는 머티리얼을 사용하고 있습니다.

image alt text

태그
언리얼 엔진의 이전 버전을 위해 작성된 페이지입니다. 현재 언리얼 엔진 5 버전을 위해 업데이트되지 않았습니다.