본문 바로가기
공부하는 하스씨/Graphics

게임 개발의 꽃 DirectX10과 3D 그래픽스

by 박하스. 2008. 10. 11.
728x90
반응형
이번 글에서는 DirectX10(이하 DX10)이 게임 개발 방법에 어떤 영향을 주게 될지를 엔비디아 하드웨어 아키텍처와 DX10 샘플을 예로 들어 설명한다. DX10을 들어는 봤지만, 그 개발에는 익숙하지 않은 독자들이 이 글의 주 대상이 될 것이다. 그럼 DX10을 보다 잘 이해하기 위해 DX10용으로 개발된 GeForce8000 시리즈의 하드웨어 아키텍처 특성들을 먼저 살펴본다.


김크리스 chkim@nvidia.com|카네기멜론대 컴퓨터사이언스과를 졸업하고 현재 엔비디아 기술개발그룹 부장을 맡고 있다. 타이토 아메리카와 타임워너 인터렉티브, 니치멘그래픽스 등을 거쳤고 파이널판타지 7과 파라사이트이브, 마리오 64 개발 툴을 제작한 바 있다.


GeForce8000 시리즈는 비스타 출시에 맞춰 DX10에 특화된 것으로 기존 시리즈와 아키텍처가 완전히 달라졌다고 해도 과언이 아니다. 물론 DX10의 이전 버전인 DX9도 지원하지만, 여기서는 주로 DX10에 초점을 맞춰 아키텍처와 기능들을 설명하고자 한다. 이 글과 관련한 보다 자세한 내용과 샘플 코드는 http: // developer.nvidia.com에서 구할 수 있음을 미리 밝혀둔다.

GeForce8000 시리즈 아키텍처
이번 시리즈의 가장 큰 특징 가운데 하나는 통합(Unified) 세이더를 지원하기 위해 하드웨어 코어도 통합되었다는 점이다. 통합 세이더의 경우 각각의 세이더, 즉 버텍스 세이더와 픽셀 세이더, 그리고 이번에 새롭게 추가된 지오메트리 세이더가 기본적으로는 같은 기능을 지원한다고 보면 된다.
<그림 1>을 통해 GeForce8800 GTX를 기준으로 8개의 독립된 세이더 유닛을 볼 수 있다. 각각의 유닛마다 16개의 스트리밍 프로세서를 가지고 있으므로 총 128개의 스트리밍 프로세서를 가지고 있다. 특이한 점은 각각의 유닛은 필요에 따라 버텍스와 픽셀, 지오메트리 세이더 기능을 담당할 수 있다는 것이다.



통합 세이더는 일단 각 세이더가 명령어를 공유하므로 이를 따로 익힐 필요가 없고, 또한 필요한 만큼 자동으로 하드웨어에서 스케줄링을 하게 된다. 기존의 게임 개발자들은 정해져 있는 세이더 유닛 별로 퍼포먼스 프로파일링을 수행해 튜닝을 해야 했는데, 이때 하드웨어 버전별로 유닛들이 달리 구성되어 있어 튜닝이 매우 힘들었다. 이런 점을 감안하면 자동 스케줄링은 프로그래머의 부담을 크게 덜어줄 수 있다. 그러면 세이더 프로그래밍 모델의 버전 별로 어떤 차이가 나는지를 <표 1>을 통해 알아보자. 여기서 보듯이 DX10에서는 명령어 숫자와 Constant 개수가 크게 늘어난 것을 알 수 있다. 또한 각 유닛이 같은 코어에 기반하므로 버텍스 유닛과 픽셀 유닛이 거의 동일한 것도 특이하다.


DX10에서는 Cap Bits가 따로 존재하지 않는다. 기존의 Cap Bits는 하드웨어가 지원하는 기능을 파악할 수 있게 해주는데 Cap Bits는 메이커나 하드웨어 별로 모두 다를 수 있다. 이것이 오히려 개발 과정에서 더 많은 문제를 발생시키곤 했는데 DX10에서는 이를 지원하는 하드웨어는 기본적으로 모든 기능을 구현토록 했다. 아울러 DX10에서는 드라이버 오버헤드를 줄이기 위해 많은 노력을 했는데, 종전의 경우 아무리 빠른 GPU를 가지고 있더라도 드라이버 오버헤드 때문에 프레임 저하가 발생하는 경우가 적지 않았다.

마지막으로 가장 주목할 만한 부분은 바로 지오메트리 세이더로, 이는 종전에 GPU가 구현할 수 없었던 부분(즉 GPU에서 새로운 폴리곤을 생성토록 하는 부분)을 가능하게 한다. 그 밖에 추가된 사항들은 다음과 같다.

- 텍스쳐 어레이: 텍스쳐 어레이를 사용하면 텍스쳐 한 장에 가능한 많은 조각들을 넣는 기존 방식(Texture Atlas 방식)을 사용하지 않아도 빠르고 쉽게 텍스쳐를 저장할 수 있다. 텍스쳐 어레이도 기본적으로는 한 장의 큰 텍스쳐로서 인덱싱 방식에 접근할 수 있게 했기 때문이다.

- 정수연산 및 인덱싱:
기존의 세이더는 부동소수점 연산만 가능해 인덱싱을 사용하기 쉽지 않았다. 그러나 이제는 정수를 지원하므로 인덱싱이 자유롭고, 정수연산과 비트연산이 가능하다.

- 버추얼 비디오 메모리:
늘어나는 그래픽 리소스를 지원하기 위해 비디오 메모리보다 더 많은 리소스를 사용할 수 있게 되었다. 또한 기존에는 디바이스가 리셋 될 때 그래픽스 리소스를 재생성해야 했지만, 드라이버에서 관리를 하므로 이제 따로 관리할 필요가 없다. 시스템 메모리 상의 버추얼 메모리를 사용하므로 사용할 수 있는 리소스양에도 거의 제한이 없다.

- MRT(Multiple Render Target)
: MRT가 4개에서 8개로 늘어났다. 게임에서 포스트 프로세싱 이펙트를 점차 많이 사용하는 추세이므로 한번에 렌더링 하는 숫자도 크게 늘었다. 특히 라이팅과 관련해 육면체에 렌더링 하는 경우가 다수 생길 수 있다. 6개 이상의 MRT를 필요로 해 이전에는 여러 번에 나눠 렌더링을 해야 했지만 이제는 지오메트리 세이더의 도움으로 한번에 6면 이상 렌더링이 가능하다.

- 인스턴싱의 강화:
인스턴싱은 다수의 파티클이나 비슷한 오브젝트들을 한 번에 화면에 그리는 경우 유용하다. 기존의 경우 많은 객체를 동시에 렌더링 하려면 스트림을 따로 세팅해야 하는 등의 제약이 많았고, 퍼포먼스도 그다지 나아지지 않아 인스턴싱을 많이 사용하지 않았다. 하지만 이번에는 인스턴싱 기능이 강화되어 원래 의도대로 다수의 객체를 한 번에 쉽게 렌더링 할 수 있게 되었다.   

DX10 파이프라인
그럼 DX10의 특징에 대해 좀 더 자세히 살펴보자. 먼저 DX10의 파이프라인을 살펴보자. 각 세이더 유닛은 하드웨어가 통합되어 있어 동일한 명령어 체계를 사용함을 확인했다. 따라서 한 가지 예로 버텍스 세이더에서 텍스쳐를 액세스하는 것이나 픽셀 세이더에서 텍스쳐를 액세스하는 것이나 기본적으로 동일하다고 볼 수 있다. 기존의 DX9 SM 3.0도 버텍스 세이더에서 텍스쳐를 액세스 할 수 있었지만 기능 및 성능에서 큰 차이가 있다. 


지오메트리 세이더
DX10의 특징을 한 마디로 정의하라면 지오메트리 세이더의 추가를 꼽을 수 있다. 지오메트리 세이더는 CPU에서 주로 담당했던 기능, 즉 새로운 프리미티브(폴리곤, 라인, 버텍스)를 구현할 수 있어 CPU의 부하를 크게 줄일 수 있다. 반복 연산해야 하는 경우에는 CPU를 통하지 않고 GPU 내부에서 해결할 수 있으므로 경우에 따라선 수십 배에서 수백 배 빠른 실행결과를 보여준다.

또한 프리미티브를 생성하지 않을 수도 있으므로 프리미티브가 픽셀 세이더에 도달하기 전에 컬링이 가능하다. 따라서 단순히 CPU 부담을 덜어주는 것 이상으로 빠른 결과물을 보여줄 수 있다. 하지만 그렇다고 해서 이것이 무조건 좋은 것만은 아니다. 한 번에 생성할 수 있는 최대 버텍스가 1,024개라고 해도 지금의 하드웨어에서 1,024개를 한 번에 생성하는 것은 캐쉬의 제약으로 인해 작은 수의 버텍스를 여러 번으로 나눠 생성하는 것보다 더 큰 퍼포먼스 저하를 초래할 수 있다. 하지만 일반적인 사용에는 큰 지장이 없을 것이다.

따라서 지오메트리 세이더를 사용하기에 가장 적당한 애플리케이션으로는 파티클(버텍스 하나당 새로운 버텍스 4개)과 단순한 프리미티브 테셀레이션 등이 될 수 있다. 그러면 지오메트리 세이더의 구조에 대해 좀 더 자세히 알아보자. <그림 3>은 지오메트리 세이더에 입력 데이터로 들어올 수 있는 프리미티브를 보여준다.


프리미티브의 종류는 세 가지로 버텍스, 라인, 삼각형이 그것이다. 이 프리미티브 외에 주변(Adjacent) 버텍스 데이터도 함께 입력 데이터로 들어올 수 있다. 이 주변 버텍스 데이터는 새로운 프리미티브를 만들 때 유용하다. 예를 들어 커브라인을 만들기 위해서는 최소 4개 이상의 버텍스 데이터가 필요하므로 주변 버텍스 데이터가 반드시 필요할 것이다. 기본적으로는 세 종류의 프리미티브를 지원하지만 경우에 따라 4각형이나 그밖의 프리미티브가 필요할 수도 있다. 이런 경우에는 주변 버텍스를 적절히 사용한다.
지오메트리 세이더를 잘 사용하면 많은 수의 파티클들을 CPU의 도움 없이 시뮬레이션 하고 생성할 수 있으므로 좀 더 화려하고 복잡한 이펙트를 구현할 수 있다.
 
StreamOut과 인스턴스 ID

지오메트리 세이더는 StreamOut이라는 유닛이 있다. 이는 지오메트리 세이더에서 새로운 프리미티브를 생성해 다시금 버텍스 세이더나 지오메트리 세이더에서 버텍스 프로세싱을 가능하게 한다.

또한 이번에 추가된 기능 가운데 인스턴스 ID라는 것이 있다. 이를 이용하면 세이더 내부에서 프리미티브별로 ID값을 가져올 수 있고, 파티클이나 폴리곤별로 다르게 렌더링 할 수 있을 것이다. <그림 4>를 보면 폴리곤 컬러 값을 ID값으로 세팅했을 때 다른 색으로 렌더링 된 것을 볼 수 있다.


텍스쳐 어레이
텍스쳐 어레이는 한 장의 텍스쳐 안에 여러 개의 텍스쳐를 저장함으로써 손쉽고 빠르게 텍스쳐를 액세스 할 수 있다. 텍스쳐가 어떻게 저장되어 있는지는 <그림 5>를 보면 쉽게 알 수 있다.


텍스쳐 어레이는 인덱싱을 사용해서 각각의 어레이를 액세스하기 때문에 한 장의 텍스쳐 안에 여러 장의 텍스쳐를 포함하고 있는 것으로 보면 된다. 여기서는 텍스쳐를 따로따로 가지고 있는 것보다 한 장으로 가지고 있을 때 훨씬 더 빠르게 액세스할 수 있다는 점이 중요하다.

다시 말해 세이더에서의 액세스는 어레이 인덱스를 사용해 간단하게 이뤄지므로 작지만 많은 수의 텍스쳐를 사용해야 할 경우 유리하다. 게임 레벨 별로 또는 캐릭터 별로 비슷하지만 약간씩 다른 텍스쳐를 동시에 액세스 할 때 유용한 것이다. 예를 들면 보통 터레인에서 여러 개의 텍스쳐 레이어를 쓰는 경우가 많은데 이런 경우 텍스쳐 어레이를 사용하면 텍스쳐 한 장에 여러 개의 텍스쳐 레이어를 저장할 수 있다. 인스턴싱을 사용할 때 같은 모델 별로 약간씩 다른 텍스쳐를 사용하면 더 편리하다. 또한 텍스쳐 한 장에 여러 개의 조각난 형태로 저장하는 방식(Texture Altlas)을 대체할 수 있다.


Displacement Mapping과 Hair Growth
<그림 7>은 디스플레이스먼트(높이) 값이 저장되어 있는 텍스쳐를 사용해 실제 폴리곤을 GPU 내부에서 만든 예제이다. 왼쪽의 것은 노말 텍스쳐를 사용해 음각의 느낌은 살아있지만 실루엣 부분에서 음각 표현을 할 수 없었다. 이와 달리 오른쪽은 실제로 폴리곤을 생성해 실루엣 부분도 음각 부분이 제대로 표현되어 있다. 최근 1년 사이에 노말맵 사용이 보편화 된 것처럼 조만간 디스플레이스먼트 렌더링도 보편화될 전망이다.


또한 지오메트리 세이더에 입력되는 버텍스를 써서 라인 프리미티브를 생성하면 마치 헤어(hair)와 같은 느낌을 줄 수 있다.  <그림 8>의 왼쪽 그림이 입력되는 폴리곤에서 헤어를 추출해 렌더링 한 것이고, 오른쪽은 커브라인으로 변환한 그림이다. 이전에는 헤어를 CPU에서 만들어 CPU의 부하가 심했으나, 지금은 GPU 내에서 모두 만들어지므로 길이와 색깔, 그리고 애니메이션 효과까지 신속하게 표현할 수 있다. 


한편 직물 시뮬레이션은 다수의 수치계산 병렬처리를 요구하므로 GPU에서 처리하기에 적합하다. 뿐만 아니라 대부분의 경우 비주얼 효과로만 쓰이므로 CPU를 전혀 필요로 하지 않는다. 이 예제는 DX9에서 처음 소개되었는데, 버텍스 텍스쳐에 버텍스 데이터를 저장하고 픽셀 세이더에서 이를 액세스 및 업데이트 하는 과정을 거쳤다. 이는 필요 이상의 복잡한 과정을 거쳐야만 구현 가능했다.


이와는 다르게 DX10은 버텍스 텍스쳐를 사용하지 않는다. 단순히 버텍스 버퍼에 필요한 정보를 넣고 버텍스 세이더와 지오메트리 세이더를 사용해 시뮬레이션 한 후 새로운 버텍스 위치 값을 업데이트 하는 것이다. 따라서 좀 더 직관적이고 빠르게 직물 시뮬레이션을 구현할 수 있다.  



GPU 활용이 핵심
현재 GPU 발전 속도가 CPU 발전 속도보다 월등히 빠르므로 동일한 것을 구현하더라도 GPU를 최대한 활용하는 것이 중복 개발이나 추가적인 수정 작업을 줄여 제품의 라이프사이클을 길게 가져가는 데 유리하다. 따라서 GPGPU(General Purpose GPU)처럼 CPU를 GPU로 대체하려는 시도가 더욱 활발해질 것으로 기대된다.



출처 : 마이크로소프트웨어 웹진

728x90
반응형

'공부하는 하스씨 > Graphics' 카테고리의 다른 글

Frame Buffer 이야기 (4)  (0) 2008.11.26
Frame Buffer 이야기 (3)  (0) 2008.11.26
Frame Buffer 이야기 (2)  (0) 2008.11.26
Frame Buffer 이야기 (1)  (0) 2008.11.26
CG 기술의 진화! - VF5  (0) 2008.08.26