본문 바로가기

Starling

Starling 과 Image. 그리고 VertexData - 1.개념잡기




이것은 조금 무서운 이야기이다....





당신의 프로젝트는 Starling 엔진으로 제작되어 있다.


어느날 디자인을 담당한 분이 당신을 찾아와 말하길


" 여기서 이게 쨘 하고 나와서 쉬리릭 하면서 y축 회전을 하며 뒷면이 보여지는 겁니다! 간단하죠! "


라며 사각형 형태의 이미지 두장( 앞면, 뒷면 ) 을 던져 주었다.


플래시 짬밥을 좀 먹은 당신은 너무나 간단한 작업이라 생각하고 아무생각 없이 씨익 웃으며 대답했다.


"네 껌이죠. 이딴 건 수없이 많이 해봐서 발가락으로도 구현합니다."



그리고 한 5분쯤 있다가 깨닫는다.


어? rotationY 어디갔어?




그렇다. 실은 이건 내가 경험한 무시무시한 이야기이다. ㄷㄷㄷ 무시무시;



기존의 flash API ( 이하 네이티브API로 표현 ) 에선 DisplayObject 클래스의 rotationX, rotationY, rotationZ 속성들과


PerspectiveProjection 객체등을 이용해 느리든 어쨌든 3D 느낌이 나는 모션등을 쉽게 구현해내었다.



내부적으로야 어떻든 일단 API 레벨에서 지원해주었기 때문에


대다수의 플래시개발자는 이러한 기능을 어렵다는 생각을 하지 않았을 것이다. (최소한 타언어에 비해서는)


하지만 이제 직접 구현해야 한다.



자 당신은 어떻게 할 것인가?


진지하게 고민해보자. 


당신이라면 어떻게 이것을 Starling 에서 구현할 것인가?


.

.

.

.

.

.




몰라 시퀀스로 뽑아 


가장 쉬운 방법은 이미지가 회전하는 시퀀스를 뽑아 스프라이트시트로 만든 뒤 MovieClip 으로 재생하는 것이다.


이 방법은 매우 쉽지만 많은 제약이 있다.



a. 일단 한객체의 회전을 보여주기 위해 상당히 많은 추가 이미지들이 필요하다.

   이는 회전을 부드럽게 보여주고자 할수록 많아진다


b. 회전은 동적이지 않고 정해진 모션만을 취하게 된다.


c. 회전할 이미지의 디자인이 고정적이지 않고 각 상황에 따라 다양한 디자인의 이미지가 나와야 한다면

   추가되는 이미지마다 회전 시퀀스가 필요하고 당신도 울고 디자이너도 울고...


d. 만약 회전하는 방향이 바뀌거나 각도가 바뀐다면 당신은 또 울고 디자이너도 또 울고...



다른 방법은 없을까?







Starling은 2D 인가?



gpu 는 삼각형을 그리는데 매우 능률적이다.

고로 gpu 가속을 사용하는 Starling 역시 모든 것을 삼각형을 이용해 렌더링 한다.

하나의 면을 표현하기 위해서 2개의 삼각형이 사용되었다.  어디서 많이 본듯한 상황이다.

그렇다. 3D 와 같다.

사실 Starling 은 카메라뷰가 고정된 2D 같은 화면만을 보여기를 고려한 (plane으로만 이루어진) 3D라 볼 수 있다. 

화면을 렌더링하는 방식은 결국 3D 와 같다.






drawTriangles


이러한 방식은 Starling , stage3d 가 아닌 다른 곳에서도 사용되고 있다.


Graphics 클래스의 drawTriangles 는 버텍스,인덱스 정보를 받아 3차원 느낌을 주는 삼각형 집합을 렌더링하는 메소드이다.


drawTriangles 는 버텍스,인덱스 정보외에 UV 매핑을 위해 uvtData 도 전달 할 수 있는데

이때 UVT 에서 T가 원근감을 표현하는데 사용된다.


조금 더 자세한 정보는 이곳에서 얻을 수 있다.


drawTriangles  활용한 유명한 플래시 컨텐츠로는 wonderWall 이 있다.


아래의 사이트를 방문해보자.

어떠한 3D 엔진도 사용하지 않고 drawTriangles  만을 사용하여 3D 효과를 표현한 걸 볼 수 있다.


http://wonder-wall.com/#project/en



하나의 사각형을 표현하기 위해서 필요한 삼각형은 최소 2개이다.

이 때 공유되는 정점(꼭지점) 이 있으므로 필요한 정점은 6개가 아닌 4개가 된다.


우리가 가장 먼저 해야할 첫번째 일은 정점을 우리가 원하는대로 조작할 수 있게끔 하는 것이다.

렌더링 되는 정점을 자신 뜻대로 조작할 수 있으면 3D회전은 어렵지 않다.





백문이불여일RUN



이것저것 말할 필요 있나?


바로 코딩 들어간다. 남자는 코딩임.


가장 먼저 해야할 것은 사용할 이미지를 구하는 것이다.


수없이 F11 을 눌러야할 우리에게 보이는 것은 이 이미지뿐이다.


이는 매우 중요하므로 신중하게 결정해야 한다!!!!


나는 곰곰히 생각한 끝에 다양한 관점에서 고려하여 코딩의 효율을 최고로 끌어올리기 위해

크레용팝의 소율 사진을 사용하기로 했다.


날따라 투! 빠빠빠ㅃㅏ 빠빠빠빠


으악 벌써 작업능률이 상승하는 것 같다.



우선 Starling 이 아닌 익숙한 네이티브API 에서 연습삼아 drawTriangles 를 이용하여 시도해보자.






stage에서의 구현.


우선 Starling 작업에 앞서

연습삼아 우리에게 익숙한 기존 Graphcis 클래스의 drawTriangle 을 이용하여 각 정점( vertex ) 을 조작해보도록 한다.


drawTriangles 메소드의 활용방법 및 기본적인 uv맵핑 개념은 알고 있다고 가정하고

여기서 자세한 설명은 하지 않는다.


어차피 대부분의 사람들은 앞으로  사용할일 도 없을 것이다;


만약 잘 모른다면 레퍼런스를 살펴보도록 하자. 매너있게 관련 포탈 2개를 열어두겠다


http://help.adobe.com/ko_KR/as3/dev/WS84753F1C-5ABE-40b1-A2E4-07D7349976C4.html


http://help.adobe.com/ko_KR/FlashPlatform/reference/actionscript/3/flash/display/Graphics.html#drawTriangles()



메인클래스는 아래와 같다.



보시다시피 전체적인 구조는 간단한 MVC 형태가 될 예정이다.


다른 클래스들을 보기에 앞서 먼저 살펴봐야 할 클래스가 있다.


정점을 시각적으로 표시해주고 실제 데이터를 갱신 시킬 마우스로 움직일 수 있는 표시객체 클래스이다.


DisplayPoint 클래스.



특별한 것은 없다.  원의 형태로 보여지고 드래그가 가능한 표시객체이다.


x, y 속성을 오버라이드함으로써 내부의 point 객체는 항상 실제 객체의 x,y 좌표와 동기화 된다. z 값은 고려되지 않았다.


조금 주목할 점은 get point 로 Point 객체를 반환할 때 clone 이 아닌 참조를 바로 넘긴다는 것 정도.


그래서 Model 에 해당 DisplayPoint 의 point 의 참조를 넘긴 경우 DisplayPoint 가 움직일 때

별도의 작업 없이 Model 의 데이터도 자동으로 변경되게 된다.


사실 이런 경우 실제적인 데이터의 보유는 DisplayPoint 객체, 즉 Control 쪽이 되므로

엄밀히 말해 Control 과 Model이  분리되지 않은 잘못된 MVC 구조이지만 귀찮으니깐 그냥 이렇게 가도록 한다.

느낌 아니깐




다른 클래스들도 살펴보자.


Control 클래스는 아래와 같다.



소율사진을 화면 중앙에 위치시킬 각 정점의 좌표를 구해

4개의 DisplayPoint 객체를 생성, 초기화 한뒤 화면에 표시하고

Model 에 각 포인트를 등록한다.


DisplayPoint 의 좌표가 바뀌면 Model 의 update 메소드가 호출되게 되어있다.



이젠 Model 클래스를 보자.



소율 사진은 Model 클래스에 직접 embed 시켜두었다.


drawTriangle 에 전달 될 각 파라메터들을 반환하는 메소드들이 준비되어 있다.


우리는 지금 한장의 이미지를 2개의 삼각형을 이용하여 표시하려고 하므로

필요한 버텍스는 4개면 충분하며 인덱스들과 uvt데이터는 갱신될 필요가 없다.

기화 값 그대로 고정시키기로 한다. (혹시 모르니 상수로 두진 않았다 )


getVertices 을 호출 하면 화면에 표시된 DisplayPoint 객체의 좌표를 바탕으로 정점 정보를 반환하게 된다.


ps.

uvtData 벡터길이가 각 정점당 2개씩 배당되어 있다면 플래시는 t ( 시야 공간에서 눈과 텍스쳐 사이의 거리 ) 를 

사용하지 않는다고 판단하여 uv 값으로만 사용하게 된다.

만약 정점의 4개 인데 uvtData 벡터길이가 12개, 즉 3개씩 배당되어 있다면

3번째 수를 t 로 해석하여 원근감을 표현하게 된다.

여기서는 uv 만 사용되었다.





자 이젠 마지막으로 view 클래스를 보자.



뭐.. 별로 할말이 없을 정도로 간단하다.


2개의 삼각형을 확실히 볼 수 있도록 lineStyle 을 이용해 검정색 선을 표시하도록 한다.




자 이제 결과를 보자

빨간 원 드래그 가능.swf



각 꼭지점에 해당하는 DisplayPoint 객체를 드래그 하면


model 객체의 update 가 호출되고


view 는 model 에게 버텍스데이터를 요청,


model 은 현재 DisplayPoint 객체의 좌표에 맞게 적절한 버텍스 데이터를 반환하고


view 가 그 정보를 받아 화면을 갱신한다.



슬그머니 강제로 3D 회전 틱 하게 만들어 볼까?


안돼 소율이의 얼굴이 찌그러져버렷!


Fail.


이미지가 일그러져 보이는 이유는 전달한 UVT 데이터의 T를 설정하지 않았기 때문이다.

T = focalLength/(focalLength + z);


적절한 T 를 구하기 위해선 z값이 필요하고 z 를 구하기 위해선 약간의 삼각함수가 필요하다.


더불어 uvt데이터와 Model 클래스의 조정이 필요하다.



하지만 지금 중요한 것은 전반적인 개념을 잡는 것과


정점데이터를 통한 텍스쳐렌더링의 변화 그자체이므로 불필요한 정보 빼고 이부분에 집중하기로 하자.


어차피 Starling 에선( stage3D 에선 ) 조금 다른 방식을 사용하게 될 것이다.





가볍게 stage 에서 구현해보았다.


사실 여기까지는 알고 있는 사람도 많을 것이고 Starling 의 S 도 들어가지 않았을뿐더러


대부분의 경우 이런식으로 직접 stage (stage3D도 아니고) 에서 삼각형을 한땀 한땀 코딩하게 될일은 없을 것이다.


말그대로 개념잡기에 불과하다.


이제 바로 Starling 으로 들어가고 싶지만 그전에 잠깐,


다음글을 통해 stage3D 에서 텍스쳐를 표시하는 방법에 대해서 잠시 알아보는 시간을 가지자.



계속...