센로그
2. Game Engine Architecture (2) 본문
▶ Scene Optimization Layer
실행중에 적절히 씬을 최적화하기 위한 목적
몇가지 자주쓰이는 씬 최적화 기법이 있음
- Frustum Culling
- Spatial subdivision
- LOD
▷ Scene Optimizaion Layer - Frustrum cull
카메라 뷰에 비치는 부분만 렌더링
정확히는, 카메라의 뷰 frustum 안에 들어가는 부분만 렌더링하고, 나머지는 불필요하므로 컬링하여 렌더링 과정에서 제외
▷ Scene Optimizaion Layer - Spatial subdivision
vertex들을 공간 단위로 구분해서 각 영역에 포함된 객체들을 관리하는 기법
그러면 뭔가를 찾을 때 이 큐브(구분된 공간) 단위로 순회해서 찾는 것임. (원래는 전체 vertex 다 순회)
이렇게 하면 프러스텀 컬링이나 충돌 감지 등의 작업을 좀 더 효율적으로 수행 가능
공간 분할을 위한 몇가지 방법이 있음
- Binary Space Partitioning (BSP) Tree:
공간을 이진 방식으로 분할하여 트리 구조로 관리합니다. 주로 2D 또는 3D 공간의 분할에 사용됩니다. - Quadtree:
2D 공간을 4개로 계속 분할하는 방식으로, 주로 2D 게임이나 지형 데이터 최적화에 유용합니다. - Octree:
3D 공간을 8개 영역으로 분할하는 방식으로, 3차원 객체들을 효율적으로 관리하는 데 유용합니다. - kd-tree:
공간을 특정 축을 기준으로 분할하는 구조로, 특정 좌표의 분포에 따라 더 효율적인 검색이 가능합니다. - Sphere Hierarchy:
구체 계층 구조를 사용해 각 구체에 포함된 객체를 관리하며, 거리 기반 검색이나 충돌 감지에서 효율적입니다.
언제까지 분할하는 건지 궁금해서 찾아봤는데,
한 구역당 최소 객체 수, 최소 구역 크기, 최대 트리 깊이 등의 종료 조건을 설정 가능하다고 함.
▷ Scene Optimizaion Layer - LOD (Level of Detail)
복잡도를 조절하여 렌더링 성능을 최적화하는 기법.
가까이 있으면, 구체적으로 렌더링. (많은 vertex, 작은 triangle)
멀리 있으면, 간단하게 렌더링. (적은 vertex, 큰 triangle)
보통 하나의 3D 모델에 대해 여러 LOD 버전을 사전에 생성해서 저장해놓고 쓴다고 함.
단, level 변경 시에 popping 현상이 있을 수 있음. (갑자기 퐝 터지면서 나타나는 느낌.)
▶ Visual Effects Layer
우리가 아는 그 머싯는 이펙트
아무래도 게임은 비쥬얼 엄청 중요하니까 많이 쓰게 되겟죠?
따라서 게임엔진에도 구현가능한 여러가지 비쥬얼적 요소들이 있음.
- Particle system
- Decal system
- Lignt mapping and environment mapping
- Dynamic shadows
- Full-screen post effect
당연히 Particle과 Decal은 내가 원하는 형태 만들어서 렌더러에 입력값으로 제공하는 형태이고,
Light Mapping, Environment Mapping, Shadow는 렌더러가 내부적으로 처리해주는 것임
▶ Front end Layer
3D 씬에서 2D 방식으로 렌더링하는 것을 front end 라고 함.
3D 게임을 만들더라도 2D 그래픽들이 필요함
기본적으로는 UI, HUD 같은 게 있음
이외에도, 성능을 위해 3D를 2D로 표현하는 경우들이 있음. (ex: 빌보드)
▷ Front end - HUD (Head-Up Display)
내가 3차원 어느 곳을 보고 있어도 화면 따라 움직이는 UI.
당연히 이런 것들은 2D 렌더링 됨
▷ Front end - Billboard
3D 모델을 여러 방향에서 프로젝션한 2D 이미지를 저장해놓고 이를 방향에따라 렌더링. (항상 카메라를 향하도록)
빌보드: 나무에 리소스 많이 쓸 필욘 없는뎅.. 자연스럽게 하고싶다! 이럴때 사용
[방법]
우선 3D이미지를 각각 방향으로 프로젝션 시킴
→ 카메라의 이동에 따라 적절한 방향에서 프로젝션된 것들이 렌더링됨
→ 2D 이미지를 렌더링하는 것이기 때문에 적은 리소스로 렌더링 가능!
▶ Profiling and Debugging Layer
퍼포먼스에 대해 프로파일링할 수 있도록 게임엔진에서 제공해주곤 함.
메모리 누수 발생하면 메모리 사용량 보면서 얘가 어디서 발생했는지 찾아내야 함
버그가 발견되면 어디서 발생된 건지 알아야 함
=> 프로파일링/디버깅 툴을 이용해 실행중에 추적!!
예를들어 유니티에는 프로파일러, 프레임 디버거 등이 있다.
▶ Collision & Physics Layer
충돌이 감지되면 그에 따른 물리적 반응을 바로 계산해야 되기 때문에, 충돌과 물리 시스템은 강하게 결합되어서 함께 작동함.
충돌 시스템에서 충돌을 판단한 후에, 물리 시스템에서 충돌로 인한 힘과 토크를 처리함(위치 및 속도 업데이트)
▷ Collision & Physics Layer - Ragdoll physics
여러 강체(rigid bodies)를 연결하여 인체 구조의 캐릭터가 현실감 있게 움직이도록 하는 물리 시뮬레이션 기법
관절 연결되어 있는 부분, 최대로 돌아갈 수 있는 각도 .. 등을 고려해 알아서 현실적으로 처리
▶ Skeletal Animation Layer
사람처럼 생긴 메쉬들을 주로 처리함. 사람의 bone들을 다룸
게임에서 사용되는 몇가지 타입의 애니메이션이 있다.
|
그중 Skeletal Animation에 대해 좀 더 알아보겠음
▷ Skeletal Animation Layer - Forward kinematics
매 프레임마다 관절체들 각각의 transform를 정의해서 애니메이션 만듦
관절체들의 상대적인 위치가 필요함.
ex)
어깨 → 팔꿈치 → 손목
직접 하나하나 돌리고 움직여줘야 함
▷ Skeletal Animation Layer - Inverse kinematics
end-effector들의 transform를 기반으로 나머지의 transform들이 알아서 계산됨 (chain 위주로 변화)
뼈에 대한 정보는 있는데, 전부 어디에 있다는 정보는 없음. 단, 끝점의 위치만 있는 거
손이 여기 있고 발이 여기 있대! 그럼 대충 이런 형태로 있는 거 같은데~? 하고 나머지 관절체의 정보를 역산해주는 것.
각각의 최대 회전값 같은 걸 수식으로 넣어두고, 최적의 값으로 찾는 것임
VR에서도 사용. 손/발 센서를 통해 나머지는 이렇게 생겼을거야! 하고 렌더링
ex)
손목 → 팔꿈치 → 어깨
손목 움직이면 알아서 적절하게 딸려옴
▷ Skeletal Animation Layer - Additive animation
서로 다른 애니메이션을 결합한 것
걷기 anim + 장전 anim → 걸으면서 장전 anim
▶ HID(Human Interface Devices) Layer
키보드, 마우스 등의 입력을 받는 부분을 게임엔진에서 지원해줌
생각보다 input을 직접 받으려면 복잡함. 그러나 게임엔진에서 다 알아서 받아주니까 ㄱㅊ~
▶ Online Multiplayer Layer
멀티 플레이, 네트워크 관련도 게임엔진에서 보통 지원해줌
멀티 플레이는 Device 별 FPS도 고려해줘야 하고, 서로 Sync도 잘 맞춰줘야 하고... 암튼 구현하기 어려움
그래도 게임 엔진에서는 이런 걸 지원해줘야 하기 때문에, 그나마 쉽게 하기 위한 패키지들을 제공하곤 함.
참고로 멀티 플레이에는 아래 세 가지 종류가 있음
- Single-screen multiplayer
물/불 게임처럼 한 화면으로 같이 하는거 - Split-screen multiplayer
화면 분할해서 같이 하는거 - Networked multiplayer
우리가 아는 멀티. 네트워크 통신하며 같이 하는거
▶ Gameplay Foundation Layer
게임에서 일어나는 Action들을 처리해주는 부분. Event, Script...
여기서부터는 우리가 실제 게임 만들 때 건드릴 부분들임!
Event system과 Scripting system이 여기에 들어가있음.
- 유니티에서 우리는 스크립트를 짜서 기능을 구현하곤 함.
즉, 실제 게임 플레이시 게임이 어떻게 동작하고, 어디서 이벤트가 발생하고, 플레이어 능력치관련 구현.. 이런 것들을 여기서 처리함
- 예를들면 물체 옮기고, 돌리고, .. 이런 것도 쉽게 할 수 있도록 지원해줌 (옛날엔 직접 vector값 넣어서 했어야 함)
Gameplay foundations는 게임플레이 코드와 저수준 엔진 시스템 사이의 중간 계층 역할을 함.
- 예를 들어, 플레이어가 점프하는 동작이 있다면, 점프 동작을 구현하는 게임플레이 코드와 실제로 캐릭터의 위치를 조정하는 물리 엔진이나 애니메이션 시스템 간의 상호작용이 필요함.
이때 gameplay foundations 계층이 양쪽을 연결해 주는 것임.
▷ Gameplay Foundation Layer - Event system
Event system은 객체들이 이벤트(또는 메시지)를 통해 독립적으로 통신하는 시스템
이벤트는 Event handler function에게 넘어감
나중에 처리할 수 있게 queue에 저장될 수 있음
▷ Gameplay Foundation Layer - Scripting system
Scripting system은 게임의 특화된 게임플레이 규칙과 콘텐츠를 보다 쉽게 개발할 수 있도록, 스크립트 언어를 사용해 실행을 자동화하는 시스템
언어의 두 가지 방식
- Compiler
소스코드를 컴파일해서 기계어로 바꿔서 실행 - Interpreter
소스코드를 기계어로 변환 안하고, 중간에 인터프리터 핸들링해주는 친구가 받아서 한줄씩 실행
게임 엔진의 스크립팅 시스템은 보통 인터프리터 방식
컴파일러의 경우 변경이 생길 때마다 새로 컴파일하고 링크해야 하는데
인터프리터는 바뀐 블록만 새로 실행해주면 됨. 따라서 실시간으로 변경하고 테스트할 수도 있음
- 장점 : 행위에 대한 결과를 빨리 볼 수 있음.
- 단점 : 디버깅 어려움
※ 언리얼 엔진에서는 C++, Blueprint 두 가지 방식의 스크립팅 시스템 지원 블루프린트는 노드 기준으로 실행되고, 객체지향임. 시각적으로 흐름을 쉽게 볼 수 있음 |
▷ Gameplay Foundation Layer - Artificial Intelligence Foundation
AI 시스템 지원해 줌
NPC 행동, Navigation 같은 거 지원.
게임 만들 때 AI는 많이 쓰일 수밖에 없음!
▶ Subsystems Layer
게임 특유의 기능과 규칙을 구현하는 시스템
Terrain 렌더링, Water 시뮬레이션, 플레이어 Movement, Camera 설정, AI Path Finding(A*), ...
게임 엔진 구조의 맨 윗단.
게임 자체의 특징을 구현하는 부분
'게임 > 게임 엔진 기초' 카테고리의 다른 글
6. Game Engine Support System (2) (0) | 2022.12.08 |
---|---|
5. Game Engine Support System (1) (1) | 2022.12.08 |
4. Object-oriented programming (2) (0) | 2022.12.07 |
3. Object-oriented programming (1) (0) | 2022.12.07 |
1. Game Engine Architecture (1) (1) | 2022.12.07 |