게임 프로그래밍 좌표계와 행렬 변환 입문 가이드

profile_image
작성자 좌표설계자 하린
댓글 0건 조회 5회

게임 화면이 어긋나는 첫 번째 이유: 좌표계 이해 부족

좌표계는 위치를 약속하는 언어입니다

캐릭터가 오른쪽으로 이동해야 하는데 위로 올라가거나, 카메라를 돌렸더니 오브젝트가 이상한 축을 기준으로 회전한 경험이 있나요? 초보 게임 프로그래밍에서 이런 문제는 대부분 좌표계를 명확히 구분하지 못해서 발생합니다. 좌표계는 단순히 x, y, z 숫자를 저장하는 방식이 아니라, 게임 월드 안에서 위치와 방향을 해석하는 공통 약속입니다.

Will Perone 같은 개발자 포트폴리오나 게임 수학 라이브러리를 살펴볼 때도 좌표와 행렬 처리는 거의 기본기처럼 등장합니다. 2026년 기준으로 Unity, Unreal Engine, Godot 같은 엔진을 쓰더라도 내부에서는 여전히 벡터, 행렬, 변환 순서가 핵심입니다. 엔진이 많은 것을 감춰주지만, 문제가 생겼을 때 원인을 찾으려면 기초 개념을 직접 설명할 수 있어야 합니다.

  • 월드 좌표: 게임 전체 공간에서의 절대 위치입니다. 맵 중앙, 플레이어 시작 지점, 적 스폰 위치를 다룰 때 사용합니다.
  • 로컬 좌표: 오브젝트 자기 자신을 기준으로 한 위치입니다. 캐릭터 손에 붙은 무기, 자동차 바퀴 위치처럼 부모 오브젝트 기준의 배치에 유용합니다.
  • 스크린 좌표: 최종적으로 모니터나 모바일 화면에 표시되는 픽셀 기준 좌표입니다. UI, 마우스 클릭, 터치 입력 처리에서 자주 만납니다.
초보자는 먼저 “이 숫자가 어느 좌표계 기준인가?”를 묻는 습관을 들이면 디버깅 시간이 크게 줄어듭니다.

왼손 좌표계와 오른손 좌표계도 확인하세요

3D 게임 프로그래밍에서는 축 방향도 중요합니다. 어떤 엔진은 y축을 위로 보고, 어떤 엔진은 z축을 위로 봅니다. 또한 왼손 좌표계와 오른손 좌표계에 따라 회전 방향과 외적 결과가 달라질 수 있습니다. 수학 공식만 외우면 된다고 생각하기 쉽지만, 실제 프로젝트에서는 엔진의 좌표계 규칙을 먼저 확인하는 것이 더 중요합니다.

예를 들어 캐릭터가 바라보는 방향 벡터를 기준으로 총알을 발사한다고 가정해 봅시다. 로컬 기준의 앞 방향을 월드 좌표로 바꾸지 않고 그대로 쓰면, 캐릭터가 회전해도 총알은 항상 같은 방향으로 날아갈 수 있습니다. 이런 버그는 코드 한 줄보다 좌표계 개념 하나를 놓쳤을 때 더 자주 생깁니다.

  1. 엔진 문서에서 위쪽 축이 y인지 z인지 확인합니다.
  2. 오브젝트 위치가 월드 기준인지 로컬 기준인지 변수명에 드러냅니다.
  3. 입력 좌표, 카메라 좌표, 월드 좌표를 섞을 때는 변환 함수를 명시적으로 사용합니다.

벡터와 행렬을 겁내지 않는 기본 공식

벡터는 방향과 크기를 담는 작은 도구입니다

게임 프로그래밍 입문자가 수학에서 가장 먼저 부딪히는 장벽은 벡터입니다. 하지만 벡터는 복잡한 기호가 아니라 방향과 크기를 함께 표현하는 데이터라고 보면 훨씬 편합니다. 플레이어가 앞으로 이동하는 방향, 카메라가 바라보는 방향, 적과 플레이어 사이의 거리 계산이 모두 벡터로 처리됩니다.

2D 게임에서는 보통 Vector2, 3D 게임에서는 Vector3를 사용합니다. 위치도 벡터로 표현하고 속도도 벡터로 표현하기 때문에 처음에는 헷갈릴 수 있습니다. 차이는 의미입니다. 위치 벡터는 “어디에 있는가”를 나타내고, 방향 벡터는 “어느 쪽을 향하는가”를 나타냅니다. 같은 숫자라도 문맥이 다르면 완전히 다른 역할을 합니다.

  • 덧셈: 위치에 이동량을 더해 새 위치를 구합니다. 예: playerPosition + velocity * deltaTime
  • 정규화: 길이를 1로 만들어 순수한 방향만 남깁니다. 대각선 이동 속도가 빨라지는 문제를 막을 때 자주 사용합니다.
  • 내적: 두 방향이 얼마나 같은 방향을 보는지 확인합니다. 시야각 판정, 조명 계산, 후방 공격 판정에 쓰입니다.
  • 외적: 두 벡터에 수직인 방향을 구합니다. 3D 회전축, 법선 계산, 카메라 오른쪽 방향 계산에서 중요합니다.

행렬은 위치, 회전, 크기를 한 번에 다루는 변환 상자입니다

행렬을 처음 보면 숫자가 격자처럼 나열되어 있어 부담스럽습니다. 하지만 게임 수학에서 행렬은 대개 오브젝트를 어떻게 옮기고, 돌리고, 키울 것인가를 담는 변환 도구입니다. 특히 4x4 행렬은 3D 공간에서 이동, 회전, 스케일을 하나의 구조로 묶어 GPU에 전달하기 좋습니다.

직접 모든 행렬 곱셈을 손으로 계산할 필요는 없습니다. 다만 변환 순서는 반드시 이해해야 합니다. 스케일을 먼저 하고 회전한 뒤 이동하는 것과, 이동한 뒤 회전하는 것은 결과가 다릅니다. 캐릭터 무기가 손에서 떨어져 보이거나, UI가 이상한 기준점으로 확대되는 문제도 변환 순서에서 시작되는 경우가 많습니다.

  1. Scale: 오브젝트 크기를 조절합니다.
  2. Rotate: 기준축을 중심으로 방향을 바꿉니다.
  3. Translate: 최종 위치로 이동합니다.

초보 단계에서는 “SRT 순서로 로컬 모양을 만든 뒤 월드에 배치한다”는 식으로 이해하면 좋습니다. 엔진마다 내부 곱셈 방향과 표현 방식이 다를 수 있으므로, 직접 만든 math library를 사용할 때는 문서와 테스트 케이스를 반드시 함께 작성해야 합니다.

로컬에서 월드로, 월드에서 화면으로 이동하는 흐름

게임 오브젝트는 여러 공간을 거쳐 화면에 나타납니다

게임 속 모델 하나가 화면에 보이기까지는 여러 단계의 좌표 변환을 거칩니다. 로컬 좌표로 만들어진 메시가 월드 좌표에 배치되고, 카메라 기준의 뷰 좌표로 바뀐 뒤, 투영 변환을 통해 화면에 그려집니다. 이 흐름을 이해하면 렌더링 파이프라인을 처음 접할 때도 훨씬 덜 막힙니다.

예를 들어 큐브 모델의 꼭짓점은 처음에는 큐브 중심을 기준으로 저장됩니다. 이 상태가 로컬 좌표입니다. 큐브를 맵의 특정 위치로 옮기면 월드 좌표가 되고, 카메라가 바라보는 기준으로 다시 바꾸면 뷰 좌표가 됩니다. 마지막으로 원근감을 적용하면 가까운 것은 크게, 먼 것은 작게 화면에 표시됩니다.

  • Model Matrix: 로컬 좌표를 월드 좌표로 바꿉니다.
  • View Matrix: 월드 좌표를 카메라 기준 좌표로 바꿉니다.
  • Projection Matrix: 3D 좌표를 2D 화면에 투영합니다.
  • Viewport Transform: 정규화된 좌표를 실제 픽셀 좌표로 변환합니다.
렌더링 버그를 만났을 때는 셰이더부터 의심하기보다 “현재 좌표가 어느 공간에 있는가”를 단계별로 출력해 보세요.

입력 처리에서도 좌표 변환이 필요합니다

좌표 변환은 렌더링에만 쓰이지 않습니다. 마우스로 적을 클릭하거나, 터치한 위치에 캐릭터를 이동시키거나, UI 위에 월드 오브젝트 이름표를 띄울 때도 필요합니다. 화면 좌표를 월드 좌표로 되돌리는 작업은 초보자가 자주 놓치는 부분입니다.

예를 들어 사용자가 화면 오른쪽 아래를 클릭했다고 해서 그 픽셀 위치가 곧 게임 월드의 오른쪽 아래를 의미하지는 않습니다. 카메라 위치, 줌, 투영 방식, 화면 해상도에 따라 같은 픽셀도 다른 월드 위치를 가리킬 수 있습니다. 그래서 ScreenToWorld, WorldToScreen 같은 변환 함수가 게임 엔진에 기본으로 제공됩니다.

  1. 마우스나 터치 입력은 먼저 스크린 좌표로 들어옵니다.
  2. 카메라 정보를 이용해 월드 좌표 또는 레이로 변환합니다.
  3. 충돌 검사나 지형 교차 계산으로 실제 목표 위치를 찾습니다.
  4. 캐릭터 이동, 선택 UI, 이펙트 생성에 결과 좌표를 사용합니다.

GDC 같은 개발자 콘퍼런스에서도 그래픽스와 엔진 구조는 꾸준히 다뤄지는 주제입니다. 용어 배경이 궁금하다면 GDC 지식백과 설명을 참고하면 산업 맥락을 잡는 데 도움이 됩니다.

초보자가 직접 만들어보면 좋은 미니 수학 라이브러리

처음부터 거대한 엔진을 만들 필요는 없습니다

게임 프로그래밍을 배우는 단계에서 수학 라이브러리를 직접 만들어보는 것은 매우 좋은 연습입니다. 다만 목표를 크게 잡으면 금방 지칩니다. Quaternion, SIMD 최적화, 행렬 분해까지 한 번에 구현하려고 하기보다, Vector2, Vector3, Matrix4처럼 작은 단위부터 시작하는 편이 좋습니다.

Will Perone 사이트의 핵심 키워드가 game programming, math, developer, portfolio인 만큼, 이런 미니 라이브러리는 포트폴리오에도 잘 어울립니다. 단순히 “벡터 클래스를 만들었습니다”에서 끝내지 말고, 이동, 회전, 충돌 판정, 카메라 변환에 실제로 사용한 예제를 함께 보여주면 개발자의 사고 과정을 드러낼 수 있습니다.

  • Vector2: 2D 이동, UI 좌표, 간단한 충돌 판정에 사용합니다.
  • Vector3: 3D 위치, 방향, 법선, 카메라 계산에 사용합니다.
  • Matrix4: 3D 변환과 렌더링 파이프라인 학습에 적합합니다.
  • Transform: position, rotation, scale을 묶어 게임 오브젝트 상태를 표현합니다.

테스트 케이스가 수학 버그를 막아줍니다

수학 코드는 눈으로만 확인하기 어렵습니다. 숫자 하나가 틀려도 화면에서는 “뭔가 이상하다” 정도로만 보일 수 있습니다. 그래서 초보자일수록 작은 단위 테스트를 작성하는 습관이 필요합니다. 길이가 5인 벡터를 정규화하면 길이가 1에 가까워지는지, 단위 행렬을 곱하면 값이 그대로 유지되는지 확인하는 식입니다.

아래처럼 최소 기능 목록을 정해두면 범위를 통제하기 쉽습니다. C++, C#, Rust, JavaScript 어느 언어를 쓰든 개념은 같습니다. 중요한 것은 라이브러리를 완성하는 속도가 아니라, 각 함수가 어떤 게임 상황에서 쓰이는지 설명할 수 있는 능력입니다.

  1. 벡터 덧셈, 뺄셈, 스칼라 곱을 구현합니다.
  2. length, normalize, dot, cross 함수를 추가합니다.
  3. identity, translation, rotation, scale 행렬 생성 함수를 만듭니다.
  4. 행렬과 벡터 곱셈 결과를 테스트합니다.
  5. 간단한 2D 또는 3D 데모에서 실제로 사용합니다.

기획자와 협업할 때도 수학 개념은 의외로 유용합니다. 이동 거리, 판정 범위, 시야각, 카메라 연출을 설명할 때 개발자만 아는 표현으로 말하면 소통이 느려집니다. 역할 이해가 필요하다면 기획자 관련 지식백과 항목처럼 직무 관점의 설명을 함께 보는 것도 좋습니다.

자주 묻는 질문과 실전 체크리스트

FAQ로 좌표계 실수를 빠르게 줄여보세요

초보자가 좌표계와 행렬 변환을 배울 때 가장 많이 묻는 질문은 비슷합니다. “엔진이 다 해주는데 왜 배워야 하나요?”, “행렬을 직접 구현해야 하나요?”, “쿼터니언은 언제 공부해야 하나요?” 같은 질문입니다. 답은 간단합니다. 엔진을 쓰더라도 디버깅, 최적화, 포트폴리오 설명을 위해 기본 개념은 반드시 필요합니다.

특히 게임 포트폴리오를 준비한다면 결과 화면만 보여주는 것보다 문제 해결 과정을 보여주는 편이 훨씬 설득력 있습니다. 예를 들어 “월드 좌표와 스크린 좌표 변환을 이용해 적 체력바를 정확히 배치했다”는 설명은 단순한 UI 구현보다 깊이가 있습니다. 작은 기능도 수학적 근거를 곁들이면 개발 역량이 더 분명해집니다.

  • Q. 행렬을 꼭 외워야 하나요? A. 모든 원소를 외울 필요는 없습니다. 이동, 회전, 스케일이 어떤 순서로 적용되는지 이해하는 것이 먼저입니다.
  • Q. 2D 게임만 만들면 3D 수학은 필요 없나요? A. 2D에서도 벡터, 내적, 정규화, 좌표 변환은 계속 사용됩니다. 3D보다 차원이 낮을 뿐 원리는 같습니다.
  • Q. 직접 math library를 만들어도 실무에서 쓰나요? A. 실무에서는 검증된 라이브러리를 쓰는 경우가 많지만, 직접 구현 경험은 디버깅과 엔진 이해에 큰 도움이 됩니다.
  • Q. 쿼터니언은 언제 배우면 좋나요? A. 오일러 각 회전에서 짐벌락이나 보간 문제가 궁금해질 때 배우면 이해가 훨씬 쉽습니다.

입문자가 바로 적용할 체크리스트

이제 좌표계와 행렬 변환을 공부할 때 무엇부터 확인해야 할지 체크리스트로 정리해 봅시다. 실제 프로젝트에서 아래 항목을 주석, 변수명, 테스트로 남겨두면 팀원이 코드를 읽기도 쉬워집니다. 특히 포트폴리오 코드라면 읽는 사람이 짧은 시간 안에 의도를 파악할 수 있어야 합니다.

2026년에도 게임 개발 도구는 계속 좋아지고 있지만, 게임 수학의 기본 원리는 크게 달라지지 않습니다. 오히려 엔진과 툴이 복잡해질수록 기초를 정확히 아는 개발자가 문제를 더 빠르게 좁힐 수 있습니다. 좌표계, 벡터, 행렬을 따로 외우지 말고 “플레이어를 움직이고, 카메라로 보고, 화면에 표시하는 흐름”으로 연결해서 익혀보세요.

  1. 변수명에 local, world, screen 같은 좌표계 정보를 포함합니다.
  2. 대각선 이동 전에는 입력 벡터를 정규화합니다.
  3. 회전 방향이 이상하면 엔진의 좌표계와 축 방향을 먼저 확인합니다.
  4. Model, View, Projection 변환 순서를 그림으로 그려봅니다.
  5. 수학 함수마다 최소 1개 이상의 테스트 케이스를 둡니다.
  6. 포트폴리오에는 결과 화면과 함께 어떤 좌표 변환을 사용했는지 설명합니다.

처음에는 숫자와 공식이 낯설지만, 작은 데모를 만들며 반복하면 좌표계는 생각보다 빠르게 익숙해집니다. 플레이어 이동, 총알 발사, 카메라 추적, UI 체력바처럼 눈에 보이는 기능과 연결해 연습하면 지식이 코드 안에 자연스럽게 남습니다.

게임 프로그래밍 좌표계와 행렬 변환 입문 가이드

댓글목록

등록된 댓글이 없습니다.