마인크래프트 짭겜 개발노트 #1 "청크"

개발노트

2018. 10. 25. 02:29

마인크래프트는 많은 사람들이 알다시피 심리스 오픈월드이고

넓은 월드를 청크라는 단위로 나누어서 관리한다.

이미지 출처 : 마인크래프트 공식 위키

마인크래프트 위키에 의하면 청크 하나의 크기는 16 x 256 x 16 이라고 한다.

(참고로 16 x 256 x 16 = 65536 = 2^16)

청크의 높이를 게임 상 최대높이로 설정해서 청크의 위치를 2차원 좌표로 표현하려는 의도일 것이다.


무한히 넓은 월드를 일정한 크기의 단위로 나누어서 관리하는 것은 너무나도 당연한 일이다. 

그러지 않고서는 그 큰 월드를 표현할 수 있는 방법은 생각할 수가 없다. 

그래서 마인크래프트가 월드를 청크라는 단위로 나누어서 관리한다는 것 자체는

딱히 엄청 특별한 얘기는 아니다.


하지만 그것 외에도 청크를 사용해만 하는 이유는 더 있다.


마인크래프트의 세계는 블록으로 이루어져 있다. 그럼 이것을 어떻게 구현하면 좋을까?


먼저 'Block' 이라는 정육면체 오브젝트를 프리팹으로 만들고 각 면에 텍스쳐를 바를 수 있게 한 다음,

적절한 위치에 적절한 텍스쳐를 입혀서 배치하는 방식을 생각해 볼 수 있다.

하지만 해 보면 알겠지만 (굳이 안해봐도...) 청크 하나 분량, 즉 65536개의 블록조차도 모두 표현할 수가 없다.

막대한 양의 블록 오브젝트들과 무수한 버텍스들이 컴퓨터를 혹사시키기 때문이다.


그리고 차마 눈 뜨고 볼 수 없을 만큼 기괴하게 치솟는 드로우콜 수...

각 블록들은 서로 다른 텍스쳐가 입혀져있기 때문에 블록을 생성하면서 텍스쳐를 바꿔줄 때마다 새 머테리얼이 필요할 것이다.

하나의 블록은 최대 6개의 서로다른 텍스쳐를 바를 수 있으므로 블록당 최대 6개의 머테리얼이 필요하다.

그러면 드로우콜은 최악의 경우 65536 x 6 이 될 것이다...


결론적으로 이 방식은 잘못되어도 한참 잘못되었다.

어떻게 하면 '65536 x (수십개의 청크) = 어마무시한 수의 블록'들을 한꺼번에 그릴 수 있을까?


3D 그래픽 최적화를 할 때 가장 먼저 생각해야 할 것은 버텍스 수를 줄이고, 메쉬와 머테리얼의 수를 줄이는 것이다.

버텍스 수를 줄이는 방법은 일단 미뤄두고 먼저 메쉬와 머테리얼 수를 줄이는 방법을 생각해 보자.

- 메쉬를 줄이는 법 : 같은 머테리얼을 공유하는 얘들끼리 하나로 통합.

- 머테리얼 (드로우콜)을 줄이는 법 : 텍스쳐 아틀라스.


그리고 청크를 사용하면 위의 두 목적을 모두 달성시킬 수 있다. 즉,

- 청크에 속한 블록들을 따로따로 그리지 말고 모두 하나의 청크메쉬에 그린다.

- 블록 텍스쳐들을 하나의 텍스쳐 아틀라스로 묶어서 청크의 머테리얼에 적용하고 사용한다.


이렇게 하면 청크에 적용된 머테리얼 수가 n개라면 드로우콜을 n으로 줄일 수 있고

동적으로 생성해야할 게임 오브젝트들의 수도 현저히 줄어들기 때문에 엄청난 최적화 효과를 볼 수 있다.

모든 블록들이 하나의 머테리얼을 공유할 수 있도록 텍스쳐들을 하나의 아틀라스로 묶고,

또 블록 메쉬들을 청크메쉬 하나로 통합한 것이다.


따라서 청크를 사용하는 것은 월드를 동적으로 로딩하는 것 외에도 다음과 같은 장점들이 있기 때문이다.

2. 게임 오브젝트의 수를 줄일 수 있다.

3. 메쉬 수를 줄일 수 있다.

4. 머테리얼 (드로우콜)을 줄일 수 있다.

5. 그것도 엄청난 스케일로 아주아주 많이!