[게임수학] 7. 게임 엔진

2025. 9. 24. 18:57·게임수학
728x90

→ 이 글은 「이득우의 게임 수학」을 바탕으로 작성했습니다.

■ 게임 엔진 구성 요소

[유니티(좌) / 언리얼(우)]

게임 엔진은 씬(Scene), 레벨(Level)이라 부르는 게임 공간을 설계하는 작업 공간과 리소스(Resource) 혹은 에셋(Asset)이라 부르는 게임 데이터를 관리하는 공간으로 나뉜다.

[씬 공간과 에셋 공간으로 분리된 게임 엔진]

게임 엔진은 씬과 에셋으로 이원화된 구조를 바탕으로 아래와 같이 데이터를 결합하여 최종 화면이 렌더링 되도록 설계된다.

[씬과 에셋으로부터 만들어지는 최종 화면]

1. 씬의 구조

게임 공간에 배치된 물체를 효과적으로 관리하기 위해 물체가 가져야 할 규격을 제시하는데, 이를 게임 오브젝트(Game Object) 혹은 액터(Actor)라 부른다.

씬을 구성하는 게임 오브젝트는 항상 게임 공간 내에 존재하기 때문에 언제나 공간 내 배치 정보를 가져야 한다.

  • 배치 정보를 위치, 회전, 크기로 구성된 트랜스폼(Transform)의 정보를 사용해 관리한다.

 

2. 모델링 행렬 설계

트랜스폼은 크기, 회전, 이동(위치)의 세 가지 데이터로 구성되며, 각 데이터는 세 가지 아핀 변환행렬에 대응된다.

$$ S = \begin{bmatrix} s_x&0&0 \\ 0&s_y&0 \\ 0&0&1\end{bmatrix} \\R = \begin{bmatrix} \cos\theta&-\sin\theta&0 \\ \sin\theta&\cos\theta&0 \\ 0&0&1\end{bmatrix}\\ T = \begin{bmatrix} 1&0&t_x \\ 0&1&t_y \\ 0&0&1\end{bmatrix} $$

[아핀 변환 대응 행렬]

 

선형 변환 행렬은 행렬곱(합성함수)을 통해 3가지 아핀 변환을 한번에 수행하는 “하나의 행렬”을 만들 수 있다.

하지만 행렬 곱은 교환법칙이 성립되지 않기 때문에, 곱하는 순서를 미리 지정하여 하나의 행렬로 만들어야 한다.

[이동 변환과 회전 변환의 순서 비교]

어떤 물체를 (0,1)로 이동변환 했을 때, 이 물체의 최종 위치는 (0,1)이 되어야 한다. 하지만 이동 변환을 먼저 적용하고 회전 변환을 적용한 결과는 물체의 위치가 다른 좌표로 바뀌는 것을 확인할 수 있다.

 

이는 크기 변환도 마찬가지이므로, 원하는 위치로 물체를 위치시키기 위해선 이동 변환이 가장 마지막에 진행되어야 한다. 따라서 아래와 같은 행렬곱 경우의 수가 남는다.

  • $T\cdot S\cdot R$ : 회전 → 크기 → 이동의 순서
  • $T\cdot S\cdot R$ : 크기 → 회전 → 이동의 순서

[크기 변환과 회전 변환의 순서 비교]

크기 변환을 먼저 수행할 경우 직사각형의 형태가 된다. 따라서 크기 변환을 먼저 적용하면 직사각형이 회전된 모습이지만, 회전 변환을 먼저 적용하면 마름오 형태가 된다.

 

회전 변환은 물체의 형태를 그대로 보존시키는 “강체 변환”이다. 따라서, 크기 변환을 적용하여 물체의 형태를 “확정”한 다음 강체 변환을 적용시켜 형태를 유지하는 것이 가장 이상적이다.

  • 따라서 트랜스폼의 변환은 크기 → 회전 → 위치 순서로 이뤄진다.

$$ M = T\cdot R\cdot S = \begin{bmatrix} \cos\theta\cdot s_x & -\sin\theta\cdot s_y & t_x \\ \sin\theta\cdot s_x & \cos\theta\cdot s_y & t_y\\ 0&0&1\end{bmatrix} $$

 

■ 로컬 공간과 로컬 축

씬에는 여러 물체가 모인 “월드 공간(World Space)”이 존재한다. 이 월드 공간에 모인 물체는 자신만의 공간에서 물체를 구성하는 각 정점의 위치 정보가 저장된다.

이렇게 물체의 정보를 담기 위해 부여한 공간을 “로컬 공간(Local space)”이라고 한다.

[월드 공간의 축과 로컬 축]

물체를 기준으로 설정된 방향 정보를 로컬 축(Local axis)이라 한다. 로컬 축 정보는 로컬 공간의 기저벡터와 동일한 값을 가진다.

  • 로컬 축은 월드의 $X,Y,Z$축과 구분하기 위해 아래와 같은 이름으로 부른다.
로컬 축 이름
+X 라이트벡터(Right Vector)
+Y 업벡터(Up Vector)
+Z 포워드벡터(Forward Vector)

 

로컬 축은 오로지 회전 정보에만 영향을 받는데, 트랜스폼에 새로운 회전 값이 설정되면 로컬 축을 구성하는 표준기저벡터들은 이에 따라 변하게 된다.

  • 로컬 공간의 $e_1$이 변화된 값을 $\vec r$로, $e_2$가 변화된 값을 $\vec u$로 표현한다면,

$$ \vec r = (\cos\theta, \sin \theta)\\ \vec u = (-\sin\theta,\cos\theta) $$

또한, 로컬축 벡터의 원소를 각각 $\vec r = (r_x, r_y)$와, $\vec u=(u_x, u_y)$로 지정하면, 아핀 회전 변환행렬은 삼각함수 대신 로컬 축 벡터를 사용해 생성할 수 있다.

 

$$ R = \begin{bmatrix} r_x & u_x&0 \\ r_y & u_y&0 \\ 0&0&1\end{bmatrix} $$

게임 오브젝트의 트랜스폼을 부여하는 과정은, 각 오브젝트에 부여된 로컬 공간 정보를 월드 공간 정보로 변환하는 것이다.

 

■ 렌더링 파이프라인

일반적으로 게임 엔진은 그릴 물체의 정보를 GPU에 넘겨 GPU가 처리하도록 위임한다. GPU에 그릴 물체의 정보를 전달하면, 지정된 워크플로우를 통해 렌더링을 진행하고 결과를 화면에 띄운다.

  • GPU 내부에 설정된 워크플로우를 “렌더링 파이프라인”이라 한다.

각 렌더링 단계를 간단하게 설명하면 아래와 같다.

 

1. Vertex / Index buffer

3D 모델의 정점(Vertex) 데이터와 이를 삼각형으로 묶어주는 인덱스(index)데이터가 GPU메모리에 저장된다.

         → 여기서부터 GPU 렌더링이 시작되며, CPU가 GPU에게 메시랑 머터리얼 조합으로 삼각형을 그리라는 명령이 발생하는 것을 “드로우콜(Draw Call)”이 발생했다고 한다.

 

2. Input Assembler

정점과 인덱스를 가져와 기본 도형(삼각형)을 조립한다.

 

3. Vertex Shader

각 정점에 대해 실행되는 프로그램이다.

  • 로컬 좌표 → 월드 좌표 → 뷰 좌표 → 클립 좌표로 변환.
  • 정점 위치 계산(행렬곱).
  • 조명에 필요한 벡터 전달.

 

4. Tessellation (선택적)

삼각형을 더 잘게 쪼개 저해상도 메시를 GPU가 자동으로 세분화해서 디테일을 높인다.

 

5. Geometry Shader (선택적)

도형(Primitive)단위로 실행되며, 입력된 점/선/삼각형을 받아 새로운 정점이나 도형을 추가하거나 버릴 수 있다.

 

6. Rasterization

벡터 기반의 도형(삼각형)을 픽셀(Fragment) 단위로 잘라낸다.

→ 이 픽셀이 삼각형 안에 들어가는지를 검사하여 픽셀을 생성.

 

7. Fragment Shader (Pixel Shader)

각 픽셀에 대해 실행된다. 픽셀의 색상, 텍스쳐, 조명 계산을 담당한다.

 

8. Color Blending

여러 fragment가 같은 픽셀에 겹칠 수 있으므로, 최종적으로 색상을 어떻게 합칠지 결정한다.

  • 투명도, 빛 효과 등을 계산한다.

 

9. Framebuffer

최종적으로 계산된 픽셀 색상들이 저장되며, 모니터에서 보는 최종 화면이다.

 

■ 카메라 공간

카메라는 자신이 출력할 화면의 해상도 즉, 크기 정보(뷰포트 - Viewport)를 가지고 월드의 일부를 그려낸다.

 

카메라에 설정된 뷰포트 정보를 바탕으로 월드 공간의 일부분을 렌더링 하기 위해서 카메라를 중심으로 물체의 트랜스폼을 재조정하는 작업이 필요한데, 카메라 중심으로 변환된 공간을 뷰 공간(View space)라 한다.

[로컬 공간, 월드 공간, 뷰 공간의 개요]

카메라를 중심으로 물체 좌표를 조정하기 위해선, 원점과 카메라가 떨어진 상대적 거리만큼 물체의 위치에 더하면 최종 좌표를 얻을 수 있다.

[카메라를 중심으로 물체 위치 계산]

카메라의 위치를 기준으로 측정한 월드 원점의 상대 좌표(10,10)은 월드 공간에서 측정된 카메라의 위치를 반전시켜 알 수 있다.

  • 이는 이동 행렬의 역행렬을 사용해 계산하며, 카메라에 트랜스폼이 설정된 경우, 이동 행렬의 역행렬을 계산하면 뷰 행렬이 된다.

$$ V =\begin{bmatrix}1&0&-t_x \\ 0&1&-t_y \\ 0&0&1 \end{bmatrix} $$

뷰 행렬과 모델링 행렬을 곱한 행렬 $VM$은, 로컬 공간을 뷰 공간으로 변환하는 기능을 수행한다. $VM$에 메시의 정점을 곱하면, 모든 정점의 위치는 카메라를 중심으로 재배치된다.

$$ v_{view} = V\cdot M\cdot v_{local} $$

728x90

'게임수학' 카테고리의 다른 글

[게임수학] 6.삼각형(Mesh)  (0) 2025.09.20
[게임수학] 6-2. 투영 벡터  (0) 2025.09.12
[게임수학] 6-1. 내적(Dot product)  (0) 2025.09.12
[게임수학] 5.아핀공간  (1) 2025.09.08
[게임수학] 4. 행렬  (1) 2025.09.05
'게임수학' 카테고리의 다른 글
  • [게임수학] 6.삼각형(Mesh)
  • [게임수학] 6-2. 투영 벡터
  • [게임수학] 6-1. 내적(Dot product)
  • [게임수학] 5.아핀공간
브라더스톤
브라더스톤
유티니, C#과 관련한 여러 정보를 끄적여둔 블로그입니다. Email : dkavmdk98@gmail.com
  • 브라더스톤
    젊은 프로그래머의 슬픔
    브라더스톤
  • 전체
    오늘
    어제
    • 개발 노트 (37) N
      • Unity,C# (28) N
        • Unity 정보 (5)
        • 알고리즘 (11)
        • 자료구조 (3) N
        • 절차적생성(PCG) (9)
      • 게임수학 (9)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

    unity
    PerlinNoise
    알고리즘
    아핀공간
    pcg
    게임수학
    절차적던전생성
    경사로이동
    최단경로찾기
    기저벡터
    ProjectOnPlane
    정렬알고리즘
    BSP
    자료구조
    절차적지형생성
    앞뒤판별
    이진공간분할
    시야판별
    이동변환
    C#
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
브라더스톤
[게임수학] 7. 게임 엔진
상단으로

티스토리툴바