해당 파트는 게임 개발 환경을 구성하는 컴퓨터 그래픽스(Computer Graphics)를 이해하기 위한기초 수학의 간단한 개념에 대해 설명하고 있습니다!
혹여나 이해가 잘 안되거나 잘못된 정보를 발견하시게 되었다면 관련해서 피드백 해주시면 정말 감사하겠습니다!
2차원이 아닌 바로 3차원의 공간에 대해 설명을 시작하기 때문에 정말 기본적인 게임 수학을 잘 모르신다면 이해하기 힘들 수도 있습니다. 그래도 최대한 알아보기 쉽도록 작성하고자 노력하겠습니다!
해당 시리즈의 글은 이득우 교수님의 '이득우의 게임수학'을 토대로 진행됩니다. 이해가 부족한 부분은 해당 책을 통해 다시 읽어보는 것을 추천드립니다!
1. 3차원 공간의 설계
3차원... 2차원에서 축 하나가 생겼을 뿐인데 생각보다 더욱 복잡하고 수학적인 난이도에서도 좀 크게 상승하는 것 같습니다.
하지만 그만큼 매력이 있는 공간이기에 흥미만 있다면 정말 즐겁게 볼 수 있을겁니다!
1-1. 다른 3D 소프트웨어들은 어떠한 3D공간을 구성하고 있을까요?
저희가 알아볼 3D 소프트웨어들은 유니티 엔진과 블랜더3D, 그리고 초라하고 별거 없지만 제가 만든 CSEngine이라는 게임 엔진도 살짝 포함해서 알아보도록 하겠습니다..ㅎㅎ..
어쨌든 다음과 같은 프로그램에서 채택한 좌표계는 다음과 같습니다.
유니티 : 왼손 좌표계 y-up
블랜더3D : 오른손 좌표계 z-up
자체제작 엔진 : 오른손 좌표계 y-up
1-2. 위 프로그램들은 왜 저렇게 설계가 되었을까요?
소개한 프로그램 별로 정리를 해보았습니다.
유니티는 왜 왼손 좌표계인가요?
유니티 레이어 관련 참고용 이미지입니다.
먼저 왼손좌표계를 채택한 이유는 UX면으로 큰 이점이 있을 것으로 예상되는데 이에 대해 제가 경험했던 내용을 덧붙여 이야기를 하자면
3D 상에서 2D를 표현할 때 가끔 z축을 이용한 레이어 구분이 필요할 때가 있었습니다.
이 때 왼손 좌표계를 사용하면 화면과 멀어질 수록 z축 값이 올라가는데, 이렇게 z축값이 올라가는 것과 각 오브젝트의 레이어 순서는 서로 비슷하기 때문에 유용하게 썼던 기억이 있습니다.
💡
그럼 왜 Y-UP 인가요?
제가 직접 유추해본 내용은 그래픽 라이브러리들과 연관이 있지 않을까 생각하고 있습니다.
유니티와 언리얼이 본격적으로 상용화 되기 전 게임업계는 자체엔진이나 따로 계약을 진행한 엔진으로 게임을 만들어 왔던걸로 알고있습니다.
이 때는 그래픽 라이브러리의 접근이 지금보다 많았을거라고 생각이 드는데
당시 유명했던 그래픽 라이브러리인 다이렉트X와 OpenGL은 y-up 좌표계를 채택하고 있습니다.
이에 따라 개발자들에게 좀 더 친숙한 y-up이 유니티와 같은 상용엔진에도 적용되지 않았을까 생각하고 있습니다.
블랜더는 왜 오른손 좌표계 z-up인가요?
한달 간 활성화 된 토론인데도 불구하고 29개의 의견이 달려있는 상태입니다!
오른손 좌표계를 채택한 이유는 인문 수학들이 대부분 2D 좌표계인 데카르트 좌표계에서 3D 좌표계로 넘어갈 때 좀 더 호환이
되는 방식이 오른손 좌표계이기 때문에 대부분 오른손 좌표계를 쓴다고 치더라도 왜 굳이 z-up일까? 이건 진짜 궁금했었습니다.
그리고 구글링을 해보니 이거와 관련한 토론이 이미 해외포럼에 진행되었었고, 위 사진이 그 포럼의 내용입니다. 해당 포럼은 한달동안만 활성화 된 토론인데도 불구하고 29개의 의견이 달려있는 상태입니다. 해당 포럼의 링크를 통해 한번 확인해보는 것을 추천드립니다.
결론부터 말하자면... 명쾌한 결론은 없었습니다!
나름 공학적인 접근방식에서 Z-UP이 거의 표준처럼 사용된다고 작성된 글도 있긴 한데 잘 모르겠네요...
그래도 토론의 전제는 각자의 관점을 존중하며 왜 이런 좌표계를 사용했는지에 대한 이야기가 오고 가는 것이라 보면 좋을 것 같습니다.
왜 자체 제작한 게임엔진은 오른손 좌표계 Y-UP 인가요?
사실...이건 OpenGL이 해당 좌표계를 채택해서 그대로 쓰고 있었습니다!
특별한 이유는 없습니다..하핫...ㅎㅎ
2. 3차원 공간의 트랜스폼
2-1. 이동변환과 크기변환 행렬
이동변환은 Identity Matrix를 기반으로 w축만 변경됩니다. 게다가 한 축이 변경되면 다른 축은 변경되지 않습니다. 따라서 크기변환은 Identity Matrix 범위 내에서 변경됩니다.
이에 따라 이 두가지 변환은 차원마다 행렬식이 추가되기만 하면 끝나기 때문에 알아보기 편합니다!
3차원 기준의 해당 변환식은 다음과 같습니다.
이동 변환
크기 변환
2-2. 표준기저벡터의 변화를 사용한 회전 변환 행렬
회전은 하나의 축을 변경하면 대부분의 축이 변경됩니다.
이에 따라 차원이 높아질 수록 해당 축의 회전은 더욱 넓은 범위의 축들을 변경하게 됩니다.
💡
예시로 2D 공간의 회전(z축 회전)은 x, y축만 영향을 끼치지만
3D 공간의 회전(x, y축 회전)은 z축에도 영향을 끼칩니다.
상세한 변환식의 내용은 아래에서 설명하도록 하고
위 그림처럼 변환된 표준 기저 벡터인 (위 그림 상 ) 값은
라고 설명할 수 있으며, 아래와 같은 식으로 적용할 수 있습니다.
💡
잠깐! 행렬인데... 왜 막상 적용하려고 하면 순서인가요?
이것에 대해 진지하게 정말 고민을 많이 했습니다. 처음엔 에이 완전 거꾸로 곱셈은 아니겠지... 했는데 완전 거꾸로 곱셈을 하는 상황이였습니다!