Graphics Programming

[Marco Scabia] 01 스테이지 3D는 어떻게 작동하는가 본문

Season 1/플래시

[Marco Scabia] 01 스테이지 3D는 어떻게 작동하는가

minseoklee 2011. 10. 7. 07:59

어도비에서 플래시 플레이어 11을 내놓으면서 Marco Scabia가 작성한 튜토리얼입니다.
열 편 정도 연작 기획이지만 아직 1편만 있습니다. 이 글은 1편을 번역한 것입니다.
http://www.adobe.com/devnet/flashplayer/articles/how-stage3d-works.html

관련 주제의 다른 글들은 여기서 볼 수 있습니다
http://www.adobe.com/devnet/games.html

-- 하면 할 수록 ----------------------------------------------------------------
------ 막 졸리고 ---------------------------------------------------------------
---------- 잠은 자야겠고 -------------------------------------------------------
--------------- 교정은 포기하고 ------------------------------------------------
-------------------- 안녕 여러분 -----------------------------------------------

Stage3D로 작업하기에 대한 시리즈의 이 첫 튜토리얼에서 여러분은 플래시 플레이어 11에서 어도비가 새로 소개하는 액션스크립트 API를 배울 것입니다. 이 API로 여러분은 플래시에서 하드웨어 가속되는 3D 렌더링의 득을 볼 수 있습니다. 이 튜토리얼에서는 Stage3D가 무엇이고 어떻게 작동하는 지에 대한 개요를 잡습니다. 또한 액션스크립트를 써서 정점 버퍼와 인덱스 버퍼를 가지고 간단한 Stage3D 기하 구조를 만들 것입니다.

Stage3D 이해하기

지난 몇 년간 개발자들은 플래시에서 3D를 이용해 여러 놀라운 프로젝트를 만들었습니다. Papervision3D, Away3D, Alternativa3D 같은 3D 엔진과 이들 엔진으로 만든 그 모든 훌륭한 애플리케이션들이 플래시에서의 실시간 3D 렌더링에 대한 요구를 보여줍니다.

이전에는 플래시 3D 렌더링을 3D 하드웨어 가속 없이 수행했습니다. 사실 버전 11 이전의 플래시 플레이어에서는 CPU로 렌더링하는 소프트웨어 모드를 써서 모든 3D 렌더링을 하였습니다. 소프트웨어 모드는 느리고 정밀한 3D 장면을 그리는 데는 쓸 수 없습니다. 요즘 3D 게임에서 흔히 보는 고급 그래픽 이펙트를 넣는 일은 쉽지 않았습니다.

플래시 플레이어 11의 출범으로 이제 새 가능성이 열렸습니다. 개발자들은 렌더링을 위해 컴퓨터의 CPU에 기대는 대신 3D 하드웨어 가속을 극대화할 수 있습니다. 새로운 렌더링 방법으로, 플래시 3D 내용을 이차적인 프로세서, 컴퓨터의 비디오 하드웨어의 일부인 Graphics Processing Unit(GPU)가 처리하게 할 수 있습니다. GPU는 오로지 3D 내의 물체를 렌더링하기 위한 전용 하드웨어입니다.

Stage3D로 작업하기

Stage3D는 어도비가 최근에 내놓은 새로운 플래시 API입니다. 이것은 실시간 3D 렌더링 전용입니다. Stage3D로 여러분은 플래시에서 사용자 컴퓨터의 GPU가 가진 하드웨어 가속 능력을 마음껏 누릴 수 있습니다.

Stage3D 출시는 플래시 개발자들에게 커다란 사건입니다. 플래시에서 3D 가속을 쓸 수 있게 되어 기존에는 불가능했던 많은 가능성이 플래시 게임과 애플리케이션에 열렸습니다.

3D 하드웨어 가속이 네이티브 플랫폼용으로 처음 나왔을 때를 생각하시면, 그게 3D 코딩 세계를 어떻게 영원히 바꿔버렸는지 기억할 것입니다. 게임의 품질과 복잡도는 폭발적으로 증가했습니다. 하드웨어 가속은 복잡한 모델, 실사 효과, 그럴 듯한 게임 플레이를 위한 번개같은 렌더링을 가능하게 하여 3D 게임을 아주, 아주 향상시켰습니다.

시장 점유율이 98%를 넘어가는 시점에서 플래시 플레이어는 유비쿼터스입니다. 플래시로 개발된 게임과 애플리케이션은 세계의 거의 모든 컴퓨터에서 즉시 사용할 수 있습니다. 사용자는 브라우저에서 게임의 URL을 입력하고 즉시 그 게임을 플레이합니다. 이미 대부분의 브라우저에 설치된 플래시 플레이어를 제외하면 사용자는 아무 것도 설치하지 않아도 됩니다. 특수한 런타임 라이브러리, OS 버전, 특정 하드웨어가 필요할 일은 없습니다.

플래시 플레이어의 편재와 3D 하드웨어 가속은 3D 가속 하드웨어의 도입 이후 컴퓨터 게임계에 급속한 혁명이 일어난 것과 비슷하게 온라인 게임 플레이를 아주 바꿔버릴 강력한 조합입니다.

오늘날의 2D 플래시 웹사이트를 생각해보십시오. 그리고 머지않아 3D 세계의 3D 경험으로 바뀔 것을 상상해 보십시오. 사용자는 자신이 탐험하는 환경에 몸을 담글 수 있습니다. 그런 미래에서는 대부분의 웹사이트가 그저 2D 경험을 제공하지 않고 상호작용하는 3D 물체가 있는 비디오 게임과 결합할 것입니다.

이 모든 것이 Stage3D에 관한 것입니다. 요즘 어느 컴퓨터에나 있는 3D 하드웨어를 최대한 이용하여, 인터넷에 연결된 어느 단일 컴퓨터에서나 3D 게임과 3D 인터랙티브 웹사이트를 쉽게 경험하기 위한 것입니다.

3D 하드웨어 가속과 일하기

이 절에서는 3D 하드웨어 가속을 받아 플래시 내용을 렌더링하기에 관한 개요를 봅니다. 

3D 하드웨어 가속은 요즘에는 모든 컴퓨터에 들어있는 아주 진보된 하드웨어 GPU를 이용합니다. GPU는 전적으로 3D 내용을 그리는 작업에 맞춰졌습니다.

여러분의 플래시 애플리케이션은 단지 3D 장면을 기술하게 될 것입니다. 애플리케이션은 3D 장면 데이터를 GPU 하드웨어에 넘기고 하드웨어는 데이터를 처리하여 장면을 그립니다. 이 과정은 소프트웨어 모드 렌더링을 써서 CPU로 3D 내용을 그리는 것보다 훨씬 빠릅니다.

잠시 소프트웨어 모드 렌더링과 하드웨어 모드 렌더링의 차이를 짚어보겠습니다.

대강 말하자면 3D 장면은 3D 기하 구조(메시)들의 집합으로 정의됩니다. 각 기하 구조는 삼각형의 집합으로 기술되고 각각의 삼각형은 정점들로 구성됩니다. 그러니 3D 장면을 정의한다는 것은 단순히 정점들의 집합을 정의하고 텍스쳐나 정점 색상 같은 관련된 렌더링 정보를 더함을 뜻합니다.

여러분이 예전의 소프트웨어 모드에서 작업했을 때 Away3D 같은 3D 엔진은 이 정점들의 목록을 받았을 것입니다. Away3D는 삼각형들의 화면 위치를 계산하고 플래시 플레이어에게 이 삼각형들을 채움 명령을 통해 하나씩 그리도록 네이티브 명령을 내렸을 것입니다.

이 과정은 엔진 내에서 영리하게 코딩되긴 했지만 극히 느렸습니다. 어떤 경우에는 렌더링 결과가 특히 부정확했습니다. 내용은 픽셀별이 아니라 삼각형별로 렌더링되었고 이는 깊이 정렬 오류를 유발했습니다. 삼각형은 제자리를 벗어나 잘못된 깊이에 렌더링되곤 했습니다.

통계를 대보자면 플래시 플레이어 10에서 소프트웨어 모드가 용납할 만한 수행능력을 유지하며 장면을 렌더링할 수 있는 최대치는 삼각형 4000개였습니다.

이제 Stage3D의 가능성을 고려해봅시다. 3D 하드웨어 가속을 사용하면, 소프트웨어는 그저 기하 구조를 정의하고 컴퓨터의 GPU에 넘깁니다. 기하 구조는 GPU 메모리에 적재되는데 이 메모리는 비디오 하드웨어에 상주하여 GPU가 사용하게 됩니다. GPU는 그 데이터를 받고 처리하여 3D 내용 렌더링을 완전히 처리합니다.

소프트웨어는 GPU가 렌더링하는 데 필요한 매개변수만 넘기면 됙 때문에 더욱 효율 높게 작동합니다. 예를 들어 시점(3D 카메라)이 3D 장면 내 어디에 위치했는지 기술하는 소프트웨어는 장면 내 빛의 위치, 3D 물체에 대한 다른 세부 사항과 장면 내 효과를 설정합니다.

GPU는 이 모든 데이터를 받습니다. 정의된 정점들을 분석하는 것으로 시작하고 삼각형을 하나씩 그려가며 장면을 렌더링합니다. GPU는 화면에 표시할 준비가 된 최종 이미지를 만들어냅니다.

GPU 렌더링 과정은 소프트웨어 모드보다 아주 빠릅니다. GPU는 아주 구체적인 작업에 초점을 맞추어 설계되었습니다. GPU는 정점을 계산하고 삼각형을 그립니다. 이게 다입니다.

GPU의 하드웨어가 이런 아주 한정된 작업에 극히 특화되었기 때문에 하드웨어 가속 3D 렌더링 과정은 극도로 효율적입니다.

반면에 CPU는 범용 프로세서입니다. CPU는 삼각형 렌더링이라는 특정 작업에 최적화되지 않았습니다. 그래서 렌더링 작업에 훨씬 효율이 떨어지는데 소프트웨어 모드로 플래시 3D 내용을 렌더링할 때 여러분이 이미 겪어봤을 것입니다.

수치를 비교하자면, 하드웨어 가속을 쓰면 백만 삼각형 이상을 포함하는 장면을 그리는 것은 특이한 일이 아닙니다. 소프트웨어 모드에서 4000 삼각형을 그리는 것에 비하면 극명한 향상입니다.

3D 렌더링 파이프라인 분석하기

하드웨어 기반 3D 렌더링은 3D 렌더링 파이프라인에 의해 가능합니다. 파이프라인이라는 낱말은 렌더링 과정이 기본 연산들의 집합으로 분리됨을 뜻합니다. GPU는 일련의 블록으로 구성됩니다. 각 블록은 이 기본 연산들 중 하나에 특화되어 있습니다. 블록들은 폭포처럼 구성되어 각 블록의 출력이 다음 블록의 입력이 됩니다.

초기에 출시된 3D 그래픽스 렌더링 파이프라인은 고정 기능 파이프라인이라 불렀습니다. 고정이라는 낱말은 어떤 방식으로든 프로그래밍하기가 불가능한 파이프라인이라는 사실을 나타냅니다. 고정 기능 파이프라인은 뭔가 뻣뻣한 것이였는데, 단순히 기하 데이터를 입력으로 받아 파이프라인 블록을 거쳐 데이터를 처리하고 최종 출력 이미지를 만들어냈기 때문입니다.

그림 1. 고정 기능 그래픽스 파이프라인의 블록들

고정 기능 파이프라인을 가지고 작업하려면 GPU에 기하구조 설명(정점과 삼각형), 기하 구조에 적용할 텍스쳐, 3D 장면 내에서 기하 구조의 위치와 방향, 시점(3D 카메라)의 위치와 방향, 조명(얼마나 많고 색상은 무엇이며 어느 위치에 있는지), 렌더링을 어떻게 할지를 기술하는 데 필요한 추가적인 매개변수들을 입력으로 넣어야 합니다.

달리 말하자면 예전 시스템을 쓸 때 여러분은 하드웨어에 정점 / 삼각형 / 텍스쳐 데이터의 집합을 매개변수 모음과 함께 넘기고 3D 하드웨어는 그것을 그립니다.

고정 기능 파이프라인은 정점을 로컬(모델) 공간에서 화면으로 사영하는 변환 및 조명 블록을 포함합니다. 이 블록은 정점별 조명도 적용합니다. 이 블록 다음에는 뷰포트 절단체 블록이 사영된 내용 중 실제로 보이는 내용만 잘라내어 화면상 뷰포트의 형식에 맞춥니다.

사영, 절단된 데이터는 파이프라인을 나와 래스터라이저 단계로 돌입합니다. 이 단계에서는 텍스쳐 맵핑을 수행합니다. 마지막에는 안개, 알파 블렌딩 효과를 적용하고 삼각형 픽셀들을 깊이가 바르게 정렬된 채 렌더링하는 데 필요한 깊이 버퍼링 테스트를 수행합니다.

이제 고정 기능 파이프라인은 수 년간 잘 작동했지만 시간이 지남에 따라 이 렌더링 과정이 조금 융통성이 없게 되었습니다. 특히 조명을 고려하여 렌더링은 기본 Goraud나 Phong 같은 표준 셰이딩 모델만을 써야 했습니다. 고정 기능 파이프라인은 개발자들이 창조적으로 즐겁고 흥미로운 효과를 추가할 만큼 유연하지 않았습니다. 많은 경우 렌더링은 똑같아 보였습니다.

그리고 프로그래밍 가능한 그래픽스 파이프라인이 도입되었습니다. 프로그래밍 가능한 그래픽스 파이프라인의 블록 도표는 렌더링을 위한 새 공정을 설명합니다. (그림 2를 보십시오)

그림 2. 프로그래밍 가능한 그래픽스 파이프라인의 블록들
 
정점 셰이더와 단편 셰이더라는 두 블록이 추가된 것이 새 시스템의 큰 차이점입니다. 이 두 블록은 프로그래밍할 수 있어서, 여러분이 프로그래밍 가능한 파이프라인을 써서 애플리케이션을 작성할 때 셰이더라는 코드 조각을 작성하여 렌더링 파이프라인 안에서 일어나는 일에 영향을 줄 수 있습니다.

보기에는 작아 보이는 셰이더 도입이라는 이 변화로 인해 3D 렌더링 세계의 모든 것이 변했습니다.

정점을 변환하고 수정하는 데 영향을 주고(정점 셰이더) 삼각형 픽셀 색상을 그리는 데 영향을 주는 작은 프로그램(단편 셰이더)을 작성하여 전에는 그릴 수 없던 놀라운 효과를 제작할 수 있게 되었습니다. 예를 들어 셰이더를 사용하여 여러분은 온갖 종류의 조명 기법을 적용할 수 있습니다. 파이프라인이 제공하는 기본 조명 대신 특정 애플리케이션을 위한 맞춤형 프로그램을 만들 수 있게 된 것입니다. 셰이더로 인해 그림자, 하드웨어 가속 뼈대 시스템, 그 외 많은 멋진 효과가 가능해졌습니다.

이 튜토리얼 시리즈의 뒷부분에서는 셰이더와 프로그래밍 가능한 렌더링 파이프라인으로 작업하는 방법을 배울 것입니다. 하지만 지금은 Stage3D가 전적으로 프로그래밍 가능 기능 파이프라인에 기반한다는 것을 알아두는 게 중요합니다. 고정 기능 파이프라인을 선택할 옵션조차 없습니다. 셰이더의 프로그래밍 가능함을 이용하여 그래픽스 하드웨어의 모든 힘을 이용할 수 있기 때문에 이건 이득입니다. 여러분은 이제 플래시 3D 프로젝트에서 놀라운 효과를 제작할 수 있습니다.

힘에는 책임도 뒤따릅니다. 가장 간단한 렌더링을 할 때에도 여러분 고유의 셰이더를 짜야 합니다. 프로그래밍 가능한 렌더링 파이프라인을 쓸 때 여러분은 고정 기능 파이프라인을 쓸 때와 달리 단순히 매개변수 몇 개를 설정하고 장면을 그릴 수 없습니다.

Stage3D로 작업하기의 장점과 제한 비교하기

이 절에서는 표준 네티이브 플랫폼 3D API인 OpenGL과 DirectX와 비교하여 Stage3D로 작업할 때 얻는 이점을 배웁니다. OpenGL과 DirectX는 십수 년간 쓰였습니다. 이것들은 현대 컴퓨터에서 멋진 게임을 제작하는 데 쓰이는 주류입니다.

시작하자면 DirectX와 OpenGL로 3D 애플리케이션을 만드는 것은 쉬운 일이 아닙니다. 간단한 삼각형을 그리는 것은 상당히 직관적이지만 C++에서 완전한 3D 애플리케이션을 만들려면 상당한 기술이 필요합니다. 확실히 비숙련자 프로그래머가 할 만한 작업은 아닙니다.

네이티브 3D 애플리케이션을 제작할 때의 문제점 중 하나는 표준 DirectX와 OpenGL API를 쓰는 것입니다. 개발자에게 그래픽스 하드웨어의 모든 능력을 제공하기 위해 프로젝트는 하드웨어에 한정된 모든 선택 사항을 제공해야 합니다. 네이티브 API는 하드웨어에 아주 가깝습니다. 개발하면서 여러분은 애플리케이션을 실행하고 있을 때 특정 GPU의 하드웨어 능력을 처리해야 합니다. 그리고 하드웨어를 최대한 써먹기 위해 종종 코드를 튜닝해야 합니다. 더욱 진보된 하드웨어에서는 더욱 놀라운 효과를 만들 수 있기 때문에 개발자에게는 이익이지만 여러 다른 하드웨어에서 애플리케이션을 튜닝하고 테스트해야 함을 뜻합니다.

Stage3D로 작업할 때는 전혀 관련 없는 이야기입니다. 여러분은 그저 Stage3D의 추상화인 Context3D와 Program3D로 코딩하고 여러분의 애플리케이션은 플래시 플레이어(또는 AIR 런타임)을 지원하는 모든 플랫폼에서 실행될 것입니다.


물론 각 플랫폼마다 사용 가능한 특정한 능력의 이점을 얻기 위해 특정 하드웨어를 겨냥할 수 없기 때문에 다소 불이익도 있습니다. 여러분은 그저 가상의 Stage3D 플랫폼에 대해 범용적으로 코딩하고 Stage3D는 여러분의 코드와 실제 하드웨어 사이에서 중간층으로 작동합니다. 

Stage3D의 큰 장점은 한 애플리케이션 내에서 3D 하드웨어 가속 코드와 일반 2D 플래시 저작물을 결합할 수 있다는 것입니다.

네이티브 3D 애플리케이션을 만들 때, 2D UI를 만들려면 거진 플래시만큼 유연한 저작 도구 없이 저마다 해결책을 마련해야 했습니다. 

Stage3D를 쓰면, 일반적인 플래시 2D 내용과 Stage3D 내용이 공존합니다. 따라서 여러분은 플래시의 모든 능력과 더불어 3D 가속 내용도 얻는 것입니다. 배경에 주 3D 장면을 만들거나 2D의 일부인 작은 3D 아이템을 포함하는 것 중 선택할 수 있습니다.

Stage3D 애플리케이션은 다수의 플랫폼에서 실행될 수 있습니다. 여러분은 Stage3D 애플리케이션을 플래시 플레이어뿐 아니라 AIR 애플리케이션으로서도 실행할 수 있습니다. 이 능력은 여러분이 Stage3D를 써서 데스크탑용 3D 게임을 만드는 것과 비슷하게 데스크탑 3D 애플리케이션을 만들 수 있음을 뜻합니다. 결국 같은 코드를 가지고 애플리케이션을 iOS나 안드로이드 같은 모바일 플랫폼에 배포할 수 있게 될 것입니다. 플래시 플레이어 설치 기반의 높은 점유율을 고려하면 Stage3D 애플리케이션이 얼마나 널리 퍼질 지 쉽게 상상할 수 있습니다.
 
Stage3D의 한계 인식하기

주된 결함은 여러 플랫폼을 위해 한 애플리케이션을 개발하는 능력에 있습니다. 단일 API를 가지고 모든 플랫폼을 겨냥하기 때문에 Stage3D는 가장 강력한 3D 그래픽스에서만 나오는 발달된 특성에서 이득을 얻을 수 없습니다.

한 애플리케이션이 어디에든 적합함을 보장하려면 Stage3D는 겨냥한 모든 플랫폼에서 공통 분모인 그래픽스 능력들을 뽑아 3D 하드웨어 장치를 추상화해야 합니다.

예를 들어 현대 GPU 하드웨어는 셰이더 모델(정점 셰이더와 단편 셰이더에서 쓰는 표준) 4.0을 지원합니다. 하지만 Stage3D는 셰이더 모델 2.0을 지원합니다.

이는 여러분이 Stage3D에서 코딩할 때 보다 첨단 하드웨어에서는 맞닥뜨리지 않을 한계에 부딪힘을 뜻합니다. 예를 들어 AGAL 같은 셰이딩 언어로 등록할 수 있는 셰이더 레지스터의 수는 아주 한정적입니다. 임시 레지스터는 최대 8개인데 GLSL에서 셰이더 모델 4.0을 가지고 코딩할 때는 4096개를 쓸 수 있습니다.

Stage3D 셰이더는 OpCode를 200개까지만 포함할 수 있지만 셰이더 모델 4.0은 4096개를 지원합니다. Stage3D 셰이더는 조건문이나 루프를 지원하지 않지만 셰이더 모델 3.0과 4.0은 지원합니다.

달리 말하자면 Stage3D의 셰이더는 더욱 발달된 하드웨어와 셰이더 모델에 반하여 아주 간단한 프로그램으로 설계되었습니다. 결국 오늘날의 AAA급 게임에서 셰이더를 이용한 고급 효과 일부를 Stage3D에서는 볼 수 없을 것입니다.

Stage3D: Stage 뒤의 무대

이 절에서는 Stage3D가 어떻게 플래시 표시 모델에 섞이는지 배웁니다. 

플래시는 Stage라는 개념에 기반하여 설계되었습니다. 플래시에서 표시되는 모든 객체는 Stage에 추가된 DisplayObject입니다. 따라서 Stage는 표시되는 모든 것의 컨테이너입니다. Stage는 모든 2D 아이템의 뿌리입니다.

어도비는 플래시에 3D 렌더링을 도입할 때 특별히 3D를 위해 설계된 특수한 Stage들의 집합을 추가했습니다. 이 특별한 Stage들을 Stage3D라 부릅니다. (그림 3을 보세요)

그림 3. Stage3D가 Stage 뒤에서 어떻게 스테이지로서 표시되는지 이해하기
 
일련의 Stage3D 스테이지가 메인 플래시 Stage 뒤에 있습니다. 이는 여러분이 Stage3D로 제작한 3D 내용은 각각의 Stage3D의 직사각형 뷰포트에 그려짐을 뜻합니다. 일반적인 2D 플래시 내용은 이 모든 것의 위에 나타납니다. 하드웨어 가속을 이용하여 3D 장면을 렌더링하고 2D인 것(게임 UI 같은)들을 그 위에 올려놓는 식으로 둘의 이점을 모두 취할 수 있습니다. UI는 직접 만든 UI 생성 도구로 작업할 필요 없이 플래시의 힘과 유연성을 사용하여 제작할 수 있습니다.

여러분이 쓸 수 있는 Stage3D는 여러 개입니다. 각 Stage3D는 자신만의 직사각형 뷰포트를 가집니다. 이는 여러분이 화면의 한 지점에 직사각형 3D 영역을 두고 다른 곳에는 다른 영역을 둔 다음 이 둘의 위에 플래시 2D 객체를 놓을 수 있음을 뜻합니다. 다양한 Stage3D와 StageVideo 층이 부분적으로 (심지어 완전히) 겹칠 수도 있습니다. 하지만 이번에 첫 출시된 Stage3D에서는 레이어간 블렌딩을 지원하지 않습니다. 따라서 Stage3D 층이 다른 Stage3D 층을 덮으면 위의 층만 볼 수 있습니다.

액션스크립트로 Stage3D에 접근하기

액션스크립트 코드로 Stage3D API에 접근하려면 Stage3D 스테이지 하나를 선언해야 합니다. 스테이지들은 플래시의 주 스테이지에 속한 한 배열을 통해 접근할 수 있습니다.
 
이런 코드를 작성하면

var stage3D:Stage3D = stage.stage3Ds[0];

Stage3D API의 주된 클래스는 Stage3D 자체가 아니라 Context3D라는 클래스입니다.

Context3D는 Stage3D를 사용할 때 작업하게 될 주 요소입니다.

여러분이 Stage3D 객체로 처음 할 일은 Context3D 객체를 요청하는 것입니다.

stage.stage3Ds[0].addEventListener( Event.CONTEXT3D_CREATE, initStage3D );
stage.stage3Ds[0].requestContext3D();
...
protected function initStage3D(e:Event):void
{
context3D = stage.stage3Ds[0].context3D;
}

정점 버퍼와 인덱스 버퍼로 기하 구조 정의하기 

Stage3D에서 여러분이 그릴 3D 장면은 기하 구조(3D 메시)의 집합으로 구성됩니다. 각 기하 구조는 삼각형의 집합으로 정의됩니다. 각 삼각형은 정점의 집합으로 정의됩니다.

기하 구조를 기술하는 모든 정점은 정점 버퍼라는 구조 안으로 들어갑니다. 이 구조는 정점에 관계된 모든 데이터를 포함합니다. 이 모든 데이터를 함께 묶어두면 GPU 메모리에 한 방에 적재할 수 있기 때문에 유용합니다.

이것은 정점 버퍼 정의의 예입니다.

var vertices:Vector.<Number> = Vector.<Number>([
-0.3, -0.3, 0, 1, 0, 0, // x, y, z, r, g, b
-0.3, 0.3, 0, 0, 1, 0,
0.3, 0.3, 0, 0, 0, 1,
0.3, -0.3, 0, 1, 0, 0]);

먼저 Vector에 모든 정점을 정의합니다. 각 정점은 위치뿐이 아니라 그 정점의 속성을 기술하는 추가적인 데이터도 포함합니다. 각 정점 구조의 이 필드들을 정점 속성(attribute)이라 합니다.

정점 속성은 렌더링 파이프라인이 기하 구조를 어떻게 그릴 지를 기술하는, 기하 구조 관련 데이터를 포함할 수 있습니다. 예를 들어 정점 색상이나 텍스쳐 UV 좌표는 정점 속성으로서 기술됩니다.

위의 예제에서 vertices 벡터는 네 정점을 정의합니다. 각 줄마다 정점이 있고 각 정점은 위치(처음 세 원소), 색상(나머지 세 원소) 두 정점 속성을 포함합니다.

이 벡터를 만든 후에는 VertexBuffer3D 인스턴스를 생성합니다. VertexBuffer3D는 Stage3D API의 클래스인데 정점 버퍼 데이터를 Stage3D API로 감싸 정점 버퍼를 GPU 메모리에 적재합니다.

이 코드가 그런 일을 합니다.

// 네 정점, 각각 여섯 숫자
vertexbuffer = context3D.createVertexBuffer(4, 6);
 
// 오프셋 0, 정점 4개
vertexbuffer.uploadFromVector(vertices, 0, 4);

Stage3D에서 정점 버퍼를 기술하는 것만으로는 기하 구조를 정의하기에 충분하지 않습니다. Stage3D에서 3D 메시는 인덱스 붙은 메시로 정의되기 때문입니다.

삼각형을 정의하려면 삼각형의 세 정점을 적어줘야 합니다. 그러니 삼각형 기하를 정의하려면 정점 버퍼의 정점들에 인덱스를 붙여 삼각형으로 조립할추가 구조가 필요합니다. 이 구조를 인덱스 버퍼라 부릅니다.

위의 정점 버퍼가 네 정점을 정의한다는 것을 고려하여 목표가 두 삼각형으로 이루어진 정사각형을 정의하려는 것이라 상상해봅시다. 정점 버퍼의 네 정점은 그 자체로는 정사각형을 정의하는 두 삼각형을 정의하기에 충분하지 않습니다.

다음 코드로 추가적인 인덱스 버퍼를 생성합니다.

var indices:Vector.<uint> = Vector.<uint>([0, 1, 2, 2, 3, 0]);

이 코드에서 indices 벡터의 처음 세 요소 0, 1, 2는 첫 번쨰 삼각형이 정점 버퍼의 정점 0, 1, 2로 이루어진다는 것을 기술합니다. 그 다음 인덱스 버퍼는 정점 2, 3, 0이 이루는 두 번째 삼각형을 생성합니다.  

인덱스 버퍼를 사용하여 삼각형을 효율적으로 정의하고 기하 구조를 생성할 수 있습니다.

정점 버퍼와 마찬가지로 인덱스 버퍼도 Stage3D에 한정된 구조인 IndexBuffer3D로 감싸야 합니다. 이 IndexBuffer3D를 사용하여 GPU에 여러분의 인덱스 버퍼를 적재할 것입니다.

// 총 인덱스 6개. 세 정점이 이루는 두 삼각형
indexBuffer = context3D.createIndexBuffer(6);

// 오프셋 0, 개수 6
indexBuffer.uploadFromVector (indices, 0, 6);
 
이게 전부입니다. 기하 구조를 정의했습니다.

이제 어디로 가야 하나

이 시점에서 여러분은 Stage3D로 작업하기의 개요를 완수했습니다. 어도비가 출시한 새로운 강력한 API는 플래시 플레이어 11에서 하드웨어 가속 3D 렌더링을 가능케 합니다. 이 튜토리얼은 액션스크립트에서 Stage3D를 사용하는 것에 관한 튜토리얼 시리즈의 1편입니다. 다음 편에서는 Stage3D 셰이더로 작업하기를 설명합니다.

Stage3D를 더 배우려면 다음 온라인 자료들도 보세요.
 
Comments