Escape Brawl - GPU Instancing을 이용한 Boids Simulation
기획 수정 전, 50마리 이하의 작은 군집을 이용할 예정이었기 때문에
GPU Instancing을 사용하지 않고 Boids Simulation을 구현
GitHub - JEIHAA/Flock-Study: Flocking Algorithm Study from <Board To Bits Games>
Flocking Algorithm Study from <Board To Bits Games> - JEIHAA/Flock-Study
github.com
https://github.com/JEIHAA/GPU_FlockAlgorithm
기획이 수정된 후 GPU Instancing에 대해 공부하며 자료를 따라 구현해보았음.
참고자료
GitHub - IndieVisualLab/UnityGraphicsProgramming: 書籍「UnityGraphicsProgramming vol.1」のサンプルコードリポジト
書籍「UnityGraphicsProgramming vol.1」のサンプルコードリポジトリ. Contribute to IndieVisualLab/UnityGraphicsProgramming development by creating an account on GitHub.
github.com
GitHub - elvismd/unity_gpu_instancing: Example of how to use Graphics.DrawMeshInstancedIndirect for instancing rendering
Example of how to use Graphics.DrawMeshInstancedIndirect for instancing rendering - elvismd/unity_gpu_instancing
github.com
게임의 핵심 자원인 군집을 제대로 활용하기 위해서는 렌더링만 하는 것이 아닌 각 개체가 플레이어와 상호작용이 가능하며 네트워크 상에 반영되어 군집의 상태를 각 플레이어들이 알 수 있어야함.
결국 Compute Shader로 물리 연산을 구현해야 했는데, 하나하나 직접 구현한다면 기간 내에 끝마치기 어려울 것으로 판단되어 Renderer 없이 BoxCollider만 가진 Game Object를 생성하여 군집이 렌더링되고 있는 위치와 동기화하였음.
게임 오브젝트와 렌더링된 그림의 위치를 동기화 하여 충돌 연산이 가능해졌고,
군집이 닿은 플레이어에게 종속되도록 했음.
그런데 개수가 많아지자 프레임이 심각하게 떨어지기 시작함.
20번대 그래픽카드로 돌렸을 때는 7~9프레임이 나옴.
아래 움짤은 3060Ti 노트북으로 돌렸을 때.
결국 맵이랑 합치니까 10~20프레임대로 떨어짐.
유니티 프로파일러로 확인해본 결과
렌더링된 군집의 위치와 생성된 Game Object의 위치를 동기화하기 위해 작성했던 코드가 문제.
1. 매 프레임마다 모든 군집의 데이터를 GPU에서 CPU로 전달받음
2. 실시간으로 변경되고 있는 Game Object의 위치를 다시 GPU로 넘겨줌
이 때문에 극심한 오버헤드가 발생함
매 프레임마다 수백 개의 데이터를 받아오던 것을
1프레임당 32개씩 쪼개서 받아오도록 수정하여 데이터 전송 빈도를 줄임
CPU 사용량 76.5% -> 21.4%로 최적화됨