유니티로 배우는 게임 수학-맛보기

Page 1




유니티로 배우는 게임 수학 기초 개념부터 모바일까지, 게임 개발에 필요한 수학 원리 설명서 초판발행 2016년 8월 1일 지은이 구부키 류이치 / 옮긴이 김성재 / 감수자 오지현 / 펴낸이 김태헌 베타리더 강찬석, 김관영, 김광남, 이보라, 유주연, 이정재, 정부일, 정재우 펴낸곳 한빛미디어 (주) / 주소 서울시 마포구 양화로 7길 83 한빛미디어(주) IT출판부 전화 02 – 325 – 5544 / 팩스 02 – 336 – 7124 등록 1999년 6월 24일 제10 – 1779호 / ISBN 978 – 89 - 6848 - 500 - 8 93000 총괄 전태호 / 책임편집 김창수 / 기획·편집 박지영 디자인 표지·내지 김미현 / 조판 이경숙 영업 김형진, 김진불, 조유미 / 마케팅 박상용, 송경석, 변지영 / 제작 박성우, 김정우 이 책에 대한 의견이나 오탈자 및 잘못된 내용에 대한 수정 정보는 한빛미디어(주)의 홈페이지나 아래 이메일로 알려주십시오. 잘못된 책은 구입하신 서점에서 교환해드립니다. 책값은 뒤표지에 표시되어 있습니다. 한빛미디어 홈페이지 www.hanbit.co.kr / 이메일 ask@hanbit.co.kr

GAME APPLI NO SUGAKU Copyright © 2015 Ryuichi Kubuki All rights reserved. Original Japanese edition published by SB Creative Corp. Korean translation rights © 2016 by Hanbit Media Korean translation rights arranged with SB Creative Corp., Tokyo through Botong Agency, Seoul, Korea 이 책의 한국어판 저작권은 Botong Agency를 통한 저작권자와의 독점 계약으로 한빛미디어가 소유합니다. 신 저작권법에 의하여 한국 내에서 보호를 받는 저작물이므로 무단전재와 무단복제를 금합니다.

지금 하지 않으면 할 수 없는 일이 있습니다. 책으로 펴내고 싶은 아이디어나 원고를 메일 ( writer@hanbit.co.kr ) 로 보내주세요. 한빛미디어(주)는 여러분의 소중한 경험과 지식을 기다리고 있습니다.



지은이·옮긴이 소개

지은이

구부키 류이치 久富木 隆一

모바일 게임 개발자. 도쿄대학 법학부를 졸업하고 2010년 GREE에 입사하여 게임스튜디오 엔 지니어로 모바일 게임 개발에 매진해왔다. 대규모 웹 소셜 게임에서 iOS와 안드로이드용 유니 티/Cocos2d-x 게임 애플리케이션에 이르기까지, 서버와 클라이언트 영역을 포함한 다양한 프로젝트에 종사한다.

옮긴이 김성재

기술 분야 전문 번역가. 관심 분야는 IT 기술과 일본어 교육 콘텐츠 등이다. 최근에는 업무에 필요한 맥 OS와 iOS 애플리케이션의 개발과 리뷰, 환경 구축에 관심이 있다. 번역서로는 『만 들면서 배우는 기계 학습』, 『빅데이터의 충격』, 『C언어로 배우는 리눅스 프로그래밍』, 『구글 웹 로그 분석』(이상 한빛미디어) 등이 있다.

4


추천의 글

유니티 때문에 게임 개발자들이 수학을 모른다는 이야기를 가끔 듣습니다. 유니티는 수학적인 배경 지식이 충분하지 않아도 게임 개발을 쉽게 만들어줍니다. 그러다 보니 유니티로 게임을 만들면서 수학의 필요성을 못 느껴 공부를 안 하게 된다는 것이죠. 유니티는 게임 개발의 민주 화라는 목표 아래 누구나 쉽게 게임을 만들 수 있도록 만들어졌지만, 그렇다고 수학을 몰라도 된다는 뜻은 아닙니다. 오히려 게임엔진을 사용하더라도 수학 이론을 잘 이해해야 엔진을 제대 로 활용할 수 있습니다. 이런 이야기를 꺼낼 때마다 저는 주로 자동차에 비유합니다. 단순히 출퇴근용으로만 자동차를 운전한다면 엔진 원리 등 내부 구조는 몰라도 큰 상관이 없습니다. 오히려 요즘은 무인자동차 가 개발되는 추세죠. 하지만, 레이싱카를 모는 프로 카레이서라면 엔진 원리와 자동차 내부 구 조를 완벽하게 알아야 하고 경기 트랙 구조도 이해해야 합니다. 그래야 0.1초라도 기록을 더 단축할 수 있죠. 게임엔진도 마찬가지입니다. 유니티는 물론 언리얼과 Cocos 2d-x 등 엔진이 어떻게 돌아가는지 원리를 알아야 게임 개발 과정에서 어려움에 직면했을 때 유연하게 대처할 수 있습니다. 수학은 이러한 게임엔진들의 기초가 되는 학문으로, 수학을 잘 알면 깊이 있고 최적화된 게임 을 만들 수 있습니다. 물론, 게임 구동에 필요한 모든 기본 기능은 게임엔진에 구현되어 있습니 다. 하지만 해당 기능들의 작동 원리를 이해해야 더욱 심도 있게 다룰 수 있겠지요. 또한, 엔진 이 제공하지 않는 기능을 구현하려면 수학이 필요합니다. 즉, 게임 개발자라면 수학을 습득해 야 비로소 게임 개발의 프로 레이서가 될 수 있습니다. 이 책은 이론에만 치우치지 않고 유니티 에서 구동되는 사례를 보여줌으로써 이해를 돕습니다. 수학뿐만 아니라 게임엔진에 대한 기반 지식들도 이야기합니다. 유니티 사용법을 알려주는 초 심자용 가이드에 치우친 기존 도서들과 달리, 게임 그래픽스 렌더링에 필요한 기반 지식들을

5


함께 제공해 유니티라는 게임엔진을 더 깊이 있게 다루도록 도와줍니다. 이 책은 여러분을 게 임 개발의 프로가 되는 길로 안내해줄 것입니다. 오지현_ 유니티 한국지사 서포트 엔지니어

간단한 수학 공식으로 해결할 수 있는 부분을 직접 로직으로 구현해야 했던 경험, 개발자라면 누구든 한 번쯤 있을 것입니다. 개인의 프로그램 능력을 높인 시간이었을 수는 있으나, 프로젝 트 진행 과정에서 불필요하게 많은 시간을 낭비한 셈입니다. 초급에서 중고급 개발자로 발돋움하려면 반드시 기본기를 닦아야 합니다. 특히 게임 개발자에 게 수학 지식은 기본 중 기본이라 생각합니다. 이 책은 그 기본 소양의 방향을 알려주는 한 권 으로, 전체적인 맥락을 이해하는 과정에서 자신의 부족한 점이 무엇인지, 그리고 게임 개발의 궁극의 지향점은 어디인지 파악할 수 있습니다. 여러분 역시 저처럼 이 책을 통해 게임 수학의 기본기를 닦았으면 하는 바람입니다. 김광남_ 금영그룹 책임연구원

유니티 등장 이전에는 3D 그래픽스 수학을 먼저 배우고, 그래픽스 라이브러리를 배운 뒤 게임 엔진을 배웠습니다. 유니티 등장 이후 우리는 유니티를 먼저 배웁니다. 그리고 스크립팅과 셰 이더에서 수학적 문제로 어려움을 겪습니다. 이 책은 유니티 스크립팅 프로그래머와 테크니컬 아티스트가 되는 데 필요한 수학적 지식들을 제공하여 어려운 문제를 푸는 데 도움을 줄 것입 니다. C#과 유니티 에디터 사용법을 배웠다면 스크립팅과 셰이더를 위해 두 번째로 배워야 할 필수 내용입니다. 정부일_ (주)위즈풀 개발자

6


게임을 개발할 때 필요한 지식은 단순히 프로그래밍에 국한되지 않습니다. 게임 개발에 처음 도전하는 경우라면, 수학이나 물리에 대한 지식이 필요하다는 것을 알면서도 어디서부터 시작 해야 할지 막연하다면, 이 책을 통해 게임 개발에 필요한 수학 지식의 가이드라인을 확인할 수 있습니다. 방대한 수학에서 게임 개발에 필요한 기본적이고 실질적인 수학 학습의 시작점을 확 인할 수 있고, 그 수학 학습의 가지를 넓게 펼쳐나가기 위한 튼튼한 기반으로 이용할 수 있습니 다. 게임 프로그래밍과 수학에서 기초의 중요성은 아무리 강조해도 부족할 것입니다. 이 책은 게임 개발에 필요한 수학적인 기초를 쌓는 데 도움을 줄 좋은 파트너가 될 것입니다. 이정재_ 미디어캔버스 개발자

우리가 일상에서 즐기는 간단한 게임 안에도 나름의 로직과 알고리즘, 그리고 수학적 지식이 포 함되어 있습니다. 많은 사람이 게임 개발을 시도하지만, 그 과정에서 수학적 지식의 부족함으로 인해 어려움을 겪습니다. 유니티처럼 사용자에게 각종 편의를 제공하는 개발 도구 역시, 기반 지식을 바탕으로 응용하는 접근이 필요합니다. 이 책은 유니티를 다루는 데 필요한 수학 지식을 공식과 그림과 함께 설명하므로, 해당 내용을 되새기고자 하는 이들이 이해하기 쉬울 것입니다. 또한 단순히 수식만 나열한 방식이 아닌, 실제 C# 코드와 함께 실습할 수 있는 여건을 제공합니 다. 직접 유니티를 다뤄보며 익히고자 하는 게임 개발자에게 이 책을 추천하고 싶습니다. 강찬석_ LG전자 연구원

소프트웨어 경진대회에서 우수한 성적을 거둔 자녀의 학부모들에게도 그들만의 고민이 있다. 자녀가 코딩만 하다가 국·영·수 공부를 못해서 수능을 못 보는 것, 그래서 좋은 대학에 들어 가지 못하는 것이 부모님들의 가장 큰 고민이라고 한다. 그 이야기를 직접 들었을 때 이 책을 알았고, 진작 추천해주었더라면 학생은 수학 공부에 큰 동기부여를 받았을 것이며, 부모님 역

7


시 간접적으로나마 안심할 수 있었을 것이라는 아쉬움이 남았다. 정보 분야 영재뿐만 아니라

IT 분야, 특히 게임 개발 진로를 생각하는 중·고등학생에게도 이 책을 권하고 싶다. 떨어져가 는 수학 학습 동기를 이 책을 통해 높이길 바란다. 이보라_ 아주대학교 소프트웨어공학 석사과정

이 책에서 정의한 주요 독자는 수학적 지식이 거의 제로에 가까운 독자이지만, 생각보다 난이 도가 높아 초보자가 접근하기에 마냥 쉽지만은 않습니다. 다만 이론을 통한 공식만 제공하는 대신, 유니티를 통해 어떻게 해당 공식이 적용될 수 있는지 예제를 함께 제공하므로, 직접 따라 해보며 실제 개발 환경에 필요한 각종 수학적 개념과 응용력을 기를 수 있습니다. 또한 게임을 개발할 때 어떤 수학 개념이 필요한지, 어떻게 응용할 수 있을지 자세히 서술하므로 읽어보는 것만으로도 여러분의 수준을 한 단계 끌어올릴 수 있습니다. 이 책은 기초와 심화된 지식을 모 두 경험해볼 수 있는 사전과 같은 존재로 여러분의 책상을 빛나게 할 것입니다. 정재우_ 용인정보고등학교 교사

게임을 만들어본 사람이라면 누구나 다음과 같은 질문을 던져봤을 것이다. “대체 이 게임엔진 은 어떻게 만들었지?” 게임엔진을 이용해 게임을 만드는 법을 설명하는 책은 정말 많다. 하지 만 게임엔진 자체에 대해 설명하는 책은 없다. 참 아이러니하지 않은가? 수학부터 빛, 메모리 계산까지 게임엔진에 관한 명쾌한 해답이 필요하다면, 여기 유니티 게임엔진에 대한 해답을 명 쾌히 써 내려간 책을 추천한다. 김관영_ 프리랜서 개발자

8


옮긴이의 말

컴퓨터 프로그래밍과 관련된 책을 여러 해 번역하다 보니, 수학을 주제로 한 책도 몇 권 옮기게 되었습니다. 그만큼 프로그래밍과 수학은 밀접한 관련이 있다고 할 수 있겠지요. 그중 절반은 이 책처럼 게임에 사용되는 수학 개념을 설명하고 프로그램 코드로 확인하는 책이었습니다. 학습한 수학 이론을 프로그램 코드로 만들고 그 결과를 시각적으로 확인해볼 수 있는 책들은 대개 재미와 학습 효과를 모두 잡을 수 있는 장점이 있습니다. 이 책도 그 비슷한 종류의 책에 서 볼 수 있는 장점을 그대로 가집니다. 게다가, 이 책은 저자가 밝혔듯 게임 앱 개발에 필요한 수학 개념을 재구성함으로써 최대한 시간 낭비를 줄이고 빠르게 일정 수준의 수학 지식을 갖출 수 있도록 배려합니다. 무엇이든 학습할 목표가 명확해야 시행착오를 줄일 수 있습니다. 그런 점에서 이 책은 삼각함 수부터 셰이더에 이르기까지 저자가 찾아낸 최적의 길을 제시합니다. 물론, 내용이 압축되어 이해하기 쉽지 않게 느껴지는 부분도 있습니다. 저처럼 기초 지식이 부족해서 다른 자료도 열 심히 찾아가며 공부해야 할지도 모르지요. 하지만, 어느 정도 수학 지식이 있으신 분이라면 게 임 앱 개발에 필요한 개념을 빠르게 정리하는 데 많은 도움을 받을 수 있을 것입니다. 이 책은 각 장의 내용을 실습하기 위해 예제 소스를 제공합니다. 예제 소스를 유니티에서 실행 하기 전에, 책 뒤의 부록을 먼저 보고 동작 환경 등을 확인해주세요. 몇 가지 보충 설명도 실려 있습니다. 아무쪼록 독자 분들이 이 책을 통해 원하는 바를 얻길 기원합니다. 끝으로, 개인적으로 여러 가지 어려운 사정이 연이어 생겨 원고 마감이 많이 지체되었습니다. 번번이 제 예상과 달리 벌어지는 일들로 본의 아니게 많은 분께 폐를 끼치고 말았습니다. 이 자 리를 빌려 기다려주시고 함께 걱정해주시고 배려해주신 한빛미디어 분들께 진심으로 감사의 말씀을 전합니다. 정말 감사합니다. 2016년 6월

김성재

9


지은이의 말

게임 개발자의 수학

이 책의 대상은 수학 지식이 거의 제로에 가까운 독자다. 이 책의 목적은 현대 게임 개발자라면 반드시 알아야 할 수학 개념과 응용법을 기초부터 고급까지 단번에 습득하는 것이다. 주요 대상 독자는 다음과 같다. 1 학생 시절 서툴렀던 수학을 기초부터 다시 배우고 싶은 사람 2 프로 게임 개발자로 취업하고 싶은 사람 3 유니티와 Cocos2d -x 입문서를 읽었고, 다음 단계를 배우고 싶은 사람 4 웹 개발 / 서버 사이드 개발 / 비게임 앱 개발을 할 수 있는 프로그래밍 지식과 컴퓨터 과학 일반 지식이 있고, 추가로 2D/3D 시각적 표현을 위한 지식을 배우고자 하는 사람

5 실시간 3D 컴퓨터 그래픽스의 원리를 알고 싶은 사람 6 스마트폰용 최적화의 핵심을 알고 싶은 사람 7 셰이더를 작성하고 싶은 사람

이 책이 다양한 요구에 부응하려는 것처럼 보인다면, 하나의 산을 서로 다른 방면에서 오르려 하는 모든 독자를 지원하기 때문이다. 하지만 올라갈 산은 어디까지나 하나다. 여기서 산이란 게임 표현의 기반이 되는 수학적 시스템이며, 그 시스템을 따라 프로그램을 실행하는 컴퓨터이 기도 하다. 이 책은 어디서부터 학습을 시작해야 할지 모르는 독자에게 학습 진행에 필요한 이 른바 원점과 좌표축을 제시하고, 게임 개발에 진지하게 임했을 때 피해 갈 수 없는 길을 스스로 걸어나갈 수 있게 지원한다. 이 책을 학습할 때 유니티나 C# 언어에 관한 지식은 필요 없다. 학습 환경으로 유니티를 선택 한 이유는 크로스 플랫폼 게임 제작 도구 중 가장 진보했고, 사용자가 샘플 소스를 실행하여 결 과를 확인하기까지 난관이 낮으며(로 리스크), 쉽게 이용할 수 있는 기능이 풍부한(하이 리 턴) 고효율 게임엔진으로서 보급되기 때문이다. 샘플 소스는 C#으로 기술되므로 C#과 비슷 한 자바나 C/C++ 지식이 있으면 더 유리하다. 하지만, 본문에서 코드의 의미에 대해 자세히

10


주석을 붙여놓았으므로, 컴퓨터가 없는 환경이라면 코드를 건너뛰고 본문과 수식만 읽는 것도 나름대로 타당한 학습 방법이다. 이 책에서 배울 수 있는 수학, 3D 그래픽스, 셰이더에 관한 지식은 유니티에 관계없이 게임 개 발에 보편적으로 활용할 수 있다. 유니티 자체는 훌륭한 도구지만, 적당히 사용해도 저절로 괜 찮은 게임이 만들어질 정도의 수준에는 아직 이르지 못한 만큼, 유니티를 충분히 자유자재로 쓰려면 유니티가 탄생한 원류로 거슬러 올라가야 한다. 유니티 이전 시대를 아는 게임 개발자 에게는 당연한 전제라 해도, 유니티로 처음 게임을 만들기 시작한 사람에게는 자명하지 않은 부분도 많다. 유니티 이전과 이후 사이의 단절을 극복하기 위해, 기술의 결정체인 유니티에 구 현된 기능이 왜 현재의 형태인가를 고고학적으로 해석한다면, 현대 게임 개발에 내재된 뼈대가 드러날 것이다. 그런 의미에서 유니티의 결점은 오픈소스가 아닌 블랙박스 방식이다 보니 분석 이 쉽지 않다는 점이다. 따라서 유니티보다 원시적이지만 교육용으로 뛰어난 Cocos2d-x의 소스 코드나, 유니티보다 하이엔드 용도에서 앞선 언리얼 엔진의 소스 코드를 살펴보는 것도 좋다. 이 책에서는 웹 브라우저로 가볍게 시험할 수 있는 환경인 WebGL도 다루고 있다. 원서에서는 제목에 ‘게임’이 아닌 ‘게임 앱’이라는 단어를 썼다. 1990년대 중반 3D 게임의 여명 기에서 2010년대 중반 스마트폰 게임의 성숙기에 이르기까지, 20년간 게임 개발에 이용된 수 학 지식의 기초가 이 책에 응축되어 있다. PC/콘솔 게임기용 기술이 전력과 열 설계의 제한으 로 실행 성능이 떨어지는 모바일기기로 내려오는 시차는 4, 5년이다. 다만, 단순히 낡은 기술 을 물려받는 대신, 유니티 등의 도구를 거쳐 선진적인 기술이 잘 다듬어진 형태로 스마트폰용 으로 도입되고 급속도로 확산되고 있다. 또한, 스마트폰이라는 기기의 특성에 따른 모바일 게 임 앱 특유의 문제도 고려해야 한다. 이제 모든 이가 가지게 된 휴대용 컴퓨터인 스마트폰은 이 미 주류 게임 플랫폼이고, 개인이라도 세계적인 상업 릴리즈를 가정하여 개발할 수 있는 가까 운 대상으로서 더할 나위 없다. 수학이라는 영구불변의 원리를 주제로 하면서도 이 책은 살아 있는 현대적 과제로의 응용을 목적으로 한다.

11


필자는 업무에서 게임을 개발하게 되면서 수학을 다시 독학한 소프트웨어 엔지니어 중 한 사람 이다. 나 자신의 시행착오가 이 책의 기초가 되었다. 이 책은 교육용으로 내용을 간추린 서적이 라기보다는 실전과 직결된 생존 지침으로서 기능하도록, 제품을 개발하는 실제 게임 개발 현장 에서의 수요를 염두에 두고 현실적으로 구성했다. 수학 개념을 가능한 한 빠르게 학습하기 위해 고민한 부분은 게임 개발의 20년 역사를 수학적 관점에서 재구성하여 내 나름대로 체계를 만드는 일이었다. 산만한 레시피 모음처럼 정리되지 않고 체계적이지 않은 지식만을 욱여넣어 결과적으로 시간을 낭비해버린다면 본말이 전도되는 것이리라. 그래서 모든 세부 항목을 기억하기보다는 문맥이 있는 일관된 이야기처럼 각각의 점 을 연결한 선이 차례로 도출되며 전개되도록 신경을 썼다. 도중에 모르는 부분이 있더라도 처 음부터 끝까지 한 번 쭉 읽고 커다란 흐름을 파악한 후에, 잘 모르는 부분을 다시 찾아보는 편 이 효과적이고 이해가 빠를 것이다. 또한, 이 책을 여러 번 읽는 반복 학습을 권한다. 이것저것 다 배우려면 시간은 부족할 수밖에 없다. 그리고 목표가 멀면 멀수록 집중력이 약해지는 것이 인간의 속성이다. 널리 이용되는 검 증된 고급 라이브러리를 이용하지 않고 독자적인 알고리즘을 구현하는 것은 실익이 없는 일이 다. 또한 알고리즘 블랙박스의 내용을 이해할 가치가 상대적으로 낮은 난수나 암호, 물리연산 등의 주제는 전략적으로 생략해 학습 사항의 절대량을 줄였다. 이렇게 함으로써 단기간에 읽고 실제로 게임 개발자로서 취직할 수 있는 수준의 수학 지식을 익히기 위한 압축된 내용으로 최 적화했다. 예제도 해당 주제의 핵심을 찌르는 것을 가장 중요시하고, 혼란을 부르기 쉬운 불필 요한 부분은 삭제했다. ‘셰이더를 작성할 수 있게 된다’와 같은 알기 쉬운 이정표 달성을 목표로 하면 학습도 진척될 것이다. 이미 프로그래밍에 익숙한 독자의 학습에 박차를 가할 수 있는 구성에도 신경을 썼다. 프로그 램은 작성할 수 있어도 기호투성이 수식에 거부 반응이 있는 경우(Perl 언어가 종종 기호가 많

12


아 야유받은 것처럼)를 배려해, 내용의 추상도를 줄이고자 시각적으로 동작을 확인할 수 있는 유니티 예제와 수학 개념을 오가도록 구성했다. 프로그래밍 언어에서 자연언어인 함수명이나 제어구조의 의미가 더 이해하기 쉬울 뿐, 형식언어라는 점에서는 수식도 프로그래밍 언어와 마 찬가지로 적응의 문제다. 따라서 수식을 프로그래밍 언어의 관용구로 바꿔 생각하면 좋다. 정 의= 클래스 정의, 연산= API로 바꿔 읽는다면, 같은 연산을 갖추는 것이 비슷한 인터페이스를 갖춘 오브젝트로서 덕 타이핑의 대상이 된다. 또한, 프로그래밍 언어에서 연산자 오버로딩을 지원한다면 수식처럼 프로그램을 구성할 수도 있다. 수식과 프로그래밍 언어가 맞닿은 것처럼 보이게 되면, 특별해보이던 수식에도 익숙해져 아무런 두려움도 없어질 것이다. 이 책은 수학의 기초부터 응용까지 한 권의 책으로 다루면서, 설령 중복되더라도 가능한 한 모 호함을 배제하고 이해가 막히지 않도록 설명하는 데 주력한다. 의미가 명확하지 않은 개념이 갑자기 나타나 독자가 놀라지 않도록 처음 나온 개념은 반드시 설명하고, 처음 나온 수학 용어 에는 대응하는 영어 단어를 함께 기술했다. 대부분의 수학 용어에 영어를 덧붙인 이유는 다음 과 같은 장점 때문이다. 수학 용어는 영어권에서도 일상적으로는 사용되지 않아 찾기 어렵지만, 영어 용어로 검색할 수 있으면 영어를

몰라도 그림이나 코드를 이해하는 데 도움이 된다. 프로그램 내에서 관련 부분에 이름 붙일 때 편리하다.

영어권에는 수식을 해석하거나 계산하거나 표시할 수 있는 울프럼 알파라는 편리한 도구가 있다. 마지막으로 ‘게임 개발자’란 무엇인지, 어떤 지식이 있어야 프로 게임 개발자로서 평가받을 수 있는지 필자의 경험에 비추어 소개하겠다. 여기서 적절한 비유를 하나 들어본다. 기원전 중국 전국시대의 사상가인 맹자가 말하길 ‘천시(天時)는 지리(地利)만 못하고 지리는 인화(人和) 만 못하다’고 했다. 하늘이 주는 운은 지리상의 이로움만 못하고, 지리상의 이로움도 사람들 사 이의 일치단결만 못하다는 뜻이다. 이를 순서대로 단순히 해석하면 ‘천시 < 지리 < 인화’가 되

13


어, ‘인화’를 가장 중요시하는 우열관계의 주장이 된다. 이 문장을 창조적으로 오독한 것이 일본 전국시대 무장 우에스기 겐신(上杉 謙信)으로, 천·지·인 3요소를 겸비한 무장은 무적이라고 했다. 실은 같은 말을 게임 개발자에게도 말할 수 있다. ‘천(天)’은 수학·물리학과 같은 세상의 원리를 가리킨다. 사람이 사는 세상은 변하는 법이지 만, 순수한 수학 원리는 부패하지 않는 아름다운 존재다. 게임 내에서 세계를 시뮬레이션하려 면 당연히 그 원리에 정통해야 한다. 한편, 자료구조와 알고리즘 같은 지식을 다루는 컴퓨터 과 학은 ‘지(地)’에 해당한다. 토대가 되는 컴퓨터가 있어야 비로소 우리는 수학 원리를 자유롭게 활용할 수 있다. 그리고 ‘인(人)’에 해당하는 지식은 프로그래밍 언어부터 객체지향, 디자인 패 턴, 애자일 같은 개발 기법이나 MySQL 등의 데이터베이스, Autodesk Maya와 같은 DCC 툴, 유니티와 같은 게임엔진까지, 인간이 ‘천’과 ‘지’를 효율적으로 조종하는 방법을 집적한 도구 의 이용법이다. 컴퓨터를 비영어권 학습자가 배울 때는 영어도 인간을 위한 도구라고 할 수 있 다. 인간이라는 생물의 인지과학적 인식 패턴을 분석하여, 오류를 방지하면서 컴퓨터를 이용한 자동화의 은혜에 관여하기 위한 맨머신 인터페이스(man-machine interface )의 경험지가 ‘인’의 층에 모여 있다. 필자는 한 C++ 전문서에서 객체지향과 제네릭스 프로그래밍으로 이루어지는 추상화 메커니 즘을 설명할 때 마키아벨리를 인용한 것을 본 적이 있다. 그제서야 프로그래밍 언어가 인간을 위해 존재하는 인문적인 도구임을 깨닫고 비로소 프로그래밍에 친근감을 느꼈다. 천·지·인 의 구별은 다익스트라법으로 알려진 에츠허르 데이크스트라(Edsger Dijkstra )가 ‘컴퓨터 과 학은 응용수학의 한 분야다’라고 말했던 것처럼 자의적이고 상대적인 분류일 수밖에 없지만, 지표로서는 유용하다. 게임 개발자가 알아야 할 내용은 시대에 따라 달라지더라도, 이 천· 지·인 3요소로 이루어지는 지식을 어느 정도 갖춰야 비로소 게임 개발자라 할 수 있다는 것 자체는 앞으로도 변하지 않을 것이다.

14


‘인’의 층은 인간인 사용자가 ‘천’과 ‘지’의 내용을 자세히 몰라도 정복할 수 있게 만들어졌다. 유 니티도 마찬가지다. 하지만 도구의 층에서, 샌드박스 안에서, 유니티 손바닥 위에서 춤만 추는 것과 유니티 구조를 이해한 다음 움직이는 것을 비교한다면, 뜻밖의 사태가 벌어졌을 때 후자 쪽이 적절한 답을 이끌어낼 확률이 높다. 원리원칙을 안다는 것은 표면적인 유행에 쉽게 좌우 되지 않는 스킬을 자신의 것으로 만드는 일이다. 수년 전 충분히 통했던 방법을 현재 똑같이 해 봐야 완전히 시대에 뒤쳐지는 게 당연하다. 잠시라도 눈을 감으면 코를 베이는, 급변하면서도 냉혹한 세계가 IT/게임 업계이기 때문이다. 게임 세계와 IT 세계가 한 무대에서 충돌하는, 개 기일식을 연상시키는 듯한 모바일 소셜 게임이 없었다면 게임 개발에 주체적으로 관여해 볼 기 회가 없었을 필자로서는, 이 같은 기묘한 만남에 감사하면서 ‘천’의 힘을 매일 재인식한다. 이 책의 주제가 멀게만 느껴졌던 사람이라도 크게 마음먹고 한번 끝까지 읽어본다면 생각이 바뀔 수 있다. 현대 게임 개발 대부분이 팀워크로 이루어지듯, 고독한 도전인 책의 저술 작업도 도와주신 분 들이 없었다면 성립할 수 없었다. 동료인 사지마 유타카 씨, 미키 텟페이 씨는 이 책의 실마리 를 주었고, 대학 선배인 아사히 마사히로 씨는 필자가 하루종일 풀지 못한 수학 문제를 순식간 에 풀어주었다. 편집부 시나다 요스케 씨, 야노 아키요시 씨는 거듭되는 마감 연장을 이해해주 고 격려해주셨다. 이 자리에서 모두에게 감사의 말을 전한다. 이 책이 한 사람이라도 많은 사람의 고민을 해결하고 길을 열어주는 데 도움이 되길 바란다. 2015년 8월 하늘 푸른 샌프란시스코에서

구부키 류이치

15


CONTENTS

지은이·옮긴이 소개 ����������������������������������������������������������������������������������������������������������� 4

추천의 글 �������������������������������������������������������������������������������������������������������������������������� 5

옮긴이의 말 ����������������������������������������������������������������������������������������������������������������������� 9

지은이의 말 ��������������������������������������������������������������������������������������������������������������������� 10

CHAPTER

1 삼각함수 1.1 삼각형 ...................................................................................................................... 27 1.2 직각삼각형 ................................................................................................................ 28 1.3 피타고라스의 정리 ...................................................................................................... 29 1.4 사인, 코사인, 탄젠트 .................................................................................................... 30 1.5 삼각함수의 주기성 ...................................................................................................... 32 1.5.1 단위원 ............................................................................................................. 32 1.5.2 코사인법칙 ....................................................................................................... 34 1.5.3 주기성 ............................................................................................................. 35 1.5.4 라디안 ............................................................................................................. 36 1.5.5 덧셈정리 .......................................................................................................... 38 1.5.6 사인파, 코사인파 ............................................................................................... 39

1.6 유니티 예제 : 클릭 위치를 향하는 캡슐·바운드하는 구체 ................................................... 42 1.6.1 동작과 사양 ...................................................................................................... 42 1.6.2 구현 코드 ......................................................................................................... 48

CHAPTER

2 좌표계 2.1 직교좌표계 ................................................................................................................ 57 2.1.1 2D 좌표계 ....................................................................................................... 57 2.1.2 3D 좌표계 ....................................................................................................... 58 2.1.3 왼손 좌표계와 오른손 좌표계 ............................................................................... 62

16


2.1.4 로컬 좌표계와 월드 좌표계 .................................................................................. 64 2.1.5 Center/Pivot과 Local/Global ........................................................................... 65 2.1.6 스크린 좌표 ...................................................................................................... 69

2.2 극좌표계 ................................................................................................................... 69 2.2.1 2D 극좌표계 .................................................................................................... 70 2.2.2 3D 극좌표계 = 구면좌표계 ................................................................................. 72

2.3 유니티 예제 : 3인칭 시점 카메라 .................................................................................... 74 2.3.1 동작과 사양 ...................................................................................................... 74 2.3.2 구현 코드 ......................................................................................................... 78

CHAPTER

3 벡터 3.1 벡터의 정의 ............................................................................................................... 85 3.1.1 수벡터 ............................................................................................................. 85 3.1.2 기하벡터 .......................................................................................................... 86 3.1.3 스칼라 ............................................................................................................. 87

3.2 벡터 연산 .................................................................................................................. 87 3.2.1 덧셈·뺄셈·교환법칙·결합법칙 ......................................................................... 87 3.2.2 스칼라 곱셈·나눗셈 .......................................................................................... 89 3.2.3 단위벡터 .......................................................................................................... 89 3.2.4 기저와 좌표계 ................................................................................................... 90 3.2.5 법선벡터 .......................................................................................................... 91 3.2.6 크기 ................................................................................................................ 92 3.2.7 내적 ................................................................................................................ 93 3.2.8 벡터의 직교투영 ................................................................................................ 96 3.2.9 내적의 응용 ...................................................................................................... 97 3.2.10 외적 .............................................................................................................. 98 3.2.11 외적의 응용 .................................................................................................. 101

17


CONTENTS

3.3 유니티 예제 : 간이 충돌 판정 ...................................................................................... 102 3.3.1 동작과 사양 .................................................................................................... 102 3.3.2 구현 코드 ....................................................................................................... 106

CHAPTER

4 행렬 4.1 행렬의 정의 ............................................................................................................. 111 4.1.1 정의 .............................................................................................................. 111 4.1.2 행렬의 종류 .................................................................................................... 111

4.2 행렬의 연산 ............................................................................................................. 113 4.2.1 행렬과 행렬의 연산 .......................................................................................... 113 4.2.2 전치행렬 ........................................................................................................ 115 4.2.3 역행렬 ........................................................................................................... 117 4.2.4 행렬과 벡터의 곱셈 .......................................................................................... 117 4.2.5 스위즐 연산 .................................................................................................... 119 4.2.6 행우선과 열우선 .............................................................................................. 120 4.2.7 AoS와 SoA .................................................................................................. 122 4.2.8 행렬식 ........................................................................................................... 124 4.2.9 직교행렬 ........................................................................................................ 127

4.3 유니티 예제 : 행렬 계산을 위한 Inspector 확장 ............................................................. 129 4.3.1 유니티 에디터의 확장 기능 ................................................................................ 129 4.3.2 동작과 사양 .................................................................................................... 130 4.3.3 구현 코드 ....................................................................................................... 133

18


CHAPTER

5 좌표 변환 5.1 좌표 변환이란 무엇인가 ............................................................................................. 143 5.2 지오메트리 파이프라인 .............................................................................................. 145 5.2.1 모델 변환 ....................................................................................................... 145 5.2.2 뷰 변환 .......................................................................................................... 146 5.2.3 프로젝션 변환 ................................................................................................. 147

5.3 동차좌표계 .............................................................................................................. 152 5.3.1 동차좌표계란 무엇인가 ..................................................................................... 152 5.3.2 동차좌표계와 사영기하학 .................................................................................. 153 5.3.3 유니티의 동차좌표계 ........................................................................................ 154

5.4 변환 종류 ................................................................................................................ 155 5.4.1 선형 변환 ....................................................................................................... 155 5.4.2 아핀 변환 ....................................................................................................... 157 5.4.3 리지드바디 변환 .............................................................................................. 158 5.4.4 투영 변환 ....................................................................................................... 158

5.5 좌표 변환의 행렬 표현 ............................................................................................... 159 5.5.1 평행이동 ........................................................................................................ 159 5.5.2 회전 .............................................................................................................. 161 5.5.3 스케일 ........................................................................................................... 163 5.5.4 모델 변환 ....................................................................................................... 165 5.5.5 기저 변환 ....................................................................................................... 166 5.5.6 뷰 변환 .......................................................................................................... 168 5.5.7 원근투영 변환 ................................................................................................. 171 5.5.8 직교투영 변환 ................................................................................................. 179 5.5.9 등각투영 변환 ................................................................................................. 181

19


CONTENTS

5.6 유니티 예제 : 행렬에 의한 아핀 변환과 프로젝션 변환 ..................................................... 187 5.6.1 동작과 사양 .................................................................................................... 187 5.6.2 구현 코드 ....................................................................................................... 191

CHAPTER

6 사원수 6.1 회전표현의 종류 ....................................................................................................... 197 6.1.1 오일러각 ........................................................................................................ 197 6.1.2 로드리게스 회전 공식 ....................................................................................... 198 6.1.3 짐벌락 ........................................................................................................... 200 6.1.4 회전 행렬 문제 ................................................................................................ 202 6.1.5 사원수의 장점 ................................................................................................. 203

6.2 사원수의 정의 .......................................................................................................... 204 6.2.1 복소수 ........................................................................................................... 204 6.2.2 이원수 ........................................................................................................... 206 6.2.3 사원수란 무엇인가 ........................................................................................... 207

6.3 사원수의 연산 .......................................................................................................... 209 6.3.1 스칼라배 ........................................................................................................ 209 6.3.2 공액 .............................................................................................................. 209 6.3.3 크기 .............................................................................................................. 209 6.3.4 곱셈 .............................................................................................................. 209 6.3.5 단위 사원수 .................................................................................................... 210 6.3.6 내적 .............................................................................................................. 210 6.3.7 역수 .............................................................................................................. 211 6.3.8 행렬표현 ........................................................................................................ 212

6.4 사원수를 이용한 3D 회전 ........................................................................................... 213 6.4.1 회전 .............................................................................................................. 213 6.4.2 보간 .............................................................................................................. 220

20


6.5 쌍대 사원수 ............................................................................................................. 222 6.5.1 정의 .............................................................................................................. 222 6.5.2 스키닝에 응용하기 ........................................................................................... 222 6.5.3 연산 .............................................................................................................. 225 6.5.4 리지드바디 변환 .............................................................................................. 226

6.6 유니티 예제 : 사원수를 이용한 회전 ............................................................................. 227 6.6.1 동작과 사양 .................................................................................................... 227 6.6.2 구현 코드 ....................................................................................................... 228

CHAPTER

7 곡선 7.1 곡선을 둘러싼 개념 ................................................................................................... 235 7.1.1 보간과 근사 .................................................................................................... 235 7.1.2 매개변수 함수 ................................................................................................. 236 7.1.3 다항식 ........................................................................................................... 238 7.1.4 곡선과 스플라인 .............................................................................................. 239 7.1.5 연속성과 미분 ................................................................................................. 240 7.1.6 이원수를 이용한 자동미분 ................................................................................. 242

7.2 곡선 알고리즘 .......................................................................................................... 243 7.2.1 베지어 곡선 .................................................................................................... 243 7.2.2 캣멀롬 스플라인 .............................................................................................. 246 7.2.3 B 스플라인 ..................................................................................................... 249

7.3 유니티 예제 : 세 종류의 곡선 ....................................................................................... 254 7.3.1 동작과 사양 .................................................................................................... 254 7.3.2 구현 코드 ....................................................................................................... 258

21


CONTENTS

CHAPTER

8 게임 앱 환경 8.1 게임엔진으로서의 유니티 ........................................................................................... 267 8.1.1 씬 그래프 ....................................................................................................... 267 8.1.2 컴포넌트 지향 ................................................................................................. 268 8.1.3 샌드박스 ........................................................................................................ 271 8.1.4 게임 루프 ....................................................................................................... 273 8.1.5 CPU와 병렬성 ................................................................................................ 274 8.1.6 GPU 프런트엔드 ............................................................................................ 276

8.2 스마트폰 아키텍처 .................................................................................................... 277 8.2.1 그래픽스 드라이버 ........................................................................................... 277 8.2.2 드로 콜 배칭 ................................................................................................... 281 8.2.3 GPU 아키텍처의 변천 ..................................................................................... 284 8.2.4 저수준 그래픽스 API ....................................................................................... 288 8.2.5 헤테로지니어스 아키텍처 .................................................................................. 290

8.3 그래픽스 파이프라인 ................................................................................................. 293 8.3.1 OpenGL ES 2.0 ........................................................................................... 293 8.3.2 CPU의 드로 콜 생성 ........................................................................................ 294 8.3.3 버텍스 셰이더 ................................................................................................. 296 8.3.4 프리미티브 어셈블리 ........................................................................................ 297 8.3.5 래스터화 ........................................................................................................ 298 8.3.6 프래그먼트 셰이더 ........................................................................................... 299 8.3.7 ROP 처리 ...................................................................................................... 300 8.3.8 OpenGL ES 3.0 이후 ..................................................................................... 304 8.3.9 디퍼드 셰이딩 ................................................................................................. 304 8.3.10 테셀레이션 셰이더 ......................................................................................... 306 8.3.11 지오메트리 셰이더 ......................................................................................... 307 8.3.12 컴퓨트 셰이더 ............................................................................................... 308

22


CHAPTER

9 셰이더 9.1 유니티의 셰이더 ....................................................................................................... 311 9.1.1 ShaderLab ................................................................................................... 311 9.1.2 셰이딩 언어 .................................................................................................... 312 9.1.3 GLSL ........................................................................................................... 312 9.1.4 에디터 설정 .................................................................................................... 315 9.1.5 셰이더의 기본 ................................................................................................. 316 9.1.6 외부 도구와 WebGL ....................................................................................... 319

9.2 조명 ....................................................................................................................... 321 9.2.1 확산반사 ........................................................................................................ 321 9.2.2 램버시안 반사 모델 .......................................................................................... 322 9.2.3 하프 램버트 확산 ............................................................................................. 326 9.2.4 퐁 반사 모델 ................................................................................................... 328 9.2.5 정점 단위 조명 ................................................................................................ 329 9.2.6 픽셀 단위 조명 ................................................................................................ 331 9.2.7 림 라이팅 ....................................................................................................... 333

9.3 텍스처 처리 ............................................................................................................. 334 9.3.1 텍스처 매핑 .................................................................................................... 334 9.3.2 법선 매핑 ....................................................................................................... 336

9.4 물리 기반 렌더링 ...................................................................................................... 342 9.4.1 BRDF .......................................................................................................... 342 9.4.2 쿡토런스 경면 반사 .......................................................................................... 344

부록

A 유니티의 물리엔진 ....................................................................................................... 349

부록

B 코드 동작 환경 ........................................................................................................... 353

찾아보기 ...............................................................................................................................

356

23



CHAPTER

1

삼각함수

1.1 삼각형 1.2 직각삼각형 1.3 피타고라스의 정리 1.4 사인, 코사인, 탄젠트 1.5 삼각함수의 주기성 1.6 유니티 예제


이 장에서 배울 내용 요즘은 삼각함수(trigonometry)를 고등학교 수학에서 배운다. 실제 게임 제작에 응용되는 삼각함 수 지식은 학교에서 배우는 삼각함수 분야보다 훨씬 간결하며 다루기 쉽다. 이 책을 읽는 당신이 중 학생이나 고등학생이라 해도 이 장은 매우 간단하므로 안심하고 읽어나갈 수 있을 것이다. 이 장에서 배울 내용은 다음 2가지다. 사인, 코사인, 탄젠트

삼각함수는 ‘삼각’이란 이름이 들어가지만 영향 범위는 삼각형에 제한되지 않는다

그렇더라도 만만하게 보지 않고, 이 장에서 배울 내용을 머리로 깊이 생각하기 전에 우선은 체득하 기 바란다. 고대부터 연구되어 온 삼각함수는 오늘날 게임 개발에 관련한 온갖 장면에 등장하는 기 본 중 하나로, 이 책의 첫 장부터 마지막 장까지 반복해서 등장하기 때문이다. 시작부터 혼자 생각하 다 멈춰 서기보다는 이 세계가 그런 거라 각오하고 받아들이고, 게임 개발자로서 하루라도 빨리 출 발선에 서도록 하자.

26 유니티로 배우는 게임 수학


1.1 삼각형 게임을 즐기는 사람이라면 요즘 게임에는 다음 두 종류가 있다는 사실을 알 것이다. 이때 어느 한 쪽을 개발해야 한다면 어느 쪽이 어려울까? 2차원(2D ) 평면상에서 캐릭터가 움직이는 게임

3차원(3D ) 공간 내에서 캐릭터가 움직이는 게임

대개는 3D 쪽이 어려울 것으로 예상하지 않을까? 실제로 초기 제작 비용으로 말하자면 3D 쪽 이 많이 드는 경우가 대부분이다. 비용이 많이 든다는 말은 개발에 필요한 기술 수준에 대해서 도 그렇고, 게임을 실행하기 위해 컴퓨터에 필요한 계산량에 대해서도 그렇다. 하지만 2D와 3D가 서로 완전히 동떨어진 것은 아니다. 이 두 개념은 서로 이어진다. 그러므로

2D부터 학습하는 쪽이 이치에 들어맞는다. 그리고 삼각형 (triangle )이라는 가장 단순한 도형 은 2D 학습을 시작하는 단서로서 안성맞춤이다. 삼각형은 세 개의 정점 (꼭짓점, vertex )으로 이루어진다. 정점으로 세 개의 변 (edge )이 정해 진다(그림 1-1 ). 정점

정점

정점 변

그림 1-1 삼각형의 정점과 변

삼각형의 세 변 중 두 개의 변이 이루는 각을 내각 (interior angle )이라고 한다. 그리고 세 개 의 내각의 합은 항상 180도다(‘비유클리드 기하학’이라는 학문에서는 180도가 아니라고 보지 만, 이 책에서는 일반적인 게임을 만들 때 당장 필요 없는 지식은 다른 개념의 이해에 도움이 되는 것을 제외하고는 가능한 한 다루지 않는다). 또한, 삼각형은 항상 어딘가의 평면 위에 존 재한다.

CHAPTER 1 - 삼각함수

27


반면 정점이 네 개일 때는 그렇지 않다. 네 개의 정점으로 이루어진 사각형을 종이접기하듯 접 어서 두 개의 삼각형이 되는 모양을 상상해보자(그림 1-2 ).

그림 1-2 네 개의 정점이 있는 경우

이런 도형은 더 이상 평면상에 없고, 3차원 공간에밖에 표현할 수 없다. 따라서 삼각형을 사용 하면 지금 단계에서는 이야기가 단순해진다.

1.2 직각삼각형 삼각함수에서 주로 다루는 삼각형은 일반적인 삼각형보다 더 조건이 좁아져, 우리가 다루 기 쉽다. 바로 세 개의 정점 부분의 내각 중 하나가 직각( 90도)을 이루는 직각삼각형 ( right

triangle )이다.

빗변 높이

밑변 그림 1-3 직각삼각형

[그림 1-3]에서는 정점C 부분의 내각이 직각을 이룬다. 이 직각 맞은편의 비스듬한 변을 빗변 ( hypotenuse )이라고 한다. 또한, 바닥에 있는 것을 밑변 ( adjacent ), 남은 변을 높이

(opposite )라고 한다.

28 유니티로 배우는 게임 수학


직각삼각형에서 세 변의 길이와, 빗변과 밑변이 이루는 내각의 각도 θ (세타, theta ) 사이에 존재하는 관계를 이용해서, 예를 들어 빗변과 θ 가 주어졌을 때 다른 두 변의 길이를 산출하는 것이 삼각함수의 가장 기본적인 쓰임새다.

1.3 피타고라스의 정리 유명한 피타고라스의 정리 (Pythagorean theorem )는 빗변의 길이를 h , 밑변의 길이를 a , 높 이의 길이를 o 으로 했을 때, 다음 식이 성립한다는 것이다.

h2 = a2 + o2

정리 ( theorem )란 이미 증명( proof )된 명제로, 어쨌든 올바르다는 사실이 보증된 사항이다.

흥미가 있으면 증명 내용을 참조해도 좋지만, 일일이 그렇게 하기보다는 정리를 일단 블랙박스 처럼 다루면 된다. 즉, 증명의 결과만을 기반으로 다른 문제를 생각해도 좋다는 뜻이다. 수학에 서 신뢰성이 가장 높은 구성 요소라 볼 수 있다. 프로그래밍으로 말하자면, 정리는 가장 기본적 인 라이브러리 함수나 컴포넌트(부품)에 해당한다. 앞에서 예로 든 세 내각의 합이 항상 180 도라는 것도 증명된 정리다. 직각삼각형에서 내각 중 하나는 90도이므로 나머지 두 내각의 합 은 언제나 90도이고 그중 한 내각의 각도를 알면 다른 쪽 내각도 알 수 있다. 피타고라스의 정리를 이용하면, 세 변 중 두 변의 길이를 알 수 있는 경우 남은 변의 길이를 구 할 수 있다. 예를 들어 a = 3, o = 4일 때 다음처럼 계산할 수 있다.

h2 = a2 + o2

= 9 + 16

= 25

제곱하면 25가 되는 제곱근(square root )은 5이므로 h = 5이다.

CHAPTER 1 - 삼각함수

29


1.4 사인, 코사인, 탄젠트 직각삼각형에서 변을 두 개 선택한 경우 두 변의 길이의 비율(삼각비)은 θ 의 각도에 따 라 변화한다. 따라서, 변화하는 매개변수 ( parameter ) θ 를 입력받아, 출력되는 결괏값이 변화하는 함수(function ) 형식으로 각 변수 사이의 관계를 나타낼 수 있다. 직각삼각형에는 세 개의 변이 있다(빗변, 밑변, 높이). 그중 단순히 두 변끼리의 비율만 생각 해봐도 3가지가 되고, 세 개의 식이 필요하다는 것을 알 수 있다. 차례대로 살펴보자. 우선 사인 (정현, sine )의 정의다. sinθ =

높이 빗변

sinθ 는 각도가 θ 일 때 빗변과 높이의 비율을 나타낸다. 즉, 빗변의 길이와 θ 의 각도를 알고 있을 때 빗변의 길이에 sinθ 를 곱하면 높이의 길이를 구할 수 있다.

빗변 높이

밑변 그림 1-4 사인

다음처럼 sinθ 의 역수 (reciprocal, 어떤 수와 곱해서 1이 되는 수)를 이용하여, 높이의 길이 와 θ 의 각도로부터 빗변의 길이를 얻을 수도 있다(이 수에도 코시컨트(여할, cosecant )라는 이름이 붙어 있지만 일부러 기억할 만큼 유용하지는 않다). 높이 1 = sinθ 빗변

30 유니티로 배우는 게임 수학


다음은 코사인 (여현, cosine )의 정의다.

cosθ =

밑변 빗변

사인과 다르게, 코사인은 빗변과 밑변의 비율을 나타낸다. 빗변과 내각 θ 가 있으면 빗변의 길 이 cosθ 를 곱해 밑변을 구할 수 있다.

빗변 높이

밑변 그림 1-5 코사인

마지막은 탄젠트 (정접, tangent )의 정의다.

tanθ =

높이 밑변

탄젠트는 밑변과 높이의 비로, 그림으로 나타내면 다음과 같다.

빗변 높이

밑변 그림 1-6 탄젠트

CHAPTER 1 - 삼각함수

31


지금까지 설명한 사인, 코사인, 탄젠트는 자주 등장하므로 [그림 1-7]처럼 기억해두는 게 좋다.

그림 1-7 사인, 코사인, 탄젠트의 관계

또한, 내각 θ 를 매개변수로 받아 각 변끼리의 비율을 반환하는 사인, 코사인, 탄젠트에 대응해 그 역함수(inverse function )로서 각 변끼리의 비율을 매개변수로 하여 내각 θ 의 각도를 구 하는 일련의 함수도 있다. 아크사인 ( arcsine ), 아크코사인 ( arccosine ), 아크탄젠트 ( arctangent )를 사용하면 각각 사

인, 코사인, 탄젠트 값으로부터 대응하는 각도 θ 를 산출할 수 있다.

θ = arcsin(sinθ)

θ = arccos(cosθ)

θ = arctan(tanθ)

다시 말해, 삼각형의 세 변 중 두 변의 길이를 알 때 이 역함수들을 적용하면 내각 θ 의 각도를 구할 수 있다.

1.5 삼각함수의 주기성 1.5.1 단위원 앞에서 삼각함수는 변화하는 매개변수 θ 에 의존하는 함수라고 설명했다. 지금까지 직각삼각형 을 염두에 두고 삼각함수의 개념을 살펴봤지만, 이 경우 θ 가 0도보다 크고 90도보다 작은 각 도로 한정되는 문제점이 있다. 그 범위가 아니면 애초에 삼각형을 그릴 수 없다(삼각형의 내각 의 합은 180도라는 정리에 따른다).

32 유니티로 배우는 게임 수학


그래서 이번에는 직각삼각형뿐만 아니라, 직각삼각형을 포함하는 원을 통해 삼각함수를 표현 하는 방법을 사용한다(그림 1-8 ).

그림 1-8 단위원

이 그림은 반지름(radius )의 길이가 1인 원, 즉 단위원 (unit circle )에, 조금 전까지 설명에 사용한 AB가 빗변이고 AC가 밑변인 직각삼각형 ABC를 둔 것이다. 이때 단위원의 중심은 x 축과 y 축이 있는 좌표축의 원점(0,0 )에 존재한다. 이렇게 표현하면, θ 의 각도만 변동한 경우 도 빗변 AB의 길이는 항상 1이므로, 사인과 코사인의 정의를 적용하면 B의 xy 좌표축에서의 좌표는 항상 (cosθ , sinθ )가 되어 이해하기 쉽다. 삼각형 ABC에 피타고라스의 정리를 적용하면 다음과 같은 관계를 도출할 수 있다.

(sinθ)2 + (cosθ)2 = 1

이 식은 피타고라스 삼각항등식 ( Pythagorean trigonometric identity )으로 불리는 일련의 관계를 도출하기 위한 기초가 되는 공식 (formula )이다. 공식이란 수식으로 대표되는, 기호의 집합으로 이루어진 형식언어 (formal language )로써 정리를 표현한 것이다.

CHAPTER 1 - 삼각함수

33


1.5.2 코사인법칙 사인, 코사인, 탄젠트 그리고 피타고라스 삼각항등식의 기초 공식을 알았으니, 공식을 사용해 서 이번에는 직각삼각형이 아닌 일반 삼각형에 성립되는 성질에 관해서도 학습하자.

그림 1-9 코사인법칙

[그림 1-9]처럼 세 변의 길이가 각각 a , b , c 이고 b 와 c 의 내각이 θ 인 삼각형을 떠올려보자.

s는 q에서 pr을 향해 수직으로 내린 직선과 pr의 교점이다. 여기서, 직각삼각형 pqs는 피타고 라스의 정리를 이용해 다음처럼 나타낼 수 있다. a 2 = (b - c cosθ)2 + (c sinθ)2

여기서부터 우변을 전개해 나간다. a 2 = (b - c cosθ)2 + (c sinθ)2

= b 2 - 2bc cosθ + c 2 (cosθ)2 + c 2(sinθ)2

= b 2 + c 2 ((cosθ)2 + (sinθ)2) - 2bc cosθ

= b 2 + c 2 - 2bc cosθ

3행째에서 앞에서 본 (sinθ )2 + (cosθ )2 = 1이라는 식을 적용했다. 이렇게 구한 식을 코사인 법칙 ( law of cosines )이라고 부른다.

a 2 = b 2 + c 2 - 2bc cosθ

코사인법칙은 직각삼각형뿐만 아니라 일반 삼각형에도 성립하는 성질이다. 피타고라스의 정리 는 코사인법칙의 특수한 케이스다(θ 가 직각인 경우 cosθ = 0 ).

34 유니티로 배우는 게임 수학


1.5.3 주기성 단위원을 사용하면 원점을 축으로 원의 반지름을 회전시킴으로써 90도보다 큰 각도에서 삼각 함수의 수치를 표현할 수 있다(그림 1-10 ).

그림 1-10 90도보다 큰 각도의 삼각함수 값

90도보다 큰 각도 θ 의 점 P의 x 좌표는 cosθ 값을 나타내고, y 좌표는 sinθ 값을 나타낸다. x 좌표가 마이너스 위치에 있으므로 θ 가 90도보다 크고 270도보다 작을 때는 코사인 값이 음 수가 된다는 사실도 이 그림으로 알 수 있다. 사인, 코사인, 탄젠트가 xy 평면의 각 사분면에서 양수와 음수 중 어느 쪽 부호를 갖는지 정리 한 것이 [그림 1-11]이다.

2사분면

1사분면

sinθ = 양수 cosθ = 음수 tanθ = 음수

sinθ = 양수 cosθ = 양수 tanθ = 양수

3사분면

4사분면

sinθ = 음수 cosθ = 음수 tanθ = 양수

sinθ = 음수 cosθ = 양수 tanθ = 음수

그림 1-11 각 사분면의 삼각함수 부호

CHAPTER 1 - 삼각함수

35


이렇게 해보면, 4사분면에서 360도까지의 각도 θ 인 삼각함수를 다룰 수 있다는 것은 알 수 있 지만, 360도보다 큰 각도일 때는 어떻게 되는지 명확하지 않다. 하지만 걱정할 필요는 없다. θ 가 360도 이상일 때는 다시 0도로 돌아온 듯 움직이고, 이후로 는 그 동작을 360도마다 계속 반복할 뿐이다. 다시 말해, 사인, 코사인 값은 같은 변화 형태를 쭉 반복한다. 이것을 삼각함수의 주기성 (periodicity )이라고 한다.

1.5.4 라디안 실제 삼각함수의 값을 표시한 것이 [그림 1-12]다. 여기서 90도에 대응하는 π , 180도에 대응 2 하는 π라는 표기가 있다. 이 표기는 라디안 (호도, radian )으로 불리는 형식으로 수학과 프로 그래밍 분야에서 각도를 나타내는 데 쓰인다.

2사분면

1사분면

3사분면

4사분면

그림 1-12 삼각함수의 실제 값

단위원의 점 D : (1, 0 )에서부터 단위원의 원호에서 길이 1만큼 이동한 점을 P라고 한다. 즉, [그림 1-13]처럼 반지름과 호의 길이가 같아진 상태의 P다. 이때 θ 의 각도를 1라디안라고 하 는 것이 라디안 형식의 기본 개념이다(일반적으로 라디안으로 각도를 표현할 때는 1라디안을

1로만 쓰고 단위를 생략하므로 이 책에서도 이후로는 생략한다).

36 유니티로 배우는 게임 수학


길이 1

그림 1-13 라디안

그럼, 왜 90도가 라디안으로 하면 π 로 표현되고, 180도가 π로 표현되는 것일까? π가 ‘원주율’ 2 로 불리며, 원주의 길이를 계산할 때 상수(constant )로 이용되는 것을 떠올려보자. 원주의 길 이를 C, 반지름의 길이를 r 이라고 했을 때 원주의 길이 C를 구하는 공식은 다음과 같다. C = 2πr 단위원의 θ 가 360도일 때 점 P는 원래 점 D로부터 원주 위를 일주하고 원주의 길이 C 만큼 이동한 위치에 있게 된다. 그리고 원주의 길이를 구하는 공식에서 단위원은 r = 1이 므로, C = 2π다. P가 원주 위를 이동한 원호의 길이가 1일 때 θ 를 라디안으로 나타내면

1이었다. 그러므로, 이번에 θ 가 360도일 때 P는 원호의 길이가 2π인 위치에 있다. 다시 말해, 이때의 θ 는 라디안으로는 2π다. 따라서, 360도는 라디안으로 표현하면 2π와 같다. 그러므로 절반인 180도는 π다. 상수 π 를 사용하는 한 도수법으로 표현하기보다 라디안으로 표현하는 쪽이 간결하므로, 수학 이나 프로그래밍 분야에서는 각도를 라디안으로 표현하는 것이 일반적이다. 원의 중심을 축으 로 반지름을 얼마나 돌렸는지와 같은 원호의 길이가 그대로 각도가 되므로, 360이라는 어디서 나왔는지 알 수 없는 수치를 사용하는 바빌로니아 각도법보다는 라디안 쪽이 자연스럽고 직관 적이기까지 하다. 또한, 삼각함수를 미분할 때 라디안을 사용하면 sinθ 의 도함수를 cosθ 로, cosθ 의 도함수를 -sinθ 로 표현할 수 있는 성질도 있다. 미분에 관해서는 7장에서 다룬다. 다만, 각도에 의한 표현도 관례적으로 많이 이용되고 나름대로 생활 속에 스며들어 있으므로 라디안 수치와 혼동하지 않도록 주의해야 한다.

CHAPTER 1 - 삼각함수

37


1.5.5 덧셈정리 다시 단위원을 보면, 내각 α 위치에 있는 점 P: (cos α , sin α )를 β 만큼 회전 이동한 점의 좌 표가 P’: (cos (α + β ), sin (α + β ) )라는 것도 알 수 있다(그림 1-14 ).

그림 1-14 덧셈정리

그럼 cos (α + β ), sin (α + β )는 어떻게 구하면 좋을까? 다행히 이 값들을 구할 수 있는 덧셈정 리 ( addition theorem )가 존재하며, 다음과 같은 관계가 성립한다.

sin(α ±  β) = sin α cos β ± cos α sin β

cos(α ±  β) = cos α cos β

sin α sin β

±

덧셈정리를 P' 에 적용해보면, 원래 점 P: (cos α , sin α )를 β 만큼 회전한 점 P' 의 위치는 다음 과 같다.

(cos α cos β - sin α sin β, sin α cos β + cos α sin β)

이 식은 좌표의 임의의 점(x , y )에 대한 원점 중심의 회전 알고리즘으로 사용할 수 있다. 회전 원의 점 P의 좌표인 cos α 를 x 로, sin α 를 y 로 치환해주면 된다. (x , y )를 β 만큼 회전한 점 의 위치는 다음과 같다. (x cos β - y sin β, y cos β + x sin β)

이 덧셈정리에서는 다양한 공식을 도출할 수 있다고 알려졌다. 예를 들어 반각의 공식 (half-

angle formulas )은 다음과 같다.

38 유니티로 배우는 게임 수학


( sin θ2 )

( cos 2 )

θ

2

=

1 - cosθ 2

2

=

1 + cosθ 2

1.5.6 사인파, 코사인파 π

90도( 2 )보다 큰 각도도 단위원을 사용하면 사인과 코사인의 값을 시각적으로 표현할 수 있다 는 것을 알았다. 한편으로 원이라는 도형의 반지름을 도는 한 최대 각도는 360도뿐이다. 360 도보다 큰 각도로 회전시킨 삼각함수의 값은 단위원을 몇 번이고 돌면서 주기적으로 같은 값을 취한다는 것을 머리로는 알아도 시각적으로 표현하기는 어렵다. 따라서, 이번에는 도형의 성질을 연구하는 기하학(geometry )적 표현을 떠나 함수의 변화량 을 살피는 해석학(analysis )적 그래프 표현으로 삼각함수를 생각하기로 한다. 우선은 θ 의 라디안을 가로축으로 했을 때 사인 값을 세로축으로 하는 그래프를 만든다(그림

1-15 ). 2π를 1주기로 해서 0 → 1 → 0 → -1 → 0이라는 값의 변동이 계속 반복한다. 이 주 기(period )를 기본주기라고 부른다. 일반적으로 상수 P에 대해서 f (x + P ) = f (x )가 성립하 는 함수를 주기함수라고 부르지만, 사인에 대해서는 P = 2 π다. 즉, 다음 식이 성립한다. sin(x + 2π) = sin(x)

π가 약 3.14라는 것을 생각하면 이 그래프는 완만한 호를 그리는 파형을 반복한다. 이 파형을 사인파 ( sine wave )라고 부른다. 자연계의 음파나 전파도 이 사인파로 표현할 수 있다(덧붙 1 여, 주파수 (frequency )란 주기의 역수를 나타낸다. 즉, 주기가 2π인 사인파의 주파수는 2π

이 된다). 코사인 값도 살펴보자. 사실은 코사인 값을 표시한 그래프도 사인파와 완전히 같은 파형으로 되어 있다. 단, 한 군데 차이가 있으므로 사인파와 같은 그래프에 표시하여 비교해보겠다(그림

1-16 ).

CHAPTER 1 - 삼각함수

39


그림 1-15 사인파

그림 1-16 사인파와 코사인파

π

사인파를 x 축 방향으로 - 2 이동시키면 코사인파 (cosine wave )와 일치한다. 다시 말해, 코 1

π

사인파는 사인파보다 원 주기의 4 만큼(즉 2 ) 빠르게 물결친다. 이 관계를 식으로 표현하면 다음과 같다.

cos(θ) = cos(-θ) = sin(

π -θ 2

)

sin(θ) = -sin(-θ) = cos(

π -θ 2

)

π

코사인파에서도 기본주기는 2π이지만, 사인파와 2 어긋나 있으므로 1 → 0 → -1 → 0 → 1 로 값이 변화한다. 이 사인파, 코사인파의 형상은 편리해서 조금만 가공해도 쉽게 변종을 만들어낼 수 있다. 예를 1

들어, 매개변수 x 를 2 로 하면 더 완만한 곡선이 되며 2배로 하면 더 빠르게 물결치듯 그려진 다(그림 1-17 ).

40 유니티로 배우는 게임 수학


그림 1-17 매개변수와 사인파 형상의 관계

또한, sinθ 의 절댓값(magnitude )인 |sinθ |를 사용하여 값이 음수가 되는 부분의 부호를 양 수로 만들어 그래프를 반대편으로 꺾으면, 구체가 바운드하는 모습의 그래프를 만들 수도 있다 (그림 1-18 ).

그림 1-18 사인함수의 절댓값

CHAPTER 1 - 삼각함수

41


1.6 유니티 예제 : 클릭 위치를 향하는 캡슐·바운드하는 구체 1.6.1 동작과 사양 삼각함수에 관한 설명은 이상으로 대충 끝났다. 이제부터는 유니티에서 삼각함수를 이용하여 간단한 프로젝트를 실제로 움직여보고 삼각함수를 어떻게 사용할 수 있는지 확인한다. 우선, 유니티 메뉴에서 File → Open Project를 클릭하고, Open에서 샘플 프로젝트 폴더를 선택하여 프로젝트를 연다(그림 1-19 ).

그림 1-19 예제 프로젝트 폴더를 지정해서 연다

42 유니티로 배우는 게임 수학


프로젝트가 열리면 이번에는 메뉴의 File → Open Scene에서 sample 프로젝트 폴더 내의 Assets/Scenes 폴더에 있는 Main.unity를 선택해서 연다(그림 1-20 ).

그림 1-20 Main.unity를 선택하여 연다

Main 씬(scene )이 열리면, 그 상태에서 유니티의 재생 버튼(▶)을 누른다(그림 1-21 ).

그림 1-21 Main 씬

CHAPTER 1 - 삼각함수

43


예제 프로젝트가 재생되고 챕터 선택 화면이 나오면 [Chapter1] 버튼을 누른다(그림 1-22 ).

그림 1-22 챕터 선택 화면

[Chapter1] 버튼을 누르면 씬이 전환되고, 화면에 [Back] 버튼과 함께 끝이 둥근 원기둥 모 양 캡슐이 보인다(그림 1-23 ). 이때 [Back] 버튼을 마우스로 클릭하면 원래 챕터 화면으로 돌아온다.

그림 1-23 Chapter1 씬

44 유니티로 배우는 게임 수학


이 씬에 구현된 기능은 2가지다. 화면의 임의의 점을 클릭하면, 캡슐의 끝(시작은 화면 위를 향한다)이 클릭한 위치로 방향을 바꾼다.

화면의 임의의 점을 클릭하면, 그 위치에 구체가 나타나고 화면 중앙을 향해 바운드하듯 움직인다.

유니티의 카메라 이 기능을 구현한 코드를 보기 전에 유니티 카메라에 관해서 설명한다. 우선 유니티 화면 내에서의 Hierarchy라는 표시가 있는 영역에서 Main Camera를 선택한 다. Hierarchy는 유니티의 현재 씬에 있는 물체(오브젝트)가 모두 계층적으로 등록되어 있는 목록이다(비표시인 것을 포함). 유니티에서는 게임 내의 세계를 임의의 각도에서 잘라내 사용자에게 비추는 카메라도 Hierarchy에 등록되며, 그 동작을 Inspector의 GUI와 C# 스크립트로 컨트롤할 수 있다. Inspector는 Hierarchy에서 선택된 특정 오브젝트에 어떤 컴포넌트가 추가됐는지, 또한 각 컴포넌트가 어떤 프로퍼티(속성)를 가지는지 살펴보기 위한 뷰(유니티 에디터의 탭)다. 또한, 단순히 보기만 하는 게 아니라, 실제로 속성 값을 변경하거나 컴포넌트를 추가·제거하는 조작 을 실행할 수 있다. Main Camera를 선택하면(그림 1-24 ), Inspector에 Main Camera의 속성이 표시된다 (그림 1-25 ).

그림 1-24 Hierarchy의 Main Camera 선택

CHAPTER 1 - 삼각함수

45


그림 1-25 Camera 컴포넌트

Main Camera에는 씬의 내용을 화면에 비추는 카메라 역할을 담당하는 Camera라는 유 니티 컴포넌트( component ), 즉 부품이 추가되어 있고, 그 컴포넌트의 Projection 항목 이 Orthographic으로 설정되어 있다. Orthographic은 씬의 내용을 평면적으로 비추는 카 메라 설정이고 주로 2D 게임에 사용한다. 이 항목을 Perspective로 변경하면 3D용 카메 라가 된다(이 예제는 Perspective에서도 동작하게 만들어졌지만 미묘하게 달라 보인다).

Camera 속성에 관해서는 5장에서 자세히 설명한다.

최종적으로 구하는 각도 그럼 우선, 첫 번째 기능인 ‘화면의 임의의 점을 클릭하면, 캡슐의 끝(시작은 화면 위를 향한 다)이 클릭한 위치로 방향을 바꾼다’를 살펴보자. 구현에 앞서 기능을 구현하기 위해 무엇이 요구되는지 그림을 그려 확인한다(그림 1-26 ).

46 유니티로 배우는 게임 수학


그림 1-26 캡슐의 방향과 각도

A가 위로 향한 캡슐의 중심이고 B가 마우스로 클릭한 점이라고 할 때, β 의 각도를 알고 각도 β 만큼 B쪽으로 캡슐을 기울이면 요구하는 동작을 구현할 수 있음을 알 수 있다. 다시 말해, A는 움직이지 않고 AD를 AB 쪽으로 시계 방향으로 회전해서 기울여야 한다. 여기서 단위원을 떠올려보자. 단위원에서는 AC의 위치에서 원의 반지름을 반시계 방향으로 얼 마나 많이 돌렸는지로 각도를 표현했다. 이번에는 AD가 AB를 향해 시계 방향으로 회전한다. 즉, β 에 부호를 붙여 –β 만큼 원래 AD를 AB쪽으로 돌리면 된다.

β 와 α 의 합은 90도이므로, α 를 알면 β = 90 - α 로 구해진다. 단, 필요한 것은 –β 이므로 양 변의 부호를 반전시킨 다음 수식을 통해 최종적으로 필요한 각도를 구할 수 있다.

–β = α – 90

B좌표와 A좌표의 차이를 구하면 직각삼각형 ABC의 밑변 길이 x 와 높이 y 를 알 수 있다. 밑변과 높이의 길이를 알면 아크탄젠트를 사용해 α 의 각도를 알 수 있다. α 의 각도를 알면 –β = α – 90로 원하는 각도의 값을 구할 수 있다. 다시 말해, 아크탄젠트로 구한 각도에서

90도를 뺀 각도가 최종적으로 원하는 각도다. 이 일련의 흐름을 코드로 어떻게 표현할지, 이제부터 실제 C# 스크립트를 따라가보자.

CHAPTER 1 - 삼각함수

47


이번 경우에는 마우스와 키보드로부터의 입력량이 0이 아니고 입력으로서 의미가 있는 양인 지 판단하고자 제곱을 한 다음 매우 작은 부동소수점 수를 나타내는 Mathf.Epsilon보다 커 야 한다는 조건을 둔다(마찬가지로 float형끼리 비교할 경우는 = = 연산자를 사용하지 않고,

Mathf.Approximately를 사용해서 모호한 비교를 해야 한다). Update 메서드의 마지막은 Transform.LookAt 메서드를 이용해 pivot으로 설정한 게임 오브젝트(이번엔 정육면체) 쪽으로 이 스크립트가 추가된 오브젝트의 방향을 돌린다. transform.LookAt(pivot.position);

이 처리에 의해, 이 스크립트가 추가된 카메라는 항상 정육면체 쪽을 향하게 된다. 실은 1장에 서 구현한 캡슐을 회전시켜 클릭한 지점으로 향하게 하는 처리는 이 3D 공간에서의 LookAt 메서드를 2D용으로 스크립트로 구현한 것이다. 다시 말해, 여기서 사용한 LookAt 메서드는

3D 공간에서의 회전을 의미한다. 회전에 관해서는 6장에서 자세히 설명한다.

82 유니티로 배우는 게임 수학


CHAPTER

3 벡터

3.1 벡터의 정의 3.2 벡터 연산 3.3 유니티 예제

CHAPTER 3 - 벡터

83


이 장에서 배울 내용 이 장에서는 삼각함수에 이어 게임 프로그래밍에 필수적인 수학 개념 가운데 가장 기본적인 것 중 하나인 벡터(vector)의 성질을 학습한다. 삼각함수가 고대로부터 연구되어 온 반면, 벡터는 19세기 에 뫼비우스, 해밀턴, 그라스만 같은 수학자들이 만들어낸 비교적 새로운 개념이다. 학교 교육에서 등장하는 화살표처럼 생긴 벡터의 이미지와는 달리, 예를 들어 벡터 계산기로 불리 는 슈퍼컴퓨터가 채용한 CPU는 배열 내의 데이터군을 단번에 병렬로 처리하는 SIMD 명령을 구현 한다. 컴퓨터에서 사용되는 벡터의 이미지는 용어는 같아도 화살표 벡터와 바로 연결되진 않을 것이 다. 하지만 둘 다 똑같은 개념을 다른 측면에서 바라본 것에 지나지 않는다. 게임 개발에 도움이 되는 벡터의 주제는 삼각함수 때와 마찬가지로 실질적으로는 그렇게 많지 않 으므로, 지금까지 학습한 삼각함수와 좌표계 지식을 지렛대 삼아 효율적으로 학습을 진행하고자 한다.

84 유니티로 배우는 게임 수학


3.1 벡터의 정의 3.1.1 수벡터 사실 이 책에는 이미 벡터가 코드에 들어가 있다. 2장에서 3D 좌표계를 다뤘을 때, (x , y , z ) 와 같은 수치의 배열(array )을 좌표라 부르며 특정 위치를 나타내는 데 사용했다. 그때 유니티 예제 코드에서는 Vector3라는 구조체에 해당 좌표를 넣었다. 유니티에서의 벡터 표현은 마찬 가지로 Vector3를 이용한다. 위치로서의 벡터는 위치 벡터 (position vector )라 불린다.

Vector3는 이들 세 개의 x , y , z 프로퍼티를 이용해 3차원 공간 안의 점을 표현할 수 있다. 또한, 유니티에는 Vector2라는 형도 있어, 2차원 평면 위의 점을 (x , y )로 표현할 수 있다. 이처럼 2차원이나 3차원에서의 점의 위치를 수치의 조합으로 나타낼 경우, 이 조합의 순서에 는 의미가 있다. x , y , z 의 순서를 (x , y , z ) 안에서 바꿔 버리면 전혀 다른 좌표가 된다. 다시 말해, 이 수치의 조합은 각 요소에 순서가 정해진 배열이지 단순한 수치의 집합(set )이 아니 다. 이처럼 순서가 있는 수치로 조합된 벡터를 수벡터 (numerical vector )라 부른다. 또한, Vector2와 Vector3가 각각 요소 두 개, 요소 세 개인 배열이고, 각각 2차원, 3차원인 벡터를 표현할 수 있었듯이 n개 요소의 배열로 n차원의 벡터를 표현할 수 있다(앞에서 언급한 벡터 계산기의 벡터란 이런 데이터의 배열을 가리킨다). 배열로 벡터를 표현한 경우 하나하나의 요소를 벡터의 성분 (component )이라고 한다. (x ,

y )라는 2차원 벡터의 성분은 x 와 y 다. 나아가 (x , y , z )처럼 성분을 옆으로 나열한 행벡터 (row vector ) 형식 외에, 다음과 같이 성분을 세로로 나열하는 열벡터 (column vector )라는 표기 방식도 있다. 이 둘은 벡터로서 동일하다.

() x

y z

성분의 배열로써 대수학적으로 벡터를 생각하는 방법은, 위치 벡터가 좌표로 사용되던 것처럼

2장에서 학습한 좌표계에 의존한다. 어느 좌표계를 선택할지 또는 좌표계의 원점이 어디인지 에 따라 벡터의 성분은 변화한다. 유니티로 말하자면, 월드 좌표계가 포함하는 각 로컬 좌표계 내의 위치 벡터는 비록 월드 좌표

CHAPTER 3 - 벡터

85


계의 같은 위치를 나타내더라도 다른 성분을 가진다. 다시 말해, 위치 벡터는 상대적인 것에 지 나지 않는다. 또한, 예를 들어 3D 공간의 좌표계라면 x 축 방향으로 3, y 축 방향으로 4, z 축 방향으로 5 이 동한 변위 (displacement )를 나타날 때도 수벡터를 사용할 수 있다(이 경우는 (3, 4, 5 ) ). 따 라서, Vector3가 유니티 스크립트에 등장하면 그 값이 위치를 가리키는지 변위를 가리키는지 구별할 수 있도록 관리해야 한다.

3.1.2 기하벡터 성분의 배열로 본 벡터 표현과 달리, 화살표를 통해 벡터를 시각적으로 표현할 수 있다. 이 표 현은 크기 (magnitude )와 방향 (direction )을 가진 양으로서 벡터를 정의하는 방법이다. 벡터 의 화살표가 시작되는 점을 시점 (initial point ), 화살표 끝 점을 종점 (terminal point )이라 고 한다(그림 3-1 ). 크기

시점

종점

방향

그림 3-1 기하벡터

또한, 시점이 A, 종점이 B인 벡터 v 는 다음처럼 표기한다. 단, 식 안의 모든 양이 벡터인 경우 처럼 이 표기법을 항상 적용하기가 번잡할 때는 화살표 기호를 많이 생략하기도 한다. 또한 이 책에서는 한 글자로 벡터를 나타낼 때 a , v 처럼 볼드체(굵은글씨)로 표기한다.

v = AB

이 기하학적 벡터는 좌표계와 관계없이 존재한다. 이런 벡터를 기하벡터 (geometric vector ) 라 한다.

→ →

여기서, 벡터 AB에 평행(다시 말해 같은 방향)이고, 크기가 같은 벡터인 A’B’를 생각해보자.

이때 AB와 A’B’의 시점과 종점은 다르다. 이런 경우에도 AB는 A’B’와 같다고 보는 것이 기 하벡터의 사고 방식이다(그림 3-2 ). 일반적으로 벡터라고 하면 기하벡터를 가리키는 일이 많

86 유니티로 배우는 게임 수학


다. 한편 좌표계와 원점이 없는 기하벡터가 존재하는 장소를 아핀 공간 (affine space )이라 부 른다.

그림 3-2 같은 기하 벡터

3.1.3 스칼라 크기와 방향이 있는 양을 가리켜 벡터라고 한다면, 크기만 있는 일반적인 수치는 보통 스칼라 (scalar )로 부른다. 위치 벡터에서 요소 하나하나는 스칼라였다. 길이, 질량 또는 시간은 당연 히 방향이 없으므로 모두 스칼라다. 덧붙여, 처음에 언급했던 벡터를 계산하는 벡터형 CPU와 달리, 명령 하나에 한 개 또는 두 개 의 데이터를 처리하는 일반 CPU는 스칼라형 CPU라 한다. 또한, 복수의 실행 유닛으로서의 파 이프라인 스테이지군을 CPU 내부에 설치함으로써 스칼라형 CPU로 복수 명령의 병렬 실행을 가능하게 하는 아키텍처(구조, architecture )를 슈퍼 스칼라 (superscalar )라고 한다. 컴퓨터의 CPU로서는 크기와 방향을 가진 양으로서의 기하벡터 자체를 직접 처리할 수 없으므 로, 어디까지나 스칼라양 또는 스칼라 배열로 수벡터를 처리한다.

3.2 벡터 연산 3.2.1 덧셈·뺄셈·교환법칙·결합법칙 기하벡터는 기하학적 표현을 매개로 시각적으로 상기할 수 있으므로, 기하벡터에 기초적 연산 을 정의할 수 있다는 점도 확인하기 쉽다.

CHAPTER 3 - 벡터

87


그림 3-3 벡터의 덧셈·뺄셈·교환법칙·결합법칙

기하벡터 a와 기하벡터 b가 있을 때, [그림 3-3]과 같이 a의 시점부터 b의 종점에 이르는 벡 터를 a와 b의 합으로서 벡터의 덧셈을 정의할 수 있다. 또한, 다음 식이 성립한다. 이 상태를 교환법칙이 성립( commutative )했다고 한다.

a+b = b+a

기하벡터 b를 역방향으로 한 역벡터 (inverse vector )인 –b도 정의할 수 있어, 다음처럼 벡 터의 뺄셈을 나타낼 수 있다. a + (-b) = a - b

뺄셈은 다음과 같이 우변에 마이너스 부호를 적용할 필요가 있으므로, 교환법칙이 성립하지 않 아 반가환 (anticommutative )이다. a - b = -(b - a)

또한, [그림 3-3]을 보면, b에 –b를 더한 경우는 원래 시점으로 되돌아가므로, 시점에서 시점 으로 향하는, 길이가 0이고 방향도 없는 벡터가 된다는 것을 알 수 있다. 이 특별한 벡터를 영벡 터 ( zero vector )라고 부른다. 영벡터 0에 관해서는 다음 식이 성립한다.

a+0 = 0+a = a

88 유니티로 배우는 게임 수학


또한, 기하벡터 c가 하나 더 있을 때는 다음과 같다.

(a + b) + c = a + (b + c)

이처럼 괄호의 위치를 이동해도 결과가 같은 상태를 결합법칙 ( associative )이 성립했다고 한다.

3.2.2 스칼라 곱셈·나눗셈 벡터의 덧셈·뺄셈은 벡터끼리 연산했지만, 벡터에 스칼라를 곱해 스칼라 곱을 구하거나 벡 터를 스칼라로 나눌 수 있다. 그 결과는 다른 길이의 새로운 벡터가 된다. 스칼라의 수만큼 원 래의 벡터가 늘어나는(음수인 경우는 역방향) 것은 직관적으로 이해하기 쉬울 것이다(그림

3-4 ).

그림 3-4 벡터의 스칼라 배

또한, 벡터 a, b와 스칼라 c 에 대해 다음처럼 분배법칙 (distributive )이 성립한다.

c(a + b) = ca + cb

3.2.3 단위벡터 지금까지 그림으로 기하벡터의 연산법칙을 확인했지만, 사실은 수벡터에도 같은 연산법칙이 성립한다.

CHAPTER 3 - 벡터

89


크기가 1인 벡터는 단위벡터 (unit vector )라 한다. 벡터 a와 같은 방향의 단위벡터 u는, a의 길이 |a |로 a 를 나누거나 또는 |a |의 역수(reciprocal )를 곱해서 구할 수 있다.

u =

a |a|

또한, 본래의 벡터 a 에 대해 그 단위벡터를 â 로 표기하기도 한다. 단위벡터를 구하는 조작을 가리켜 벡터를 정규화한다 ( normalize )고 표현한다. 유니티의

Vector3 클래스의 normalized 프로퍼티는 이 같은 정규화를 반영한다. normalized를 사 용하면 원래 벡터의 단위벡터를 구할 수 있다.

3.2.4 기저와 좌표계 3D 직교좌표계에서 원점에 해당하는 위치를 시점으로 x 축, y 축, z 축 방향으로 각각 단위벡터 i , j , k 가 뻗어 있다고 가정하자(그림 3-5 ).

그림 3-5 기저와 좌표계

이때 해당 좌표계상의 임의의 점을 가리키는 위치벡터 a 는 다음과 같은 식으로 나타낼 수 있다. a = ax + ay + az

여기서 a x , a y , a z 는 각각 i , j , k 를 스칼라양 x , y , z 로 곱한 것이다. a = xi + yj + zk

다시 말해, a 의 종점 좌표는 (x , y , z )다.

90 유니티로 배우는 게임 수학


이처럼 기하벡터를 이용해도 직교좌표계를 표현할 수 있고, 또 거꾸로 기하벡터를 좌표의 수벡 터로서 나타낼 수 있어, 컴퓨터상에서 단순한 배열 데이터로 처리할 수 있다. 또한, 여기서는 서로 직교하는 단위벡터 i , j , k 를 이용해 3D 직교좌표계를 표현했지만, 직교하지 않는 단위 벡터를 여러 개 이용하면 사교좌표계를 표현할 수 있다. 단, 서로 평행인 벡터로는 좌표계를 표현할 수 없다. 또한, 3D 공간을 표현하고 싶은데 세 개의 벡터가 모두 같은 평면에 있어도 좌표축으로 사용할 수 없다. 그 벡터들은 선형종속 (linearly

dependent )이라 불리며, 하나의 벡터를 다른 벡터의 합으로 표현할 수 있는 상태가 된다. 반 면에, 선형종속이 아닌 상태를 선형독립 (linearly independent )이라고 한다. 선형독립이고 좌표계 표현에 사용할 수 있는 벡터(앞의 예에서는 i , j , k )를 가리켜 기저벡터 (basis vector )라 하고 그 집합을 기저 (basis )라 부른다. 벡터가 만족하는 덧셈과 스칼라 곱( scalar multiplication )이 잘 정의된 벡터공간 ( vector

space )이라는 집합에서는, 좌표계를 나타내는 기저를 구성하는 기저벡터의 개수를 차원 (dimension )이라 부른다.

3.2.5 법선벡터 법선벡터 ( normal vector )는 2D인 경우에는 어떤 벡터에 수직인 벡터이고, 3D인 경우에는

어떤 평면에 수직인 벡터다. 법선 (normal )이라는 개념 자체는 벡터에 국한되지 않고 수직인 직선을 의미한다. 이 같은 법선벡터는 3D 컴퓨터 그래픽스에서는 매우 응용 범위가 넓으며, 다 양한 장면에서 등장한다. 단위벡터를 구하는 조작인 ‘정규화 ( normalize )’와 영어 표현이 비슷 ( normalized 와

normal )하므로, 단위벡터와 법선벡터를 혼동하기 쉽다. 또한 법선벡터 자체가 실제로 이용될 때는 이용하기 쉽게 정규화되는 경우가 일반적이지만, 법선벡터와 단위벡터는 별개의 독립된 개념이다. 한편, 벡터 v 를 그 시점이 속한 면에 수직인 벡터와 그 면상의 벡터로 분해했을 때, 수직인 벡 터를 가리켜 v 의 법선성분 (normal component )이라고 하고, 면상의 벡터를 v 의 접선성분 (tangential component )이라고 한다. 법선벡터는 평면을 정의하는 데도 사용할 수 있다. 점 P와, P를 시점으로 하는 법선벡터 N 이

CHAPTER 3 - 벡터

91


있을 때 P를 포함하는 평면의 표면이 어느 쪽을 향하는지 결정할 수 있다(그림 3-6 ).

그림 3-6 평면의 법선벡터

3.2.6 크기 단위벡터와 기저벡터에 의해 좌표축과 벡터가 연결되었으니, 벡터의 크기(magnitude )를 좌 표축 상에 표현 가능한 수치로써 표현하는 방법을 생각해보자. 벡터v 의 크기는 절댓값 기호와 같은 기호를 사용해 스칼라양과 마찬가지로 |v |로 표기하는 방식과, 벡터의 크기를 노름 (norm )이라 부르고 ‖v ‖로 표기하는 방식이 있다. 좌표축을 사용하면, 위치벡터의 좌표에 표시되는 각 성분의 수치를 피타고라스의 정리에 적용 해 벡터의 크기를 구할 수 있다(그림 3-7 ).

그림 3-7 벡터의 크기와 좌표축

위치벡터 (x , y )로 표현되는 2D 벡터 v 의 크기는 다음과 같이 구할 수 있다.

92 유니티로 배우는 게임 수학


‖v‖2 = x 2 + y 2

‖v‖ =

3D 벡터 v 역시 마찬가지로 다음과 같이 구한다

‖v‖ =

단, 이렇게 벡터의 크기를 구하려면 제곱근 연산이 필요한데 컴퓨터상의 제곱근 연산은 실행 비용이 많이 든다. 그러므로 두 개 벡터의 크기만 비교하고 싶을 때는 제곱근을 구할 것까지 없 이, 벡터의 크기를 제곱한 값끼리 비교하는 것으로 충분하다. 유니티는 이를 위해 Vector3 클 래스에 sqrMagnitude라는 벡터 크기의 제곱을 나타내는 프로퍼티를 준비했다.

3.2.7 내적 지금까지 다룬 벡터의 덧셈·뺄셈과 벡터와 스칼라의 곱은, 스칼라 연산과 마찬가지로 기하학 적으로 이해하기 쉬운 설명에 의해 직관적으로 연상할 수 있었다. 한편, 벡터에는 그런 기하학 적인 벡터 공간을 구성하는 연산뿐 아니라 다른 종류의 연산도 부가적으로 정의할 수 있다. 그중 하나가 내적 (dot product, inner product )으로, 내적은 두 개의 벡터를 하나의 스칼 라양으로 변환하는 연산이다. 벡터 a 와 벡터 b 의 내적은 수식상으로는 도트 연산자(·)를 이 용해 a ·b 로 표기한다. 내적이 추가된 벡터 공간은 내적공간 (inner product space )이라고 한다. 그럼, 이제부터 내적이라는 연산이 어떤 사양을 만족해야 벡터를 다루는 도구로서 바람직한지 몇 가지 항목을 예로 들어보자. 우선 다음 식처럼 벡터 자신의 내적은 해당 벡터 크기를 제곱 한 스칼라양과 같다고 가정한다.

a ∙ a = ‖a‖2

여기서 [그림 3-8]과 같은 삼각형의 내각 θ 를 이루는 두 변에 해당하는 벡터를 각각 a , b 라 하고, 나머지 한 변을 벡터 c 라고 하자.

CHAPTER 3 - 벡터

93


그림 3-8 벡터 a, b, c

그러면 다음과 같은 식이 성립한다. c = a-b

이 사실을 전제로 하고, 또한 내적이라는 연산에서 분배·교환법칙이 성립한다고 가정하여

c 와 c 의 내적의 식을 전개해보면 다음과 같다. c ∙ c = (a - b) ∙ (a - b)

= a ∙ (a - b) - b ∙ (a - b)

= a ∙ a - a ∙ b - b ∙ a + b ∙ b

= a ∙ a + b ∙ b - 2a ∙ b

= ‖a‖2 + ‖b‖2 - 2a ∙ b

또한, 맨 처음 설정했던 것처럼 c ∙ c = ‖c ‖2 이므로 다음 식이 성립한다. ‖c‖2 = ‖a‖2 + ‖b‖2 - 2a ∙ b

한편, 1장에서 학습한 코사인법칙을 이 삼각형에 적용해보자.

‖c‖2 = ‖a‖2 + ‖b‖2 - 2‖a‖‖b‖ cosθ

이들 두 식은 모두 ‖c ‖2를 표현하므로, 우변끼리 같아져 다음 식이 성립한다.

‖a‖2 + ‖b‖2 - 2a ∙ b = ‖a‖2 + ‖b‖2 - 2‖a‖‖b‖ cosθ

이 방정식을 풀면 최종적으로 다음 식을 얻을 수 있다. a ∙ b = ‖a‖‖b‖ cosθ

94 유니티로 배우는 게임 수학


θ 가 0일 때 cosθ = 1이므로, 벡터 자신과의 내적은 벡터 크기의 제곱과 같다(a ∙ a = ‖a ‖2 )고 처음에 설정한 성질도 이 식으로 표현할 수 있다. 또한, a 가 b 에 수직일 때 cosθ = 0이므로 a ∙

b = 0이다. 나아가, 2D에서 원점 O 를 기준으로 한 위치벡터로서 a 와 b 를 생각하고, a 의 성분 혹은 점

A의 좌표를 (a x , a y ), b 의 성분 혹은 점 B의 좌표를 (b x , b y )로 하여, 이들 좌표와 내적의 관 계를 구해보자. 조금 전 내적의 식을 도출하는 과정에서 나온 식으로 한 번 더 돌아가본다. ‖c‖2 = ‖a‖2 + ‖b‖2 - 2a ∙ b

여기서 피타고라스의 정리를 사용하면, c는 직각삼각형의 빗변에 해당하므로 다음 식이 성립한다. ‖c‖2 = (a x - b x )2 + (a y - b y )2

마찬가지로 다음 식이 성립한다.

‖a‖2 = a x 2 + a y 2

‖b‖2 = b x 2 + b y 2

따라서, 다음과 같이 만들어진다.

(a x - b x )2 + (a y - b y )2 = a x 2 + a y 2 + b x 2 + b y 2 - 2a ∙ b

이 식을 전개하면 다음과 같은 식을 얻을 수 있다.

a ∙ b = ax bx + ay by

한편, 3D 벡터라면 (a x , a y , a z )와 (b x , b y , b z )에 대해 똑같이 계산해서 다음처럼 내적의 성 분표시를 얻을 수 있다.

a ∙ b = ax bx + ay by + az bz

사인과 코사인으로 대표되는 초월함수 ( transcendental function )라 불리는 종류의 함수 는 일반적으로 컴퓨터상에서 처리비용이 비싸므로, 내적을 계산으로 구할 때는 가능한 한 이 성분표시를 사용해야 한다.

CHAPTER 3 - 벡터

95


내적에는 교환법칙과 분배법칙이 성립하고, 스칼라 상수를 곱할 수 있다. 벡터 a , b , c 와 스칼 라 상수 n 을 사용하면 다음 식이 성립한다.

a∙b = b∙a

(a + b) ∙ c = a ∙ c + b ∙ c

(na) ∙ b = a ∙ (nb) = n(a ∙ b)

결합법칙은 내적의 경우 결과가 스칼라다 보니 스칼라를 곱하는 게 되어버리므로 정의되지 않 는다.

3.2.8 벡터의 직교투영 내적에는 또 한 가지 사용법이 있다. 바로 벡터의 직교투영 (vector projection )을 구하는 것 이다. 직교투영이란 직관적으로 말하자면 빛이 닿았을 때 생기는 그림자 형태라고 생각하면 된다.

그림 3-9 벡터를 직교투영한 길이

[그림 3-9]처럼 벡터 a 의 종점에서 벡터 b 를 향해 수직으로 내린 선과 b 가 교차하는 점에서 부터 b 의 시점까지의 길이는 ‖a ‖ cosθ 다. 여기서 a ·b = ‖a ‖‖b ‖ cosθ 라는 사실을 떠올 리면, ‖b ‖ = 1, 다시 말해 b 가 단위벡터일 때 다음처럼 나타낼 수 있다. a ∙ b = ‖a‖cosθ

96 유니티로 배우는 게임 수학


a 에서 b 로 직교투영한 길이(스칼라양)는 a 와 단위벡터 b 와의 내적으로 구해진다는 사실을 알 수 있다. 또한, b 와 같은 방향에서 a 를 b 로 직교투영한 길이를 가지는 벡터 b’ 는 b 가 단위 벡터일 때 다음과 같다(그림 3-10 ). b’ = (a ∙ b)b

벡터를 스칼라 배하면 그만큼 늘어나는 것은 벡터의 스칼라 곱에서 살펴본대로다.

그림 3-10 직교투영된 벡터

이처럼 벡터는 단위벡터로 되어 있으면(정규화되어 있으면) 사용하기 편리하므로, 유니티 의 Vector3 클래스에도 그런 점이 고려되었다. normalized 프로퍼티에 더해, Vector3.

forward와 같은, z축 방향으로 (0, 0, 1 )만큼 전진하는(왼손 좌표계이므로 화면 안쪽을 향해 z 값이 증가하는 이미지) 벡터를 나타내는 프로퍼티도 마련되어 있다. 또한, 직교투영을 구하 는 메서드로서 Project 메서드를 제공한다.

3.2.9 내적의 응용 벡터 a 와 b 의 내적(a ·b = ‖a ‖ cosθ )은 a 와 b 가 이루는 각 θ 를 변화시킴으로써 바뀌는 cosθ 값에 따라 변한다. 이 점을 이용하여 단순한 방법으로 a 와 b 의 관계를 파악할 수 있다. [그림 3-11]의 왼쪽처럼 1장에서 학습한 코사인파를 떠올려보자. 라디안으로 말하자면 x 축 의 각도 θ 가 0에서 2π (360도)로 변화하는 동안 y 축의 cosθ 값은 1 → 0 → -1 → 0 → 1로 π

코사인파에 따라서 변화한다. 특히 2 의 경우 0이 되므로 이해하기 쉽다.

CHAPTER 3 - 벡터

97


그림 3-11 벡터 a, b가 이루는 각의 코사인

또한, 그림의 오른쪽은 벡터 a 와 벡터 b n 이 이루는 각도와, 해당 각도일 경우 cosθ 의 실제 값 을 나타낸다. 여기서는 a 와 b 의 내적은 a 와 b 가 이루는 각 θ 에 따라 다음과 같이 변화한다는 것을 알 수 있다. a 와 b 가 완전히 같은 방향을 향할 때(a 와 b 가 평행) : a ·b = ‖ a ‖‖ b ‖ (이때 cos0 = 1 )

θ 가 90도보다 작을 때 : a ·b < ‖ a ‖‖ b ‖

π

b 3 가 a 에 수직일 때 : a ·b = 0 (cos 2 = 0)

θ 가 90도와 180도 사이일 때 : a ∙ b < 0이고 |a ∙ b | < ‖a ‖‖b ‖

a 와 b 6 가 반대일 때 : a ∙ b = -‖a ‖‖b ‖ (cosπ = -1)

이처럼 내적 값의 부호와, a 와 b 길이의 곱과 a 와 b 의 내적을 비교함으로써 두 벡터의 위치 관 계를 조사할 수 있다.

3.2.10 외적 벡터에는 또 한 가지 다른 연산을 정의할 수 있는데, 이를 외적 (cross product )이라고 한다. 외적은 두 개의 벡터에서 한 개의 스칼라를 생성하는 내적과 달리, 두 개의 벡터에서 새로운 한 개의 벡터를 생성하는 연산이다. 외적과 내적의 또 다른 차이점은 벡터를 생성하는 것이 외적 연산이라고 정의했을 때, 2차원 벡터끼리의 외적이란 없고 3차원 이상의 벡터가 아니면 외적을 정의할 수 없다는 것이다(쐐기

98 유니티로 배우는 게임 수학


곱(wedge product )이라는 개념을 도입하면 2차원·3차원에 관계없이 더 일반적인 광의의 외적을 표현할 수 있으나 이 책에서는 다루지 않는다). 외적으로 생성되는 벡터는 두 개의 벡터 a , b 에 수직이고, a , b 로 이루어지는 평행사변형 (parallelogram )의 면적과 크기가 같은 벡터다(그림 3-12 ).

그림 3-12 왼손 좌표계에서의 외적

각도 θ 를 이루는 벡터 a 와 b 의 외적과 그 크기는 크로스 연산자( × )를 사용해 다음과 같이 정 의한다.

a × b = (‖a‖‖b‖sinθ)u

‖a × b‖ = ‖a‖‖b‖sinθ

u 는 a 와 b 에 수직인 단위벡터다. 밑변의 길이가 ‖b ‖이고 높이는 ‖a ‖sinθ 라고 생각하면, 평행사변형의 면적은 밑변의 길이에 높이를 곱해 구할 수 있으므로, 생성되는 벡터의 크기는 ‖a ‖‖b ‖sinθ 가 된다. a 와 b 가 평행이고 θ = 0, 다시 말해 sinθ = 0일 때 a × b 는 영벡터가 된다. 또한 a 또는 b 가 영벡터일 때도 a 또는 b 의 노름이 0이 되므로 a × b 는 영벡터다. 외적이 내적과 다른 중요한 점으로서 교환법칙이 성립하지 않는다는 성질이 있다. 그대신, 한 쪽 벡터의 방향을 역으로 하면 교환할 수 있다.

a×b≠b×a

a × b = -b × a

다시 말해, 외적에서는 곱하는 순서에 의미가 있다. 외적의 정의에 나왔던 단위벡터 u 가 그림 에서는 위를 향하지만, b × a 라는 연산을 하면 반대 방향이 된다는 뜻이다. [그림 3-12]처럼 a

CHAPTER 3 - 벡터

99


가 안쪽 방향으로 향하고 앞쪽에 b 가 있을 때가 아니면, 외적의 결과인 벡터는 그림과 같은 방 향이 되지 않는다. 사실, 외적이 생성하는 벡터의 방향은 좌표계에 의존한다. 그림에서 a × b 의 방향은 왼손 좌 표계에서의 외적의 결과로, 오른손 좌표계라면 반대 방향이다. 유니티에서는 Vector3 클래스 의 Cross 메서드로 외적을 산출할 수 있지만, 유니티의 외적은 왼손 좌표계이므로 결과 방향 은 그림과 같다.

2장에서 좌표계란 관측자가 시점을 어디에 두는가 하는 단순한 약속에 지나지 않는다 했다. 또 한 벡터란 좌표계에 의존하지 않는 양이었다. 여기서는 외적으로서 생성되는 벡터의 방향이 좌 표계를 어떻게 구성하는가에 따라 변화하므로, 마치 전제에 반하는 것처럼 보인다. 이처럼 어느 좌표계를 사용하는지에 따라 방향이 바뀌는 벡터를 유사벡터 ( pseudo vector ) 또는 축성벡터 (axial vector )라 부르며 일반 벡터와는 구별한다. 좌표계가 변해도 방향이 변 하지 않는 일반 벡터는 극성벡터 (polar vector )라 한다. 일반 벡터는 좌표계가 변화해도 방향이 바뀌지 않으므로 좌표계를 바꾸면 성분이 변화하지만, 유사벡터는 좌표계에 따라 방향이 바뀌므로 반대로 좌표계상의 성분은 변화하지 않는다. 외적 에 의해 생성되는 벡터는 유사벡터이므로, 좌표계를 변환할 때는 주의해야만 한다. 좌표계를 변환하지 않을 때는 극성벡터처럼 다룰 수 있다. 외적에는 교환법칙·결합법칙은 성립하지 않지만, 스칼라를 이용한 곱셈과 분배법칙은 성립 한다.

(na) × b = a × (nb) = n(a × b)

(a + b) × c = a × c + b × c

한편 벡터의 외적과 내적을 연관짓는 식은 벡터 삼중적 (vector triple product )이라고 한다.

a × (b × c) = (a ∙ c) b - (a ∙ b) c

(a × b) × c = (a ∙ c) b - (b ∙ c) a

벡터 삼중적 식에서 a , b , c 를 차례로 바꾼 것(a × (b × c ), b × (c × a ), c × (a × b ) )을 더하면 다음 식을 얻을 수 있다.

100 유니티로 배우는 게임 수학


a × (b × c) + b × (c × a) + c × (a × b) = 0

이 식은 야코비 항등식 (Jacobi identity )으로 불리며 3차원 벡터의 외적의 성질을 나타낸다. 내적의 경우와 마찬가지로 외적의 좌표계상에서의 성분 표시도 살펴보자. 벡터 a = ( a x , a y ,

a z )와 b = (b x , b y , b z )의 외적 c = (c x , c y , c z )는 다음처럼 나타낼 수 있다.

a × b = (c x , c y , c z ) = (a y b z - a z b y , a z b x - a x b z , a x b y - a y b x )

이 상태로는 이해하기 매우 어렵지만 인덱스에 해당하는 ‘c x = a y b z - a z b y ’ 부분을 ‘xyzzy ’ 로 기억하고, 세로열이 x → y → z → x → y → z …와 같이 반복된다고 가정해 xyzzy 아래 에 두 줄을 만들어준다.

xyzzy

yzxxz

zxyyx

이것은 c 의 y , z 성분의 인덱스와 일치하므로, (그다지 실용성은 없지만) 이렇게 해서 외적의 성분 표시를 기억할 수도 있다. 유니티에서는 앞에서 소개한 Vector3의 Cross 메서드를 사용하면 외적을 계산할 수 있으므 로, 실제 손으로 외적을 계산하는 상황은 드물 것이다.

3.2.11 외적의 응용 외적의 크기에 관해서는 다음 식이 성립한다.

‖a × b‖ = ‖a‖‖b‖sinθ

그러므로, 다음과 같은 내적의 정의를 떠올리면, 외적의 크기도 내적과 마찬가지로 θ 에 따라 (부호 포함) 변동하는 스칼라양이라는 것을 알 수 있다.

a ∙ b = ‖a‖‖b‖cosθ

이때 차이점은 외적의 크기가 (코사인파가 아닌) 사인파에 따라서 변화한다는 것이다. 다시 말해, 내적은 90도일 때 0이 되었지만, 외적의 크기는 0도와 180도일 때 0이 된다. 내적은

CHAPTER 3 - 벡터

101


벡터의 직교 판정에 사용할 수 있고, 외적의 크기는 평행 판정에 사용할 수 있다. 이 사실은 두 개의 벡터가 서로 평행일 때 두 개의 벡터로 이루어지는 평행사변형의 면적이 0이 된다는 점에서도 분명하다. 하지만, 외적에 관한 가장 직접적인 사용법은 평면의 법선벡터를 구하는 것이다. 세 개의 정점 으로 구성되는 삼각형의 두 변을 이루는 벡터의 외적을 구해 정규화해주면, 그 삼각형이 존재 하는 평면의 법선벡터를 얻을 수 있다(그림 3-13 ).

법선

그림 3-13 외적과 법선벡터

3.3 유니티 예제 : 간이 충돌 판정 3.3.1 동작과 사양 그럼 벡터를 사용한 유니티 예제를 만들어보자. 이번에는 벡터의 외적과 내적의 성질을 사용해 간이 충돌 판정 (collision detection )을 구현해보기로 한다. 유니티에서 Main.unity 씬을 열고, 유니티의 재생 버튼을 눌러 Game 뷰에 표시된 버튼 중 [Chapter3] 버튼을 누른다. 이번에는 Game 뷰가 아니라 Scene 뷰를 볼 것이므로 레이아웃이 2 by 3으로 되어 있지 않다면, 메뉴에서 Window → Layouts 또는 툴바의 레이아웃 선택 버튼(그림 3-14 )에서 2 by 3을 선택한다.

102 유니티로 배우는 게임 수학


그림 3-14 2 by 3 레이아웃

[Chapter3] 버튼을 누르면 Scene 뷰의 중심에 큐브가 표시된다. 여기까지는 2장의 예제와 같다.

그림 3-15 큐브와 카메라

CHAPTER 3 - 벡터

103


public static Vector4 operator * (Matrix4x4 lhs, Vector4 v) {

Vector4 result; result.x = lhs.m00 result.y = lhs.m10 result.z = lhs.m20 result.w = lhs.m30 return result;

* v.x + lhs.m01 * v.y + lhs.m02 * v.z + lhs.m03 * v.w; * v.x + lhs.m11 * v.y + lhs.m12 * v.z + lhs.m13 * v.w; * v.x + lhs.m21 * v.y + lhs.m22 * v.z + lhs.m23 * v.w; * v.x + lhs.m31 * v.y + lhs.m32 * v.z + lhs.m33 * v.w;

}

Matrix4x4의 각 행벡터와 Vector4와의 내적을, 결과인 Vector4의 각 성분에 저장한다. 인 수를 값으로 전달하고 반환값도 값으로 반환하므로 Matrix4x4의 복사는 자원을 많이 차지한 다. 많이 사용된다면 ref로 참조 전달하는 메서드를 만드는 편이 좋을 것이다. 한편으로, MultiplyVector 메서드는 인수를 Vector3로 보고, Matrix4x4도 3 × 3 행렬로 다루어 4행째 4열째를 무시하고 각각 곱해 Vector3 벡터를 구하는 메서드다. 그렇다면, Matrix4x4의 남은 두 개의 곱셈 메서드인 MultiplyPoint, MultiplyPoint3x4 는 도대체 무슨 일을 하는 것일까? 이 두 개의 메서드는 5장에서 다시 그 의미를 설명하기로 한다.

140 유니티로 배우는 게임 수학


CHAPTER

5

좌표 변환

5.1 좌표 변환이란 무엇인가 5.2 지오메트리 파이프라인 5.3 동차좌표계 5.4 변환 종류 5.5 좌표 변환의 행렬 표현 5.6 유니티 예제

CHAPTER 5 - 좌표 변환

141


이 장에서 배울 내용 게임 내에 표시되는 오브젝트의 구성 요소인 삼각형을 형성하는 정점은 좌표계라는 지도상에 존재 한다. 벡터도 마찬가지다. 좌표계상에 위치하는 좌표로서 표현할 수 있고, 삼각함수로 규정된 내적 과 외적 같은 벡터끼리의 관계 역시 좌표계상의 성분 계산으로 표현할 수 있었다. 그리고 4장에서는 행렬과 벡터의 곱셈으로 또 다른 벡터를 구할 수 있다는 것을 학습했다. 그 모든 것은 5장을 위한 준 비라고 해도 좋다. 이 장에서는 3D 게임에 쓰이는 복수의 좌표계/좌표공간을 소개하면서, 벡터와 정점을 나타내는 좌 표를 행렬 연산으로 다른 좌표계 사이에서 변환하거나, 좌표계 내에서 변용시키는 조작으로서 좌표 변환을 학습한다. 좌표 변환은 모든 3D 게임의 그래픽스 처리를 성립하게 하는 기본 원리다.

142 유니티로 배우는 게임 수학


5.1 좌표 변환이란 무엇인가 좌표 변환 ( coordinate transformation )이란 서로 다른 좌표계 사이에서 좌표를 변환하는 작

업의 총칭이다. 수학적으로는 행렬과 벡터를 곱해 그 결과로서 새로운 벡터로 변환하는 조작과 같다. 여기서 행렬이라는 도구는 입력되는 데이터 스트림을 변환하여 출력하는 이른바 ‘필터’ 로, 변환 자체를 나타내는 존재다. 이 문맥에서는 ‘행렬= 변환’이라고 잘라 말해도 좋다. 행렬이 자궁을 의미하는 matrix로 이름 붙여진 것은, 행렬식을 생성하는 모체로 여겨진 데서 유래한다. 다만 행렬은 행렬식 외에도 뭔가를 입력하면 변환해서 생성하는 능력도 가진다. 2장 에서 학습한 서로 다른 좌표계끼리는 좌표 변환이라는 연산을 거쳐 행렬을 이용해 서로 관련지 을 수 있다. 좌표 변환은 3D 컴퓨터 그래픽스의 기초가 되는 원리다. 2D 게임이라도 직교 좌표와는 다른 좌표계가 사용되거나, 일정한 법칙에 기초해 변형을 구현하거나 할 경우에는 좌표 변환으로 대 응한다. 좌표 변환의 응용범위는 매우 넓어 게임 영역을 뛰어넘기도 한다. 예를 들면 로봇을 제어할 때 도 로봇 자신과 로봇이 인식하는 외부, 가동축이 있는 로봇의 팔이나 로봇끼리 등등 서로 다른 좌표계를 가진 복수의 요소끼리 서로 관련지을 수 있다. 게임 세계에서 캐릭터를 3D 공간 내에 표시하고 애니메이션화할 때, 배후에서는 방대한 양의 좌표 변환이 이루어진다. GPU는 게임 씬 내의 오브젝트를 구성하는 대량의 정점 정보에 대해 동시병렬로 좌표 변환을 적용하기 위한 하드웨어로서 처음 도입되었다. 1장 도입부에서 폴리 곤으로서의 삼각형은 정점으로 구성된다고 이야기했다. 폴리곤의 형상을 나타내는 정점 데이 터를 가리켜 수학의 기하학에서 따온 단어인 지오메트리 (geometry )라 부른다. 입력의 출발점은 이미 2장에서 소개한 로컬 좌표계에서의 좌표다. 3D 모델링 툴로 만든 캐릭 터의 메시가 포함하는 정점 정보는 로컬 모델 공간에 존재하는 3D다. 최종적인 출력은 스크린 좌표계로, 여기서는 원래 3D였던 캐릭터가 화면상의 픽셀군으로 표현 되는 2D 평면상의 존재가 된다. 컴퓨터 메모리상에서 3D를 표현한 데이터 구조인 폴리곤 메 시로서 출발했지만, 현재 일반적으로 유통되는 출력 기기인 모니터의 사정으로 인해 마지막에 는 항상 2D 좌표로 변환된 이미지로 보여진다.

CHAPTER 5 - 좌표 변환

143


이 최초의 입력부터 마지막 출력까지의 공정이 어떤 규칙적인 대응관계로 이루어져야 화면상 에서 의미불명의 혼란이 일어나지 않는다. 현실의 실시간 비주얼 시뮬레이션으로서 도저히 성 립할 수 없고 게임으로서도 성립할 수 있을지 의문스럽다. 캐릭터의 폴리곤 메시 내의 손이나 발의 위치관계, 씬에서의 캐릭터끼리의 위치관계 등 그런 모든 관계가 인간이 인지하는 화면상에서 제작자의 원래 의도대로(혹은 물리법칙대로) 그럴 듯하게 유지되어야 비로소 제대로 된 게임으로서 인간이 받아들일 수 있기에 충분한 몰입감을 생성할 수 있음은 굳이 말로 설명할 필요도 없을 것이다. 이 일정한 규칙에 기초한 일련의 그리기 공정을 가리켜 그래픽스 렌더링 파이프라인(graphics

rendering pipeline )이라 한다. 파이프라인은 원래 유전에서 석유를 송출하는 관이지만, 컴 퓨터 세계에서는 복수의 처리 공정(스테이지)을 연결해 차례로 결과물을 처리하는 공정의 흐 름, 작업 라인을 가리킨다. 각 스테이지는 이전 스테이지에서 보내는 결과물을 받아들이지 않 는 한 작업할 수 없으므로, 그런 의미에서는 이전 스테이지에 의존적이라고 말할 수 있다. 하지 만 작업 자체는 서로 독립적이고, 다른 스테이지가 병렬로 동작함으로써 전체적으로 효율적으 로 처리해간다. 이 파이프라인 전반의 각 스테이지에서 파이프라인 위를 흘러가는 것은 정점 데이터로, 지오메 트리 연산으로서 좌표 변환이 세 번 이루어진다. 그래픽스 파이프라인 전체는 나중에 8장에서 설명하기로 하고, 우선은 지오메트리 연산이 이 루어지는 각 스테이지로서 다음 각각의 동작을 파이프라인상의 처리 순서대로 확인하겠다. 1 모델 변환 2 뷰 변환 3 프로젝션 변환

이를 통해 좌표 변환이 활용되는 경우를 학습하고, 3D 게임의 가장 기초적인 그래픽스 처리인 정점 변환을 이해하자.

144 유니티로 배우는 게임 수학


5.2 지오메트리 파이프라인 5.2.1 모델 변환 앞서 2장에서 소개한 3D 모델의 폴리곤 메시가 가진 모델 공간의 로컬 좌표계상의 좌표로부터 월드 좌표계상의 좌표로 변환하는 것이 모델 변환 (model transform )이다(그림 5-1 ). 월드 좌표로 변환하므로 월드 변환 (world transform )이라고도 한다. 로컬 좌표 벡터에 모델 변환 행렬을 곱하면 월드 좌표상의 좌표를 얻을 수 있다. 각 오브젝트 고유의 상대적 좌표에 지나지 않던 로컬 좌표가, 절대적 기준으로서의 월드 좌표계 내의 대응 위치에 존재하는 것으로 재인식되는 것이다.

로컬 좌표계

로컬 좌표계

로컬 좌표계 월드 좌표계

그림 5-1 로컬 좌표계와 월드 좌표계

모델 각각의 로컬 좌표계는 원점의 위치가 월드 좌표계의 원점과 다를 수 있다. 또한 로컬 좌표 계의 좌표축이 월드 좌표계의 좌표축과 다른 방향을 향할 수도 있고, 로컬 좌표계의 길이 단위 가 월드 좌표계의 길이 단위와 다를 수도 있다. 이러한 로컬 좌표계와 월드 좌표계의 차이를 해소할만큼의 변위를 좌표에 적용해주는 것이 모 델 변환이다. 모델 변환은 다음과 같은 세 가지 변환 요소로 구성된다. 평행이동(translation )

회전(rotation )

스케일(scale )

이들 변환을 조합하면 로컬 좌표계의 좌표축을 월드 좌표계의 좌표축과 완전히 똑같은 위치· 방향·크기로 배열할 수 있어, 앞에서 말한 좌표계의 불일치가 사라진다. 실제로는 로컬 좌표 계상의 좌표를 변환해서 월드 좌표계상의 좌표로 만들었으므로 좌표계가 움직이는 것은 아니

CHAPTER 5 - 좌표 변환

145


지만, 좌표계 쪽을 움직인다고 생각하면 이해하기 쉽다. 사실 유니티를 이용하면, 이들 변환은 처음부터 친숙할 것이다. 모든 씬의 오브젝트에 있는

Transform 클래스의 프로퍼티는 각 모델에 적용된 모델 변환을 나타낸다. [그림 5-2]를 보자. Transform에 표시된 Position, Rotation, Scale 값은 모두 로컬좌표 계로서 부모 Transform과의 상대적인 위치와 회전, 스케일을 나타낸다. 이처럼 인스펙터에 표시되는 값들은 스크립트에서 Transform 클래스의 localPosition, localRotation,

localScale 프로퍼티로 각각 접근할 수 있다. 이들의 월드 좌표계는 position, rotation, lossyScale 프로퍼티로 접근할 수 있으며, 이중 lossyScale는 읽기 전용 프로퍼티다. 또한, 최종적인 모델 변환 행렬 자체도 Transform.localToWorldMatrix로 가져올 수 있 다. 유니티 4까지는 유니티 쪽에서 GPU에 넘겨주기 전에 스케일을 가공했기 때문에 GPU 쪽 에 넘어가는 모델 변환 행렬과 Transform.localToWorldMatrix로 가져올 수 있는 행렬이 달랐다. 따라서 GPU 쪽에 넘겨지는 모델 변환 행렬은 Renderer.localToWorldMatrix를 이용하여 가져와야 했지만, 유니티 5부터는 기본적으로 필요 없어졌다.

그림 5-2 Transform

5.2.2 뷰 변환 모델 변환이 끝나고 월드 좌표로 변환된 후에 뷰 변환 (View transform )이 이루어진다. 월드 좌표계로 규정되는 월드 공간에서는 게임 씬 안에 자의적으로 놓인 부동의 원점 주위에 좌표계 를 두었지만, 게임의 3D 공간을 사용자가 실제로 표시할 때는 시점이 동적으로 변할 수 있다. 어떤 시각에 특정 시점, 요컨대 카메라로 본 세계를 표시하는 것을 고려하면, 월드 공간 좌표에 서 카메라를 중심으로 한 카메라 공간 (camera space ) 좌표로 변환해주어야 한다. 카메라 공 간을 가리켜 뷰 공간 (view space )이라고도 하며, 이 변환을 뷰 변환이라고 부른다.

146 유니티로 배우는 게임 수학


유니티에서는 카메라를 나타내는 Camera 클래스 자체도 월드 공간으로서의 씬 내에 존재하는 한 게임오브젝트에 추가되고 월드 공간에서의 Transform 프로퍼티를 가진다. 모델 변환에서 는 모델 좌표계로부터 월드 좌표계로의 좌표 변환으로서, 어떤 모델의 Transform에 해당하는 변환의 역변환을 적용하고, 이번에는 월드 공간 내 모든 모델의 좌표를 카메라의 모델 좌표계 에서의 좌표로 변환해주게 된다. 뷰 좌표계의 원점은 카메라 자체의 위치에 존재한다. 또한 좌표축의 방향은 카메라가 대상물 쪽으로 향하는 시선 벡터와 카메라 자체의 위쪽이 향하는 벡터에 따른 카메라의 회전 상태로 결정된다. 결국 월드 좌표계로부터 뷰 좌표계로의 차이를 좌표 변환으로 표현하려면 원점을 옮 기는 평행이동과 카메라의 방향을 설정하는 회전을 적용해주면 된다(그림 5-3 ). 유니티의 경우 뷰 좌표계는 OpenGL의 관례에 따라 오른손 좌표계(화면 안쪽이 마이너스인

z 축)인데, 이는 유니티에서 일반적으로 사용하는 왼손 좌표계와는 다르다. 유니티에서 카메라 가 사용하는 뷰 변환 행렬은 Camera 클래스의 worldToCameraMatrix로 가져올 수 있다.

뷰 좌표계

월드 좌표계

모델 좌표계

그림 5-3 뷰 변환

5.2.3 프로젝션 변환 뷰 변환으로 뷰 좌표계로 변환된 지오메트리는 이번에는 프로젝션 변환 ( projection

transform )에 의해 클립 공간 (clip space )으로 바뀐다. 프로젝션이란 투영을 말하며 투영 변 환이라고도 한다. 클립이라는 이름대로, 클립 공간은 뷰 좌표계 중 일부를 클립하는(잘라내서

불필요한 부분을 제거하는) 역할을 한다. 이때 잘라버리는 부분은 카메라에서 보이지 않는 부 분이다.

CHAPTER 5 - 좌표 변환

147


뷰 공간 상태라면 월드 공간에서 시점만 변환한 것이므로, 그 상태로는 카메라 뒤쪽과 카메라 에서 너무 멀어서 비치지 않는 부분, 그리고 반대로 지나치게 가까운 부분의 오브젝트가 공간 에 포함된다. 여기서 카메라에서는 보이지 않는 부분을 삭제한 육면체 영역을 뷰 프러스텀 (시 야 절두체, view frustum )이라 한다. 이때 뷰 프러스텀은 시야를 나타낸다. 시야 바깥쪽의 정점 정보를 버리고, 뷰 프러스텀을 정규 뷰 볼륨 (canonical view volume ) 이라 하는, 각 정점 좌표가 정규화된 정육면체로 변환하는 것이 바로 프로젝션 변환이다(그림

5-4 ).

원평면

원평면 근평면

근평면

그림 5-4 프로젝션 변환(원근투영)의 뷰 프러스텀과 정규 뷰 볼륨

뷰 프러스텀 중 카메라에 가까운 쪽 평면을 근평면 (near clipping plane ), 먼 쪽 평면을 원평 면 ( far clipping plane )이라 한다. 카메라의 화각/시야각( field of view, FOV )이 크면 클

수록 근평면과 원평면의 크기 비율 측면에서는 원평면 쪽이 더 커진다. 다만 뷰 프러스텀에서 정규 뷰 볼륨으로 변환할 때는 근평면보다 커야 할 원평면이 결과적으로 같은 크기가 되므로, 뷰 프러스텀을 무리하게 정육면체 모양으로 찌부러뜨린다고 생각하면, 정 규 뷰 볼륨에서는 원평면에 가까워지면 가까워질수록 오브젝트의 응축도가 높아진다. 반대로 근평면에 가까워질수록 비율적으로는 커진다. 요컨대, 정규 뷰 볼륨 안에서는 멀리 있는 것일 수록 작게 보이는, 일반적인 3D다운 원근법 효과가 시뮬레이트된다. 이런 프로젝션 변환 방법 을 원근투영 (perspective projection )이라고 한다.

148 유니티로 배우는 게임 수학


유니티의 Camera 클래스는 이러한 프로젝션 변환의 뷰 프러스텀을 어떤 형태로 할지 설정 하는 매개변수를 가진다(그림 5-5 ). Camera의 Projection을 Perspective로 한 경우, Field of View는 수직 방향 화각, Clipping Planes는 근평면과 원평면 각각의 시점으로부 터의 거리를 나타낸다. aspect 프로퍼티에는 뷰 프러스텀의 종횡비(아스펙트비)가 설정되는 데, 기본으로 스크린의 종횡비가 설정되어 있어 수평 방향 화각은 이 프로퍼티에 의존한다.

그림 5-5 Camera의 프로퍼티

뷰 프러스텀 바깥쪽의 오브젝트를 그릴 대상에서 제거하여(즉, 그리지 않고) 부하를 줄이 는 프러스텀 컬링 (절두체 컬링, frustum culling )은, 유니티의 경우 프로젝션 변환 시 원평 면을 기준의 하나로 삼아 실행된다. 또한, 스크립트에서 이용할 수 있는 Camera 클래스의

layerCullDistances에 원평면의 거리와 다른 값을 제거 대상의 거리로 삼는 레이어를 설 정해두면, 원래 작아서 눈에 띄지 않는 오브젝트에 해당 레이어를 설정하여 손쉽게 제거하는 식으로 최적화할 수 있다. 유니티는 프러스텀 컬링 외에 오클루전 컬링 (Occlusion Culling )이라는 더 고급 컬링 기법도 제공한다. 이 기법 역시 Camera 클래스에서 활성화/비활성화를 설정할 수 있다. 프러스텀 컬 링은 시야 밖의 오브젝트를 생략하지만, 화면 내 오브젝트의 불필요한 겹쳐그리기(오버드로,

overdraw )를 막을 수 없다. 오클루전 컬링을 활성화하면, 카메라에서 보이지 않는 오버드로 된 부분의 그리기처리를 생략할 수 있다(그림 5-6 ).

CHAPTER 5 - 좌표 변환

149


그림 5-6 Overdraw

Scene 뷰의 컨트롤 바의 그리기모드 버튼은 보통 Shaded 셰이딩 모드가 선택되어 있지만, 클릭해서 Overdraw를 선택하면 오버드로 모드가 된다. 카메라에서 봤을 때 오브젝트가 겹쳐 서 오버드로가 발생한 부분이 더 밝게 표시되므로 문제 위치를 특정하기 쉬워진다(그림 5-7 ).

그림 5-7 Overdraw 모드로 확인

또한, 1장 예제에서도 봤듯이 Camera 컴포넌트의 Projection에는 Perspective 이외에 Orthographic도 지정할 수 있다. Orthographic으로 했을 때 활성화되는 것은 직교투영 (orthographic projection )에 의한 프로젝션 변환이다(그림 5-8 ).

150 유니티로 배우는 게임 수학


원평면 근평면

그림 5-8 직교투영 변환

직교투영의 뷰 프러스텀은 직육면체 모양으로, 근평면과 원평면의 크기에 차이가 없다. 요컨대 원근투영의 경우와 달리 변환해도 원근법 효과는 나타나지 않는다. 또한, 시야각이라는 개념도 없다. 유니티에서는 Orthographic을 선택하면 fieldOfView 프로퍼티가 무시되고, 대신에

orthographicSize 프로퍼티로서 직육면체의 수직방향으로 세로 절반의 크기를 지정할 수 있다. 유니티 4.3부터 도입된 2D 모드에서는 씬의 내용은 기존처럼 3D임에도, 이 Orthographic 모드 카메라를 채용함으로써 언뜻 2D처럼 보인다. 원근투영이 르네상스 이후 서양화의 시점 표현이라고 한다면, 직교투영과 사투영 (oblique projection ) 같은 투영 변환은 헤이안 시대 (平安시대 : 794년~1185년) 이후의 일본화의 세계다(그림 5-9 ).

그림 5-9 원근투영 게임과 직교투영 게임1

1 저자주_ 왼쪽은 ‘뫼비우스 파이널판타지’의 스크린샷 © 2015 SQUARE ENIX CO., LTD. All Rights Reserved. 오른쪽은 ‘크로시 로드(Crossy Road)’의 스크린샷. Hipster Whale © 2014-2015

CHAPTER 5 - 좌표 변환

151


유니티에서는 Camera 컴포넌트의 Projection을 Perspective로 할지 Orthographic으 로 할지에 따라 Scene 뷰에서의 카메라의 시계를 나타내는 와이어프레임 형상이 뷰 프러스텀 또는 직육면체로 변한다. 따라서 어느 시계로 되어 있는지 알기 쉽다(그림 5-10 ).

그림 5-10 Perspective(좌)와 Orthographic(우)

5.3 동차좌표계 5.3.1 동차좌표계란 무엇인가 3D 지오메트리가 프로젝션 변환의 결과 정규 뷰 볼륨 상태까지 이르게 되면, 2D로의 변환은 쉽다. 정규 뷰 볼륨에 대해 뷰포트 변환 (viewport transform )이 이루어지고, 2D의 윈도우 좌 표계 ( window coordinate system ) 또는 스크린 좌표계로 변환한다. 이는 단순히 z 값을 빼

고 x, y 값만 남긴 후 스크린 크기에 맞게 스케일을 변환하는 것이다. 떨어져 나간 z 값의 저장 소는 Z 버퍼 (Z-buffer, depth buffer )라는 곳으로, 뷰 공간에서 오브젝트의 전후 관계를 판 정하는 심도 테스트 (depth test )에 쓰인다. 앞에서는 설명을 생략했지만, 클립 공간의 클립 좌표계에서 정규 뷰 볼륨이 생기기 전에, 정규 뷰 볼륨의 좌표계인 정규화 디바이스 좌표계 (normalized device coordinates, NDC )로 변 환하는 단계가 끼어있다. 이 변환을 원근분할 (perspective division )이라고 한다. 클립 좌표계의 좌표는 x , y , z 외에도 w 라는 네 번째 성분을 가지며, 이 w 값은 카메라에서 멀 어질수록 커진다(뷰 좌표계는 오른손 좌표계이고 클립 좌표계가 왼손 좌표계이므로, 뷰 좌표

152 유니티로 배우는 게임 수학


계의 z 값 부호를 반전시킨 것이 된다). 원근분할이란 x , y , z , w 를 w 로 나누는 조작이다. 나 눈 후에 w 는 항상 1이 되지만, w 가 크면 x , y , z 가 작고, 반대로 w 가 작으면 x , y , z 가 커진다. 결국, w 성분은 정규 뷰 볼륨에서의 원근법의 시뮬레이션을 위한 계수로서 기능한다. 이처럼 실제로는 클립 좌표계는 (x , y , z , w )라는 4차원 좌표로 표현되는 좌표계다. 이러한 좌표계를 동차좌표계 ( homogeneous coordinates )라 한다. 클립 좌표계를 원근분할하여,

w 성분이 1이 되어 무시할 수 있게 된 시점에서 겨우 4차원이 아닌 3차원 좌표로서 정규화 디 바이스 좌표계를 얻을 수 있다는 것이다.

5.3.2 동차좌표계와 사영기하학 일반적인 직교좌표계를 유클리드 기하학에서 사용한다면, 동차좌표계는 사영기하학 (projective geometry ) 분야에서 사용하는 좌표계로 19세기에 뫼비우스가 발견했다. 사영 기하학은 비유클리드 기하학의 일종인데, 예를 들어 사영기하학에서는 유클리드 기하학과 달 리 평행선은 무한원점 (point at infinity )에서 교차한다고 생각한다. 투영 공간은 유클리드 공 간에 무한원점 집합을 추가한 공간이다. 동차좌표계의 좌표에서는 각 성분끼리의 비율만 의미가 있다. 요컨대 n 이 0이 아닌 정수일 때 (x , y , z , w )와 (nx , ny , nz , nw )는 동차좌표로서는 같다. 또한, 직교좌표를 동차좌표로 나타낼 수도 있는데, 한 개의 직교좌표 (1, 2, 3 )을 동차좌표 (x , y , z , w )로 나타내면 (1, 2,

3, 1 )이나 (2, 4, 6, 2 ) 등 무한히 많은 동차좌표를 생각할 수 있다. 동차좌표 (x , y , z , w )로 부터 대응하는 직교좌표를 산출해내려면 w 로 다른 성분을 나누어주면 된다. 단, w 가 0일 때 나눈 결과는 무한이다. 따라서, 나누기를 하지 않는 한은 (x , y , z , 0 )으로, 직교좌표로는 표현 할 수 없는 무한원점을 동차좌표로 표현할 수 있다. 또한, 무한원점은 직사광 (directional light )으로서도 이용된다. 동차좌표로 나타냈을 때 일반 적인 점광원 (point light )은 (x , y , z , 1 )에 위치하지만, 직사광은 무한원점인 (x , y , z , 0 ) 에서 씬에 내리쬐는 빛으로 생각하므로, 광원의 좌표의 네 번째 성분이 0인지 아닌지 조사하면 직사광인지 점광원인지를 알 수 있다. 직사광과 점광원은 9장에서 다시 설명한다. 클립 좌표계는 동차좌표계의 4차원 벡터로서 표현되므로, 이를 좌표 변환으로 생성하기 위한 행렬은 4 × 4 행렬이어야 한다. 따라서, 변환할 좌표는 처음부터 동차좌표계의 4차원 벡터로 표현해두는 게 좋다. 실제 게임 개발에서는 사영기하학이라는 배경 지식에 관한 이해가 요구되

CHAPTER 5 - 좌표 변환

153


지 않고, 단순히 4차원 벡터가 3차원 벡터 계산에 편리하므로 이용하는 측면도 있다.

5.3.3 유니티의 동차좌표계 유니티는 어떻게 동차좌표계에 대응할까? 여기서 다시 4 장 예제코드 설명에서 다룬

Matrix4x4 클래스로 되돌아가, MonoDevelop의 Assembly Browser로 Matrix4x4 의 MultiplyPoint 메서드의 구현을 살펴보자. 앞에서 살펴본 것처럼 4 장 예제코드 내 에서 컨텍스트 메뉴의 Go to declaration 으로 Assembly Browser 를 열어도 되고,

MonoDevelop으로 프로젝트를 연 상태에서 View 메뉴에서 Assembly Browser를 선택 한 후 UnityEngine 어셈블리의 UnityEngine 네임스페이스를 열어 Matrix4x4의 정의 안 에서 MultiplyPoint를 찾아도 좋다. public Vector3 MultiplyPoint (Vector3 v) {

Vector3 result; result.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z + this.m03; result.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z + this.m13; result.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z + this.m23; float num = this.m30 * v.x + this.m31 * v.y + this.m32 * v.z + this.m33; num = 1 / num; result.x *= num; result.y *= num; result.z *= num; return result; }

이 메서드는 인수가 Vector3이지만, 실제로는 x , y , z 성분은 원래 v와 같고, 4번째 성분(v 가 Vector4라면 v.w )을 1로 간주한 4차원 벡터와 Matrix4x4를 곱한다. 애초에 행렬의 행 수와 벡터의 열수가 일치하지 않으면 곱할 수 없으므로 이런 조치가 필요하다. 이 곱셈의 결과 가 되는 4차원 벡터의 4번째 성분이 num이 되고, x , y , z 성분을 num으로 나눈 값을 최종적 인 결과로서 Vector3의 x , y , z 성분으로 저장하고 num 자체는 버린다. num은 동차좌표의

w 성분이다. num으로 나누므로, Matrix4x4의 4행이 모두 0이라면 0으로 나누게 되므로 이 메서드는 사용할 수 없다.

MultiplyPoint 메서드는 레퍼런스에 따르면 MultiplyPoint3x4보다 느리지만, Multiply-

154 유니티로 배우는 게임 수학


Point3x4와 달리 프로젝션 변환도 할 수 있다고 기술되어 있다. 앞에서 본 것처럼, 프로젝션 변 환을 하려면 동차좌표의 w 성분이 1이 아닌 경우에 대응할 수 있어야 한다. MultiplyPoint3x4 의 구현은 다음과 같다. public Vector3 MultiplyPoint3x4 (Vector3 v) {

Vector3 result; result.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z + this.m03; result.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z + this.m13; result.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z + this.m23; return result; }

MultiplyPoint3x4는 행렬 연산을 3행분만 하고 w 성분을 1이라고 처음부터 정하여 연산하 므로 내부에서 나눗셈을 하지 않아 빠르지만, 클립 좌표를 생성하는 프로젝션 변환에는 이용할 수 없는 종류의 곱셈이다.

5.4 변환 종류 5.4.1 선형 변환 지오메트리 파이프라인의 각 단계에서 좌표 변환이 이루어진다는 것을 알았다. 지금부터는 좌 표 변환에서의 변환이라는 조작에 도대체 어떤 수학 성질이 있는지를 주목하고, 지오메트리 파 이프라인에서 일어나는 좌표 변환이 따르는 규칙을 학습한다. 우선 살펴볼 것은 선형 변환 (linear transformation )이다. 두 개의 집합 V와 W가 있을 때, V 의 임의의 요소 v 에 W의 요소 w 를 단 하나 대응시키는 규칙적인 대응관계 f 가 있으면, f 를 V 에서 W로의 사상 (map )이라고 하고 다음처럼 나타낸다.

f:V→W

사상 중에서도 다음처럼 자기 자신에게 사상하는 것은 변환 (transformation )이라고 한다.

f:V→V

CHAPTER 5 - 좌표 변환

155


변환 f 가 선형 변환이려면, 임의의 벡터 u , v 와 스칼라 n 에 관해 다음과 같은 성질을 만족해야 만 한다.

f (u + v) = f (u) + f (v)

f (nv) = nf (v)

또한, 영벡터 0에 대해서는 다음처럼 f (0 ) = 0이다. f (0) = f (0 + 0) = f (0) + f (0)

여기서 다음과 같은 선형 변환의 특징을 알 수 있다. 직선은 변환해도 직선이다.

복수 정점간의 상대적인 거리의 비율은 변화하지 않는다.

서로 평행인 직선은 변환해도 평행이다.

영벡터는 변환해도 영벡터다.

벡터와 정방행렬의 곱은 4장에서 살펴봤듯이 다음처럼 나타낼 수 있다. (u + v)M = uM + vM

따라서 이 식은 다음과 같다.

f (u + v) = f (u) + f (v)

또한, ( nv ) M = n ( vM )은 곧 f   (nv ) = nf   (v )와 같으므로, 벡터와 정방행렬의 곱은 선형 변환이라고 할 수 있다. 또한, 선형 변환의 행렬 M은 가역행렬로, 서로의 곱은 단위행렬 I 가 된다. M M -1 = M -1 M = I

여기서, 모델 변환을 할 때 구성 요소로서 나타낸 변환이 선형 변환에 들어맞는지 살펴보자. 평행이동

회전

스케일

156 유니티로 배우는 게임 수학


평행이동은 좌표축을 따라 x 방향으로 얼마, y 방향으로 얼마, z 방향으로 얼마를 이동시키는 변환이다. 회전은 회전축을 정하고, 축의 주변을 특정 각도로 도는 변환이다. 스케일은 어떤 스 칼라를 곱하여 성분을 스칼라배 하는 변환이다. 그 어떤 변환에서도, 직관적으로는 직선을 구부리거나 원래 평행이던 선이 교차하거나 점과 점 사이의 비율이 바뀌는 변화는 일어나지 않을 것으로 보이며 실제로도 그렇다. 단 하나 문제가 있다. 평행이동에서 위치 벡터로서의 영벡터를 평행이동할 경우, 당연히 원점 에서 그만큼 어긋나므로 좌표계에서 본 위치 벡터로서는 영벡터가 아니게 된다. 따라서, 평행 이동은 선형 변환이 아니다.

5.4.2 아핀 변환 선형 변환만으로는 평행이동을 표현할 수 없으므로, 평행이동도 함께 표현하기 위해 아핀 변환 (affine transformation )이라는 개념을 도입했다. 아핀 변환 a 는 선형 변환 f 와 벡터 u , v 를 이용해 다음과 같이 나타낸다. a(v) = f (v) + u

벡터 u 가 있으므로 영벡터의 평행이동 결과가 반드시 영벡터여야만 할 필연성은 없다. 그 밖 의 선형 변환의 특징은 모두 아핀 변환에 합성되어 포함된다. 따라서 모델 변환에 필요한 다음

3가지 변환은 아핀 변환으로 다 표현할 수 있다. 평행이동

회전

스케일

또한, 게임에서는 그다지 등장하지 않지만, 직사각형을 평행사변형으로 하는 전단 (shear )이 라는 변환도 아핀 변환에 속한다.

3장에서 원점과 위치 벡터가 없는, 변위로서의 기하 벡터만 존재하는 공간으로서 아핀 공간을 소개했다. 아핀 변환은 아핀 공간 내에서의 요소로 맵핑된다.

CHAPTER 5 - 좌표 변환

157


5.4.3 리지드바디 변환 아핀 변환에서 스케일을 제외한 변환(요컨대 회전과 평행이동)은 유클리드 변환 (Euclidean

transformation ), 등거리 변환 ( isometry transformation ), 또는 리지드바디 변환 ( rigid transformation )이라고 한다. 리지드바디 변환은 변환 후에도 두 개 점의 거리가 변하지 않는 것이 특징이다. 리지드바디 변환에 관해서는 6장에서도 다룬다.

5.4.4 투영 변환 모델 변환과, 모델 변환의 역변환으로서의 뷰 변환은 아핀 변환으로 표현할 수 있다는 것을 알 았다. 그럼, 프로젝션 변환은 어떨까? 원근투영 변환을 생각해보자. 원근투영 변환에서는 가까이 있는 것은 크게 보이고 멀리 있는 것은 작게 보이므로, 본래 평행인 도로의 폭이 멀어질수록 좁아지는 것처럼 변환된다. 다시 말 해, 평행인 직선이 변환 후에는 평행이 아니다. 따라서, 원근투영 변환은 아핀 변환의 요건을 만족하지 못하므로 아핀 변환이 아니다. 원근투영 변환은 투영 변환 (projective transformation, homography )이라는 변환에 속한 다. 투영 변환은 아핀 공간을 포함하는, 더 넓은 공간인 투영 공간 내의 변환으로, 이미 설명한 것처럼 동차좌표계를 도입하여 표현할 수 있다. 또한, 아핀 변환은 투영 변환의 일부다. 투영 변환은 기하학적으로는 동일 선상의 네 개의 점 A, B, C, D 간의 선분으로, 다음과 같이 표현되는 복비(unhamonic ratio ) 또는 교차비(cross ratio )라는 비율이, 변환 후에도 변화 하지 않는 변환으로 정의된다. AC ∙ BD BC ∙ AD 대체로 (아핀 변환에서는 저장되었던) 선분의 비율과 각도가 보존되지 않는, 아핀 변환보다 더욱 조건이 완화된 변환이 바로 투영 변환이라고 알아두면 좋다.

158 유니티로 배우는 게임 수학


5.5 좌표 변환의 행렬 표현 5.5.1 평행이동 지금까지 좌표 변환이 수학적으로 어떠한 성질의 것인지 살펴보았다. 이제부터는 좌표 변환을 나타내는 실제 행렬이 어떤 것인지 내용을 확인해보자. 우선은 평행이동이다. 이미 살펴본 것처럼 평행이동은 좌표축 방향으로 이동하는 조합이다. vx

v =

vy vz 1

이 4차원 동차 좌표 벡터 v 에 대해, 행렬 T 의 덧셈이 아닌 곱셈으로 평행이동 좌표 변환을 표 현하고자 한다. 행렬의 덧셈이라면 4 × 1 행렬을 더해야만 하지만, 곱셈이라면 다른 곱셈으로 표현할 수 있는 변환과 조합해 다룰 수 있다는 장점이 있기 때문이다. 요컨대, v 의 각 성분 v x , v y , v z 에 벡터 (t x , t y , t z )의 각 성분을 더한, 다음과 같은 4 × 4 행렬 T 를 원하는 것이다. v x + t x v y + t y v z + t z

= Tv

1

우선, 결과벡터의 x 성분 v x + t x 를 어떻게 만들면 좋을지 생각해보자. 결과벡터의 x 성분은 T 의 1행째와 v 의 내적이므로, 1을 1행 1열 위치에 넣으면 적어도 v x 를 넣을 수는 있다. vx 0 0 0

=

vx

1

0

0

0

0

0

0

0

0

0

0 v y 0 vz

0

0

0

0

1

CHAPTER 5 - 좌표 변환

159


모든 대각 위치에 1 을 넣어 단위행렬로 하면, 마찬가지로 y 성분, z 성분에 v y , v z 를 넣고, 동 차 좌표의 w 성분의 위치에 1을 넣을 수 있다. v x 1

0

0

0 v x

vy

0

1

0

0

vy

vz

0

0

1

0

vz

1

0

0

0

1

1

이제부터 (t x , t y , t z )를 결과벡터에 더해가려면 어떻게 하면 좋을까? v 의 w 성분인 1을 사용 하면 된다. v x + t x 1

0

0

t x v x

v y + t y 0

1

0

ty

vy

v z + t z 0

0

1

tz

vz

0

0

1

1

1

0

따라서, 평행이동의 좌표 변환을 나타내는 행렬 T 는 다음과 같다.

T=

1

0

0

tx

0

1

0

ty

0

0

1

tz

0

0

0

1

이처럼 v 의 w 성분과 T 의 4열을 사용하지 않으면 평행이동을 표현할 수 없기 때문에, 평행이 동에는 3 × 3 행렬로는 부족하고, 동차좌표를 이용해서 벡터를 4차원으로 확장한 후에 4 × 4 행렬과 곱한다. 단, 곱할 때 실제로 의미있는 계산이 이루어지는 것은 T 의 1행부터 3행까지(4 행은 단순히 w 성분을 보존하며 결과에 영향을 주지 않는다)이므로, 평행이동에서 실제 계산 에 필요한 것은 3 × 4 행렬만큼이다. 앞서 소개한 유니티의 Matrix4x4.MultiplyPoint3x4는 그 점을 이용해서 연산을 일부 생략하여 고속으로 좌표를 변환하기 위한 메서드다. 유니티에서는 좌표 변환을 계산할 것까지도 없이, Transform의 Translate 메서드를 사용하 면 오브젝트를 평행이동시킬 수 있다.

160 유니티로 배우는 게임 수학


5.5.2 회전 다음은 회전 변환을 살펴보자. 회전은 다음과 같은 2가지 변수로 규정되는 변환이다. 어느 축을 회전할 것인가

회전 각도는 어느 정도인가

우선은 z 축을 회전하는 것으로 하고, 회전 각도에 따라 변환 전과 변환 후의 벡터가 어떻게 되 어야 하는지 생각해보자(그림 5-11 ).

그림 5-11 z 축을 회전

원점에서의 거리가 r 인 점 P를 z 축 둘레로 θ 만큼 회전시켜 점 P’의 위치로 움직이는 조작 을 생각해보자. 이때 P의 좌표는 (r cos (α ), r sin (α ), 0 )이다. 마찬가지로 점 P’의 좌표는 (r cos (α + θ ), r sin (α + θ ), 0 )이 된다. 1장에서 소개한 덧셈정리를 이용하면 다음과 같다.

(x cosθ - y sinθ, x sinθ + y cosθ, 0)

이번에는 행렬을 이용하여 표현해보자. vx

v x cosθ - v y sinθ v x sinθ + v y cosθ

vz

1

= Rz

vy vz 1

CHAPTER 5 - 좌표 변환

161


여기서 행렬 R z 는 다음처럼 된다. v x cosθ - v y sinθ

cosθ - sinθ 0

0

vx

v x sinθ + v y cosθ = sinθ cosθ vz 0 0

1

0 v y 0 vz

0

1

1

0

0

0

1

마찬가지로, x축에서의 회전 결과는 다음과 같다. vx

v y cosθ - v z sinθ v y sinθ + v z cosθ

1

그리고 y축에서의 회전 결과는 다음과 같다. v z sinθ + v x cosθ vy

v z cosθ - v x sinθ

1

즉, v x , v y , v z 가 차례대로 순회할 뿐이다. 정리하면 x , y , z 각 축에서의 각도 θ 의 회전 이동을 위한 행렬 Rx , Ry , Rz 는 다음과 같다. 1 Rx =

Ry =

0

0

0

cosθ - sinθ 0

0

sinθ

0

0

cosθ 0 0

1

cosθ

0

sinθ

0

1

0

0

0

- sinθ 0

162 유니티로 배우는 게임 수학

0

0

0

cosθ 0 0

1


w w w. h a n b i t . c o . k r

이것이 프로그래밍이다! 저자 직강 동영상 제공!

이것이 안드로이드다

이것이 C언어다

이것이 자바다

진정한 안드로이드 개발자로 이끌어줍니다.

세상에 없던 새로운 C언어 입문서 탄생!

가장 중요한 프로그래밍 언어를 하나 배워야 한다면, 결론은 자바다!

SDK 5.0 롤리팝 호환!

삼성, LG에서 펼쳐졌던 전설의 명강의를 풀타임 동영상 강좌로!

중급 개발자로 나아가기 위한 람다식, JavaFX, NIO 수록

이보다 더 확실한 방법은 없다, 칠판강의

책만 보고, 동영상 강좌로도 만족하지 못했다면 Daum 카페 '슈퍼드로이드'에서 만나요

전체 동영상 강좌 유투브 전격 공개!

자바의 모든 것을 알려주는 인터넷 강의 궁금한 것은 카페에서!

cafe.daum.net/superdroid

http://goo.gl/tJK3Tu

cafe.naver.com/thisisjava

박성근 저 | 1,164쪽 | 45,000원

서현우 저 | 708쪽 | 25,000원

신용권 저 | 1,224쪽 | 30,000원


w w w. h a n b i t . c o . k r

지금은 모던 웹 시대! 모던 웹 디자인을 위한

모던 웹을 위한

HTML5 + CSS3 입문 HTML5 분야 부동의 1위 도서

JavaScript + jQuery 입문

HTML5 표준안 확정에 맞춘 완전 개정판의 귀환!

자바스크립트에서 제이쿼리, 제이쿼리 모바일까지 한 권으로 끝낸다!

HTML5 권고안과 최신 웹 브라우저 환경 대응

시대의 흐름에 맞춰 다시 쓴 자바스크립트 교과서

윤인성 저 | 624쪽 | 30,000원

윤인성 저 | 980쪽 | 32,000원

모던 웹을 위한

HTML5 + CSS3 정복

Node.js

프로그래밍 페이스북, 월마트, 링크드인은 왜 Node.js를 선택했는가?

필요한 것만 배워 바로 현장에서 쓰는 HTML5

이 물음에 대한 답은 Node.js가 보여주는 빠른 처리 능력 때문이다.

순서대로 읽으며 실습할 수 있는 HTML5 자습서

윤인성 저 | 484쪽 | 25,000원

김상형 저 | 700쪽 | 32,000원


w w w. h a n b i t . c o . k r

Hanbit eBook

Realtime w w w. h a n b i t . c o . k r / e b o o k

DRM free! 어떤 디바이스에서도 자유롭게

eBook Oriented! 전자책에 꼭 맞는 최적의 내용과 디자인

Hanbit eBook

Hanbit eBook

Realtime 70

Realtime 89 49

MFC 프로그래밍 주식분석 프로그램 만들기 김세훈 지음

Hanbit eBook

Hanbit eBook

Realtime 90

Realtime 92 49

자바 개발자를 위한

Vert.x JavaScript Promise​ azu​지음 /​주우영​옮김

애플리케이션 개발 모바일/웹 메시징 STOMP와 MQTT로 개발하는 IoT 모바일/웹 애플리케이션 Mobile and Web Messaging 제프 메스닐 지음 / 조건희 옮김

이연복 지음


w w w. h a n b i t . c o . k r

즐거운 상상이 가득! 2015년 화제의 신간

즐거운 상상이 가득! 2015년 화제의 신간

전자부품 백과사전 vol.1 찰스 플랫 지음 / 배지은 옮김 / 30,000원

취미공학에 필요한 핵심 전자부품을 사전식으로 정리한 안내서.

전자부품 백과사전 vol.1 찰스 플랫 지음 / 배지은 옮김 / 30,000원

처음 시작하는 센서

취미공학에 필요한 핵심 전자부품을 사전식으로 정리한 안내서.

전자부품 백과사전 vol.2

찰스 플랫 지음 / 가격미정

키모 카르비넨, 테로 카르비넨 지음 임지순 옮김 / 13,000원

세상을 수치로 읽어내는

<전자부품 백과사전> 시리즈의 두 번째 도서다.

부품인 센서를 알려주 는 책. 이 책을 통해 자신 만의 프로젝트에 다양한 처음 센서를 사용해보자.

Zero to Maker

: 누구나 메이커가 될 수 있다 데이비드 랭 지음 / 장재웅 옮김 / 14,000원

전자부품 백과사전 vol.2

찰스 플랫 지음 / 가격미정

일반인에서 메이커로. 날백수에서 무인 잠

<전자부품 백과사전> 시리즈의 수정 회사 CEO 가 된 사나이, 데이비드두 번째 도서다. 랭의 메이커 도전기.

Make: 센서

시작하는 센서

키모 카르비넨, 테로 카르비넨 지음 임지순 옮김 / 13,000원

세상을 수치로 읽어내는 부품인 센서를 알려주

키모 카르비넨, 테로 카르비 넨, 빌 발토카리 지음 는 책. 이 책을 통해 자신 / 가격미정

만의 프로젝트에 다양한

필수 전자부품인 센서를

센서를 사용해보자. 마이크로 컨트롤러 보드

Zero to Maker

: 누구나 메이커가 될 수 있다

에 응용하는 방법을 담

데이비드 랭 지음 / 장재웅 옮김 / 14 ,000원 Maker Pro

았다.

베이첼 지음 / 가격미정 일반인에서 메이커로.존날백수에서 무인 잠

메이커라면 반드시 읽어야 할 필수 계발

수정 회사 CEO가 된 사나이, 데이비드 서. 프로 메이커들과의 인터뷰 및 에세이 랭의 메이커 도전기. 수록.

프로젝트로 배우는 라즈베리 파이

도날드 노리스 지음 / 임지순 옮김

다양한 실전 프로젝트를 통해 라즈베리 파이를 쉽고 재미있게 배워본다.

Maker Pro 존 베이첼 지음 / 가격미정

메이커라면 반드시 읽어야 할 필수 계발

Make: 센서 키모 카르비넨, 테로 카르비 넨, 빌 발토카리 지음 / 가격미정

필수 전자부품인 센서를 마이크로 컨트롤러 보드 에 응용하는 방법을 담 았다.



Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.