OpenGL의 좌표계, 진짜로 이해하기

2025. 4. 8. 11:00·Dev/Grapics
"왜 0, 0, 0에 두었는데 화면에 안 보일까?

 

1.  좌표계가 헷갈리는 이유

OpenGL에서 처음 물체를 렌더링 할 때 이런 경험이 있다면 당신만 그런 게 아니다

  • 분명히 (0, 0, 0)에 모델을 뒀는데 화면에 아무것도 안 보인다.
  • 카메라는 설정했는데 방향이 어디를 보는지 감이 없다.
  • gl_Position 계산했는데 화면이 시커멓다.

이런 혼란의 원인은 대부분 좌표계와 변환에 대한 이해 부족이다.

OpenGL에서의 렌더링은 단순한 그리기가 아니라,

"모델의 좌표를 변환해 최종 스크린까지 도달시키는 여정"이다.


2. 좌표계란 무엇인가?

좌표계(Coordinate System)는 공간의 기준을 정의하는 약속이다.

어디를 기준으로 (0, 0, 0)인지, 각 축이 어느 방향을 향하는지를 정의한다.

 

OpenGL은 총 6단계의 좌표계를 거치며 위치를 변환한다

Object -> World -> View -> Clip -> NDC -> Screen

각 단계는 행렬(Matrix) 연산으로 이어지며,

이는 다음과 같은 연산으로 요약된다

gl_Position = Projection * View * Model * vec4(position, 1.0);
즉, 하나의 정점(Vertex)을 최종 위치로 변환하는 데는 3개의 행렬과 6개의 좌표계가 필요하다.

 

시작하기 앞서 OpenGL에서 기본적으로 사용하는 좌표계 방향을 알아보자

Right Handed system

OpenGL에서는 기본적으로 오른손 좌표계를 사용하고 있고

기본 뷰 카메라는 -Z방향을 보고 있기 때문에 흔히 하는 실수는

물체를 +Z 축 방향으로 이동시키면 카메라의 뒤쪽으로 물체를 보내버리는 셈이라 화면에 보이지 않게 된다.


3. 좌표계 흐름 완전 정복

이제 각 좌표계가 무엇을 의미하고, 왜 존재하는지를 하나씩 세세히 알아보자.

 

 

1. 모델 좌표계 (Model Space, 또는 Local/Object Space)

"이 물체 자체 안에서 좌표가 어떻게 생겼나?"

 

  • 각 정점은 오브젝트 기준으로 표현됨
  • 예: 정육면체는 중심을 (0, 0, 0)으로 하고, 꼭짓점은 (-1, -1, -1) 같은 값

Model행렬은 이 모델을 "어디에", "얼마나 회전시켜", "얼마나 확대/축소할지" 결정한다

model = Translate * Rotate * Scale;

 

Model -> World

 

2. 월드 좌표계 (World Space)

"이 오브젝트를 세상 안에 어떻게 배치할까?"

 

  • 모델이 속해있는 월드 좌표 기준으로 변환.
  • 모든 물체들이 공유하는 절대적 위치 기준
  • 서로 다른 모델들이 이 좌표계에서 충돌 검사, 카메라 연산 등을 할 수 있게 된다.

 

3. 뷰 좌표계 (View Space, Camera Space)

"카메라의 시점에서 이 물체는 어떻게 보일까?"
  • 카메라를 원점 (0, 0, 0)으로 이동시키는 것처럼 동작
  • 월드 공간의 모든 물체들을 카메라 기준으로 뒤로 이동시키는 연산
  •  View행렬은 LookAt() 같은 방식으로 만든다
view = glm::lookAt(cameraPos, targetPos, upVector);

 

4. 클립 좌표계 (Clip Space)

"투영(projection)을 거쳐 계산된 공간. 아직 정규화는 안 됨"
  • Perspective(원근) 또는 Orthographic(직교) 방식으로 변환됨
  • Z 축 깊이 정보가 보존되지만, 아직 w를 나누기 전이라 왜곡되지 않음
  • 모든 좌표계 중 가장 수학적인 단계

Perspective orthographic

 

5. NDC (Normalized Device Coordinates)

"좌표계를 -1 ~ 1 사이로 정규화"

 

클립 공간 좌표를 w로 나누어 정규화한 좌표계

OpenGL에서 그릴 수 있는 범위는 반드시 -1 ≤ x, y, z ≤ 1 이내여야 함

이 범위를 넘으면 자동으로 잘려(Clipping) 버려짐


Cplipping

 

쉽게 비유하면, 클립공간에서 NDC좌표계로 변환되며 -1~1의 범위를 넘어가는 경우

카메라로 촬영할 때 카메라의 뷰파인더와 같이 뷰파인더 안에 들어온 장면만 필름에 담기고,

바깥은 잘려나가는 것과 같다

 

 

NDC는 해상도에 상관없는 '가상 화면' 개념

따라서 1920x1080이든, 300x300이든 NDC의 좌표값은 같다.

 

6. 스크린 좌표계 (Screen Space)

"정말로 픽셀이 존재하는 화면"

  • NDC의 -1~1 범위를 실제 해상도 (예: 800x600)에 매핑
  • Viewport 설정에 따라 달라짐
giViewport(0, 0, screenWidth, screenHeight);

4. w로 나누는 이유 - 원근 투영의 핵심

OpenGL은 gl_Position = vec4(x, y, z, w); 로 셰이더에서 좌표를 출력한다.

그런데 렌더링 전에 GPU는 자동으로 다음과 같은 연산을 수행한다.

x' = x / w
y' = y / w
z' = z / w

 

이게 바로 원근(Perspective) 투영의 핵심이다.

w 값은 보통 카메라로부터의 거리와 관련된 값이다.
멀리 있는 물체일수록 w값이 커지고, 그 결과 x/w, y/w는 작아져서 더 작게 보인다.

즉, 원근 왜곡 효과는 이 w 나눗셈에서 시작된다.


5. 자주 생기는 좌표계 관련 실수

상황 원인 해결 방법
물체가 안 보인다 NDC 범위 밖에 있음 View/Projection 설정 점검
화면에 물체가 너무 큼 FOV나 Neer/Far Plane 이상함 Projection 행렬 확인
텍스처가 뒤집혀 보임 UV좌표계와 스크린 좌표계 차이 텍스처 flip 설정 확인

 


6. 좌표계 흐름 요약표

좌표계 설명 변환 행렬
모델 오브젝트 내부 기준  Model
월드 전역기준 좌표 Model
뷰 카메라 기준 View
클립 투영된 좌표 Projection
NDC 정규화된 -1~1 공간 w 나눗셈
스크린 실제 해상도 픽셀 기준 Viewport 매핑

참고 자료

• LearnOpenGL - Coordinate Systems

• OpenGL Wiki - Vertex Transformation

• Scratchapixel - 3D Perspective Projection

'Dev > Grapics' 카테고리의 다른 글

Rasterization vs Ray Tracing  (0) 2025.04.09
셰이더는 그낭 함수일까?  (0) 2025.04.08
정점(Vertex)이란 무엇인가? - 그래픽 세계의 가장 작은 시작점  (0) 2025.04.08
렌더링 파이프라인: 그래픽이 만들어지는 과정  (0) 2025.04.07
컴퓨터 그래픽스에서 말하는 '그래픽'이란 무엇인가?  (2) 2025.04.07
'Dev/Grapics' 카테고리의 다른 글
  • Rasterization vs Ray Tracing
  • 셰이더는 그낭 함수일까?
  • 정점(Vertex)이란 무엇인가? - 그래픽 세계의 가장 작은 시작점
  • 렌더링 파이프라인: 그래픽이 만들어지는 과정
onepaperhoon
onepaperhoon
한장훈님의 블로그 입니다.
  • onepaperhoon
    OnePaperHoon Blog
    onepaperhoon
  • 전체
    오늘
    어제
    • 분류 전체보기 (14)
      • Dev (14)
        • System Programming (2)
        • Linux (0)
        • CS (0)
        • Network, Protocol (0)
        • Grapics (11)
        • Web, App (0)
        • Design Pattern (1)
      • Projects (0)
      • TIL (0)
      • Life (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    graphics
    named pipe
    C언어
    cpp
    IPC
    shader
    그래픽스
    OpenGL
    3d
    Vertex Shader
    glfw
    공유 메모리
    shared memory
    싱글톤 패턴
    c++
    Pipe
    graphicapi
    Game
    디자인 패턴
    Process
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
onepaperhoon
OpenGL의 좌표계, 진짜로 이해하기
상단으로

티스토리툴바