사이드 프로젝트/Voxel System

[Voxel System] 2025-04-07 에디터 오버헤드와 CombineMeshes

라일라엘 2025. 6. 14. 18:18
반응형

큐브를 가로 100, 세로 100, 높이 15로 쌓으려고 하는데 프레임이 심각하게 떨어지는 문제가 발생했었다.

한 프레임을 연산하는데 약 300ms이라는 시간이 걸렸는데, 프로파일링 해보니 에디터에서 시간을 많이 잡아먹고 있었다. 조사해 본 결과 GameObject가 별다른 컴포넌트를 가지고 있지 않아도, 너무 많이 있으면 Transform을 계산하느라 에디터에 부담이 간다고 했다.

GameObject를 없앨 수 있는 방법을 고민을 해보던 중, CombineMeshes라는 기술로 여러 개의 Mesh를 하나의 Mesh로 묶어서 드로우콜도 줄이고, 게임오브젝트도 줄일 수 있는 방법이 있었다.

이제 여러 개의 Cube가 각각 하나의 메시를 가지고 있는 것을 Chunk라는 클래스에 모든 메시 정보를 넘기고, Chunk는 이 정보를 바탕으로 하나의 메시로 묶는 방식으로 구조를 변경했다. 이때 묶고 난 뒤 Cube의 모든 오브젝트를 꺼버려서 에디터 부하의 감소를 기대했다.

하지만 CombineMeshes로 묶는 과정에서 메시가 null이거나 비어있다면 따로 제거를 해줘야 하는데, 모든 Cube가 Mesh를 가지고 있지 않기 때문에 이를 걸러주는 기능이 필요했다. 또 CombineMeshes는 메시의 정보를 배열의 형태로 받은 다음 파라미터로 넘겨줘야 하는데, 메시가 없는 데이터를 걸러주는 과정에서 배열의 길이가 가변 된다. 따라서 임시로 List의 형태로 만들고 ToArray 함수로 배열의 형태로 만들어주기로 했다.

일단 List를 넘겨주는 방법이 없는지 찾아보고, 없다면 캐싱하는 방식으로 해서 List를 최대한 복사하지 않는 선에서 ToArray로 파라미터를 넘겨줘야겠다.

이 외에도 여러 가지 최적화 기법을 찾아봤는데, MarchingCubes는 런타임에 메시가 변경되기 때문에 오클루전 컬링은 사용할 수 없고, 유니티에서 제공하는 LOD도 사용할 수 없다. 따라서 카메라의 거리에 맞춰 LOD를 처리하는 것을 직접 구현해야 했는데, 이는 조금 시간이 걸릴 것 같다.

728x90
반응형