2015년 10월 30일

2천 기가픽셀 텍스쳐 다룰 수 있는 분?

저자: Aljosha Demeulemeester

제 이름은 Aljosha Demeulemeester입니다. 저는 벨기에 Ghent에 소재한 미들웨어 회사인 Graphine의 CEO이자 공동창업자입니다.Graphine은 비디오 게임과 3D 시각화 산업을 위한 텍스쳐 스트리밍과 텍스쳐 압축 기술을 개발하였습니다.

지난 7년간, 저희는 이 한 가지 질문에 전념하였습니다. '비디오 게임에서 엄청난 양의 텍스쳐를 사용하는 기술적 장벽을 허물 수 있을까?' 였습니다. 목표는, 당연하게도 가상 세계에서 완전히 독창적인 세부 묘사를 포함하는 아주 세밀한 그래픽을 얻어내는 것이었습니다 . 모든 게임이 이 기술을 필요로 하는 것은 아닐 것이고, 또한 더 많은 텍스쳐를 추가시키는 것은 비주얼적인 측면에서 항상 기대치를 높여 주는 것은 아니지만, 저희는 이 한 가지 문제를 옳은 방향으로 해결하고 싶었습니다.

비디오 메모리는 텍스쳐 해상도를 높이거나 갯수를 늘릴 때를 제한하는 한 가지 요소입니다. 그래픽 카드 제조사는 더 많은 메모리를 추가시키려고 하지만, 개발자에게는 항상 부족하죠. 게임 레벨 시작에서 텍스쳐를 전부 로드해서 끝날 때 까지 기다리는 것 대신에, 개발 자들은 일종의 스트리밍 형태의 텍스쳐를 이미 몇 년 전 부터 사용해 오고 있었습니다. 하지만, 언리얼 엔진 4의 밉맵 스트리밍처럼 진보된 기술도 한계가 있습니다.

저희의 주력 미들웨어 제품인 Granite SDK와 함께라면, 현재 시스템이 갖고 있는 문제를 풀어내고, 굉장히 큰 (>16K) 텍스쳐를 사용할 수 있는 능력을 갖게 됩니다. Granite의 핵심 기술은 저희가 거대 텍스쳐에 대해 접근하는 방식인, id 소프트웨어가 개척해 낸 가상 텍스쳐링이라고 하는 것입니다. 여러분은 Tiled Resources(DX11.2)나 Partially Resident Textures (OpenGL)에 대해서 들어 보셨을 것입니다 . 이 기술들은 그래픽 하드웨어에서 버추얼 텍스쳐링을 가속하지만, Granite를 작동시키는 데에 필수적인 것은 아닙니다.

저희는 한참 전에 언리얼 엔진 4에 샘플로 통합을 시켜보았고 현재는 저희의 최초로 사용자 친화적이고 마무리 작업이 잘 이루어진 Granite for Unreal을 발매 하였습니다. 또한 저희는 언리얼을 위한 새로운 PC기반 라이센스정책을 발표하였는데, 왜냐하면 팀의 크기와 상관없이 모든 팀이 이 기술로부터 이득을 얻을 수 있다고 믿기 때문입니다. 또한, 저희는 이후에 인디 개발자를 위한 라이센스 정책을 추가할 계획입니다.

Granite를 왜 쓰나요?

줄여서, Graphine for Unreal은 더 큰 텍스쳐나 더 많은 텍스쳐를 튀어나오는 등의 깨짐 현상, 메모리 부족이나 긴 로딩 시간 등의 한계 없이 사용하도록 하는 한 가지 솔루션입니다. 이 기술은 여러분이 256K x 256K 까지의 텍스쳐, UDIM 텍스쳐, 또는 수 백 개의 4K 또는 8K 텍스쳐를 사용할 수 있도록 해 줍니다.

Granite는 다양한 범위의 응용프로그램에서 사용되어 왔습니다. Oculus같은 회사나, Allegorithmic, Mill 같은 회사들은 실시간 그래픽의 품질의 한계를 넘어서기 위해 이 기술을 사용하고 있습니다. Larian Studios의 Dragon Commander는 구워진 16K짜리 랜드스케이프 텍스쳐에 이 기술을 사용중이고, The Farm 51의 Get Even에서도 실사같음을 위한 독특한 고화질 3D 스캔 결과물을 다루기 위해 사용하였습니다. VR 영역에서, Granite는 미리 구워놓은 초고화질 텍스쳐를 다룸으로써 90프레임 고정으로 랜더링을 할 때에도 고품질 그래픽스 결과물을 생산해 낼 수 있습니다.

GetEven  
The Farm 51이 제작한 Get Even의 주변 환경

 

이번 포스팅에서 저는 언리얼에서 Granite를 사용하여 어떻게 큰 텍스쳐를 사용할 수 있는지를 보여드리겠습니다. 여러분은 약간의 텍스쳐 스트리밍에 관한 기술적인 정보를 다음 섹션에서 보실 수 있을 것이므로 Granite 사용법만을 보고자 하시는 경우에는 이 부분을 건너 뛰어 주시기 바랍니다.

바로 시작하기 위해서 여러분은 Granite를 여기에서 체험판 다운로드 하시거나, 여기에 서 튜토리얼 동영상 시청을 통해 간략하게 알아보실 수 있습니다.

텍스쳐 스트리밍

텍스쳐 스트리밍은 게임을 플레이 하는 중에 텍스쳐 데이터를 로드하는 과정입니다. 텍스쳐의 아주 일부분만이 메모리에 실제로 올려져 있게 됩니다. 스트리밍 시스템은 자동으로 언제 특정한 텍스쳐를 디스크에서 읽을 것인지, 또는 프로그래머가 명시적으로 텍스쳐를 읽어오라고 설정하거나 둘의 조합으로 정할 수 있습니다.

언리얼은 자동으로 텍스쳐를 몇 개의 파라미터, 특히나 가장 중요한 요소인 카메라로부터의 거리를 포함하는 파라미터들에 따라 자동으로 로드시키는 자체 텍스쳐 스트리밍 시스템이 있습니다. 언리얼 엔진은 특정한 거리에 위치한 텍스쳐에 해당하는 밉맵을 읽어들일 것입 니다. 이런 시스템은 거대한 오픈월드 게임을 가능하게 합니다. 하지만, 조밀하게 모여있는 씬에서는 난항을 겪게 됩니다. 다수의 오브젝트 가 모여있거나 한 오브젝트에 많은 텍스쳐가 올라가 있는 경우 등을 말합니다. 여러분이 월드에서 특정한 부분에 텍스쳐를 너무 많이 사용하 게 되고, 카메라에 동시에 가깝게 다가오면 스트리밍 시스템에 의해서 로드가 되어야 합니다. 이렇게 되면 시각적으로 튀거나 흐려지는 등의 문제점이 발생하게 됩니다. 여러분은 메모리 캐쉬 사이즈를 키울 수 있겠지만, 이 방법은 여전히 한계를 갖게 됩니다.

Granite SDK를 이용하면 이러한 문제에 대한 솔루션이 준비되어 있습니다. 이 프로그램은 타일 기반 텍스쳐 스트리밍, 버추얼 텍스 쳐링 쉐이더 라이브러리, 다양한 텍스쳐 압축 포맷, 텍스쳐 트랜스코더, 예측 시스템, 캐쉬 관리 시스템과 기타 등등의 기술이 들어 있습니 다. 기술적인 세부사항은 여기까지 하고, Granite는 텍스쳐의 모든 밉맵을 작은 텍스쳐 타일로 나눕니다, 특히 128x128 픽셀로 말이죠. 게임 을 실행할 때, Granite는 자동으로 카메라에서 어떤 타일이 보이는지를 판단하여 해당 타일만을 로드시킵니다. 대부분의 경우가 텍스쳐 밉맵 의 일부만이 화면에서 보이기 때문이죠. 예를 들어, 아래 이미지에서는 비행기의 날개 윗면만이 보이게 됩니다. 여러분이 사용하는 기존 스트리밍 엔진에서는 비행기의 모든 텍스쳐가 로드 될 것입니다. (8K 디퓨즈, 8K 노말, 8K 스패큘라) Granite는 실제로 필요한 부분만을 로드 하게 됩니다. 이렇게 되면 로드할 데이터가 훨씬 적게 되고, 여러분이 더 적은 텍스쳐 메모리로도 효율 높은 텍스쳐 해상도를 사용할 수 있 게 해 줍니다.

GRAPH_1 Graph_2

버추얼 텍스쳐링의 사용에 따르는 한 가지 주요한 장점은 여러분이 256K x 256K 같이 훨씬 큰 텍스쳐를 사용할 수 있다는 것입니다. DXT1로 압축되어 있는 이러한 크기의 텍스쳐는 32GB의 메모리를 사용할 것이고, 이 텍스쳐를 로드하는 것은 몇 분이 걸리게 될 것 입니다. Granite를 사용하면 여러분은 이 텍스쳐용으로 32MB의 비디오 메모리만을 필요로 하게 되고, 눈 깜짝할 새 로딩이 됩니다.

한가지 고려해볼 것은 버추얼 텍스쳐 샘플링이 일반적인 텍스쳐 샘플링보다는 연산량이 조금 더 추가가 된다는 것입니다. 저희는 그래서 머티리얼 당 16개의 버추얼 텍스쳐와 해당 텍스쳐 샘플러에 입력시키는 UV에 최대 4개까지의 서로 다른 UV coordinate를 가질 수 있도록 제한하였습니다. 이렇게 하여, 저희는 버추얼 텍스쳐 샘플링이 실용적인 측면(게임이나 가상현실 데모)에서 퍼포먼스를 확실히 거의 떨어 트리지 않도록 할 수 있었습니다.

Granite for Unreal 워크플로우

Granite를 사용할 때에는 텍스쳐 임포트 워크플로우가 조금 다릅니다. 아래에 설명이 되어 있습니다.

  1. Granite의 툴을 사용해서 텍스쳐를 타일셋으로 만들어 임포트 합니다. (아래를 보세요) 타일 셋들은 디스크에서 효율적으로 스트리밍 하기 위해서 텍스쳐를 나눠서 담아 두는 저장소입니다. 하나의 타일셋은 텍스쳐 데이터베이스 또는 256K 까지의 텍스쳐 아틀라스로 생각할 수 있습니다.
  2. 언리얼에 다른 에셋을 임포트 하듯이 .GTS 타일셋 파일을 임포트 합니다. 이렇게 하면 자동으로 여러분의 타일셋에 맞는 ‘Granite Texture’ 오브젝트 애셋을 생성해 줍니다. 이 오브젝트들은 표준적인 언리얼 텍스쳐와 유사합니다.
  3. Granite 머티리얼 노드에 Granite 텍스쳐를 사용합니다. 이 머티리얼은 Granite Texture를 여러분의 머티리얼에 샘플링 할 수 있도록 해 줍니다.

Graph_3

여기까지가 설정의 전부입니다. 아주 단순합니다. Granite 텍스쳐 노드는 여러분의 머티리얼 그래프에서 평범한 텍스쳐 노드처럼 사용될 수 있고, 모든 Granite 텍스쳐는 자동으로 Granite에 의해 백그라운드에서 스트리밍 됩니다.

Granite 텍스쳐 노드는 표준 언리얼 텍스쳐와 혼합될 수 있습니다. 그러므로 어느 텍스쳐를 Granite와 함께 스트리밍할까요? 일반 적으로 말씀드려서, Granite 를 사용하는 것은 커다란 텍스쳐를 사용할 때 가장 유용합니다. (>1K) 이 텍스쳐를 특정한 오브젝트나 영역에 사용할 때가 되겠습니다. 비슷한 텍스쳐들이나 서로 다른 UV로 여러번 샘플링되거나, 거의 항상 보이게 되는 텍스쳐 등은 언리얼 스트리밍 시스템을 사용하거나 전혀 스트리밍 되지 않는 것이 더 좋습니다.

텍스쳐 임포트 Importing Textures

타일셋을 만들고 여러분의 이미지 파일을 이 포맷으로 임포트하기 위해서 (.GTS 파일) 저희는 타일셋 스튜디오라고 하는 편리한 툴을 제작하였습니다. 이 툴은 .jpg, .png, .exr, .tga 기타 등등 대부분의 흔한 이미지 포맷을 지원합니다.

Graph_4

거대 텍스쳐 임포트 하기

타일셋 스튜디오는 32K x 32K 의 개발 이미지들을 임포트 할 수 있습니다. 텍스쳐에 지원되는 한 가지 굉장한 기능은 디스크에 이미지를 그리드로 나눠 저장한다는 것입니다. 거대 이미지 파일을 다루는 대부분의 툴은 이미지 세트로 익스포트 시킵니다. 이런 파일 그리드를 임포트 하기 위해서 파일들은 ‘landscape_02_06.jpg’ 또는 “satellite-A-3.png”와 같이 그리드의 위치를 이름에 포함 해야 합니다. 그냥 이미지 중 하나를 선택하면, 타일셋 스튜디오는 자동으로 이미지가 세트의 일부분인지를 감지합니다. 이렇듯 결합된 타일 이미지는 256K x 256K 크기까지 구성이 가능해 집니다.

특수효과급 품질의 UDIM 텍스쳐 임포트 하기

타일셋 스튜디오는 쉽게 UDIM 텍스쳐 또한 임포트 할 수 있습니다. 그냥 UDIM 패치 중 하나를 선택하면 됩니다. 예를 들어, ‘robot_1016.exr’와 같은 파일을 선택하거나, 직접 익스포터를 사용해서 MARI에서 가져올 수 있습니다. 모든 UDIM 패치는 타일 셋을 임포트 하고 나면 언리얼에서 하나의 Granite 텍스쳐 애셋이 됩니다. Granite는 UDIM UV 좌표를 다룰 수 있어서 여러분이 메쉬를 조절 할 필요가 없어지고, 언리얼 엔진에서 바로 사용할 수 있습니다.

또 다른 필수적인 요소는 Granite가 실질적으로 거대한 양의 텍스쳐를 특히나 특수효과급 품질의 UDIM 텍스쳐를 다룰 수 있다는 것 입니다. 예를 들어, Nurulize가 제작한 Rise 데모의 로봇은 (이미지를 보세요) 700개의 4K 맵들로 구성이 되어 있습니다. Granite는 주어진 상황에서 보이게 되는 UDIM 패치의 일부분만을 로드 할 것입니다. 이런 방법으로 여러분은 특별한 문제 없이 최고 품질로 텍스쳐를 볼 수 있습니다.

Graph_5

수백개의 개별 텍스쳐 임포트 하기

마지막으로, 지루한 반복작업이 없도록, 타일셋 스튜디오는 와일드카드와 배치 임포팅을 지원합니다. 이 기능은 전체 폴더를 ‘plane_diffuse.jpg’, ‘robot_diffuse.jpg’같이 연속적으로 명명된 폴더 세트로 임포트 할 수 있도록 해 줍니다. 이 예제에서, 여러분은 ‘*_diffuse.jpg’ 를 모든 디퓨즈 텍스쳐를 이 폴더에 임포트 할 때 사용할 것입니다. 언리얼에서 Granite 텍스쳐는(임포트 이후에) 파일 이름의 고유한 부분에 따라 명명될 것입니다. (‘plane’, ‘robot’, 그리고 기타 등등). 

다른 주목할 만한 기능들

라이트맵 스트리밍 하기

 

Graph_6

여러분이 언리얼의 라이트매스 시스템을 사용하고 게시다면, 여러분은 쉽게 Granite를 이용해서 라이트맵을 스트리밍 할 수 있습니다. 그냥 아래에 보시는 체크 박스를 선택하시면 되고, 이게 설정의 전부입니다. Granite가 수 백 기가바이트의 라이트맵이라도 64MB의 비디오 메모리만 있으면 돌릴 수 있기 때문에 걱정 마시고 라이트맵 해상도를 높이시기 바랍니다.

Graph_7

큐브맵 스트리밍

Granite는 다른 텍스쳐와 같이 큐브맵 또한 다룰 수 있습니다. 그냥 여러분의 .DDS 파일을 선택하고 타일셋 스튜디오에서 cubemap 박스를 선택하시기 바랍니다. Granite는 여러분이 언리얼 엔진에 여러분의 타일셋을 임포트 할 때 자동으로 GraniteTextureCube 오브젝트를 생성합니다. 여러분은 이 스트리밍되는 큐브맵을 보통의 큐브맵처럼 사용하시면 됩니다.

텍스쳐 압축

Granite는 DXT1, BC5 or BC7같은 블럭 기반 포맷보다 60퍼센트까지 더 압축할 수 있는 능력이 있습니다. 텍스쳐 맵마다 압축률을 구분할 수 있습니다.(낮음, 중간, 높음, 무손실) ‘낮음’ 과 ‘중간’ 은 디스크에서 아주 작은 크기를 차지하게 되고 더 좋은 스트리밍 퍼포먼스를 보입니다. ‘높음’ 압축률 설정은 좋은 품질을 유지하면서도 평균적으로 60퍼센트의 압축률을 보입니다. 이 설정으로 효과적인 스트리밍과 줄어든 디스크 용량을 차지합니다.

간결한 퍼포먼스 조절

어떠한 3D 엔진에서라도 사용될 수 있도록, Granite는 저사양 하드웨어에서부터 고사양 하드웨어까지 조절을 할 수 있도록 디자인 되었습니다. 전형적인 시나리오에서 Granite는 512MB의 비디오 메모리를 1080p에서 랜더링할 때 필요로 합니다. 캐시 사이즈를 더 크게 설정하는 것은 Granite가 안 보이는 데이터를 처리하는 것을 돕도록 합니다. 더 많은 캐싱은 더 많은 메모리를 사용하는 대신에 시스템의 부하를 줄여 줍니다. 하지만, 심지어 여러분이 레벨에 엄청난 양의 텍스쳐를 올리게 될 때에도 꼭 필요한 설정은 아닙니다. 예를 들어, 여러분이 256MB의 메모리를 갖는 저사양 기기만을 갖고 계시다면, Granite는 자동으로 텍스쳐 해상도를 낮춰서 안정적인 퍼포먼스를 유지시킵니다. 여러분은 텍스쳐 설정을 수동으로 변경하지 않으셔도 됩니다.

동일한 스케일링 시스템은 일시적으로 더 적은 데이터를 스트리밍 하도록 통제될 수 있습니다. 예를 들어, 여러분이 카메라라 빨리 움직일 때 모션 블러를 사용하고 계시다면, 여러분은 다시 블러가 될 것이기 때문에 최상단 레벨의 밉맵을 로드 할 필요가 없어집니다. 이러한 설정은 여러분이 빠르게 움직이는 카메라와 함께 위 예제에서 보듯 별 차이 없이도 4에서 16배나 더 적은 스트리밍이 가능하도록 해 줍니다.

또 다른 설정은 Granite가 프레임마다 얼마나 많은 데이터를 스트리밍 할 수 있는지를 조정할 수 있습니다. 특히나 여러분이 높은 프레임 레이트를 목표로 하신다거나, 게임의 다른 서브시스템을 위해서 여유를 두려는 경우 유용합니다. 이런 설정을 낮추는 것은 Granite가 프레임 당 더 적은 리소스를 사용하는 것을 확실히 하고, 특히 여러 프레임에 걸쳐서 작업을 실시하도록 합니다. 아래에는 각 텍스쳐 로드가 피크인 순간 더 많은 딜레이가 걸릴 수 있음을 보여주는 그림입니다.

결 론

텍스쳐 스트리밍에 관해서 언급할 때, 사람들은 본능적으로 커다란 오픈월드를 떠올립니다. Granite는 역시 이를 위한 좋은 솔루션이긴 하지만, Unreal은 이 분야에서는 그 자체로 훌륭하게 동작합니다. Granite는 아주 밀집된 씬에 아주 많은 독특한 텍스쳐들이 있는 곳에서 빛을 발합니다. 대부분의 경우, 모든 오브젝트의 일부분만이 눈에 보이게 되고, Granite는 이 부분의 텍스쳐만을 로드함으로써 그 장점을 발휘합니다. 이러한 접근 방식 때문에, Granite는 여러분이 거대한, 미리 구워진 분할 랜드스케이프 텍스쳐, 수 많은 조각 으로 나눠진 UDIM 텍스쳐를 사용할 때, 고화질 라이트 맵이나, 사진 측량용 스캐닝 등을 사용할 때 아주 좋은 솔루션입니다. 또한 오브젝트의 해상도를 4K 나 8K 텍스쳐로 튀거나 하는 등의 문제 없이, 기가바이트 급의 비디오 메모리 없이 올릴 수 있도록 해 줍니다.

Granite의 대부분이 가능하면 적은 리소스를 사용하도록 만들어 졌습니다. 게다가, 저희는 여러 파라미터를 입력받아서 여러분이 기기들 사이에서 퍼포먼스, 메모리 사용, 디스크 사용과 렌더링 품질 등을 조절할 수 있도록 하였습니다. 이 방법으로 여러분은 현재 보유한 기기에서 가능한 최고의 품질을 얻으실 수 있습니다. 이 것은 특히나 초당 고정 90프레임이 결정적인 VR에 중요합니다. 사람들이 Granite를 VR에 어떤 방식으로 사용하는가가 기대됩니다. 그래픽카드의 대역폭에 제한이 없다면, 텍스쳐 품질을 올리는 것은 프레임레이트에 영향을 주지 않으며 섬세함을 더할 수 있는 아주 멋진 방법입니다.

언리얼 업데이트에 따른 Granite에서, 저희는 더 기능이 많은 언리얼용 Granite SDK를 내 놓았습니다. 예를 들어, 향후 릴리즈는 퍼포먼스에 더 많은 설정을 할 수 있습니다. 저희는 Granite를 언리얼 라이트맵 시스템에 연결하였고, 저희는 언리얼의 지형 시스템을 들여다보고 있습니다. 언리얼 용 Granite는 하이트맵과 디스플레이스먼트 맵을 지원합니다. 저희는 곧 자동 지형 지원 시스템을 추가할 것입니다.

저희는 계속 새로운 기능을 고객의 필요에 따라 추가하고 있습니다. 그러므로, 여러분께서 원하시는 기능에 대해 이야기 해 주시기 바랍니다. 저희는 여러분이 커뮤니티를 통해 주시는 피드백을 기다리고 있습니다.! Granite를 사용하여 본 적이 없으신 분들은 여기에서 체험판 버전을 사용하여 보시기 바랍니다.