언리얼 엔진의 분할 화면 오디오
대부분의 작업자가 직관적으로 이해하는 이 기능의 작동 방법은 실제로 이 기능이 어떻게 작동하고, 어떤 방식으로 작동해야 하는지와 상당히 달랐습니다. 게임 오디오 커뮤니티에서 이 주제에 대해 놀라울 정도로 많은 관심을 보여주었기 때문에, 언리얼 엔진에서 화면 분할 오디오의 작동 방식에 대한 기본적인 소개를 제공하기 위해 이 개발자 기술 블로그를 작성하게 되었습니다.
화면 분할 게임의 배경
화면 분할 게임플레이는 최근 업계에서 다시 각광받고 있는 추세입니다. 화면 분할 방식은 콘솔 네트워크가 지원되기 전까지 초기 멀티플레이 게임에 많이 사용되었습니다. 저 역시도 10대 시절에 친구 집에서 피자를 먹으며 밤새 골든아이(Goldeneye)나 헤일로(Halo) 같은 화면 분할 게임을 즐겨 했던 것이 생각납니다. 광대역 인터넷을 지원하는 첫 콘솔이 나오기 시작하면서 화면 분할 지원은 서서히 사라졌습니다. 그런데 이 기능이 점점 다시 사용되고 있습니다. 사람들은 온라인으로 여럿이서 플레이하는 *것뿐만 아니라* 친구들과 직접 만나서 함께 게임하는 것을 좋아합니다.다행히도 언리얼 엔진은 최대 4개의 화면 분할을 지원합니다. 대부분의 게임은 로컬 코옵 플레이 및 원격 네트워크 멀티플레이 모드를 지원하는데, 포트나이트에서도 이를 지원하고 있습니다. 친구들을 초대해 같은 콘솔을 공유하면서 전 세계에 있는 다른 친구들과 플레이할 수 있습니다.
언리얼 엔진에서 분할 화면을 구현하려면 로컬 멀티플레이어(Local Multiplayer) 세팅 탭에서 프로젝트 세팅 옵션을 활성화하고 원하는 화면 분할 모드를 선택하면 됩니다. C++ API를 사용하면 모드를 커스터마이징하거나 더 많은 기능을 활용할 수 있습니다.
화면 분할 게임의 어려움
분할 화면을 구현하는 것은 게임 프로젝트 옵션만 켜고 모든 기능이 제대로 작동하기를 바랄 수 있을 만큼 간단하지 않습니다. 월드에 더 많은 시점을 추가하려면 더 많은 오브젝트를 렌더링해야 하며 컬링의 기회는 줄어들게 됩니다. 즉, 더 많은 요소를 사용하고 로드해야 하며 가비지 콜렉터에서 이를 더 많이 참조해야 합니다. 이렇게 과도한 작업을 수행하면 게임 엔진의 거의 모든 하위 시스템에 부담을 주게 됩니다.한편, 오디오 측면에서는 흥미로운 일이 벌어집니다.

직관적인 것이 항상 적합한 것은 아니다
동료 개발자들과 대화를 나눠보면 대부분 직관적으로 이해하기로는 각 분할 시점의 오디오에서 개별 플레이어, 즉 리스너가 들을 수 있는 오디오가 렌더링될 것으로 기대하는 것 같습니다. 물론, 플레이어 1 바로 옆으로 총알이 날아간다면 그 플레이어에게 소리가 크게 들려야 할 겁니다. 하지만 멀리 떨어져 있는 플레이어 2의 시점에서는 소리가 작게 들려야겠죠. 결국 귀를 분할할 수는 없으니 양 플레이어의 시점에서 모든 오디오가 들려야 한다고 생각하실 겁니다. 사실은 그렇지 않습니다.양방향 분할 화면을 위해 오디오 렌더링의 CPU 비용이 2배가 되는 것은 차치하더라도 이 시나리오에서는 끝이 없는 소리로 혼란이 발생할 겁니다. 생각해 보세요. 모든 플레이어가 들을 수 있는 범위 내에서 벌어지는 모든 이벤트는 양방향 분할 화면에서 2배가 됩니다. 3방향, 또는 4방향이라면 4배가 되겠죠. 발자국을 한 번 내디디면 여기저기에서 발자국을 내딛는 소리가 나게 됩니다. 각 리스너가 동일한 소리를 가진 발자국을 동일한 시점에 내딛는 소리를 듣는다면 동일한 각각의 발자국 소리가 중첩되어 갑자기 매우 큰 소리가 들리게 될 것입니다. 총알이 오고 가는 전장이라면 얼마나 큰 혼돈이 빚어질지 생각해 보세요. 모든 총소리가 모든 시점에서 동시에 렌더링되어 들릴 것입니다.
그렇다면 이를 구현하는 올바른 방법은 무엇일까요? 답은 간단합니다. 가장 가까운 리스너를 기준으로 소리를 렌더링하는 것입니다.
언리얼 엔진에서 분할 화면을 처리하는 방법
언리얼 엔진의 솔루션은 매끄럽습니다. 제가 입사하기 전에 개발된 구현 전략이며, 5년 전에 에픽게임즈에 들어와 이 단순하고 훌륭한 솔루션을 접했을 때 감명을 받았습니다. 이론적으로는 다른 곳에서 보았던 방식과 비슷하지만 언리얼 엔진 4의 솔루션은 특히 더 완벽합니다.기본적으로 언리얼 엔진은 모든 사운드 이미터의 위치를 가장 가까운 리스너의 로컬 스페이스 트랜스폼으로 변환합니다. 이렇게 하면 막대한 세부 처리 과정을 간소화할 뿐 아니라 로우 레벨 오디오 렌더러에서 하나의 리스너 트랜스폼에 대해서만 고려하면 됩니다. 이러한 단순함으로 인해 저희의 새로운 멀티플랫폼 오디오 렌더러인 오디오 믹서에는 리스너 지오메트리 표현이 필요하지 않습니다. 모든 사운드 이미터가 항상 오디오 렌더러에 전송되기 전에 로컬 스페이스 트랜스폼으로 변환되기 때문에 모든 소리는 단순히 단위 행렬을 기준으로 공간화되어 렌더링됩니다. 따라서 공간화 코드와 관련된 모든 복잡성이 줄어들고 차세대 공간화 기능을 위한 개발 프로세스를 단순화하여 이와 관련한 비용을 낮출 수 있습니다.
단점
직관적이지는 않지만 가장 근접한 리스너를 기준으로만 소리를 렌더링하는 것이 합리적입니다. 하지만, 이러한 방식에도 단점은 있습니다.- 효과적이지 않은 시점
- 시점이 전환되는 소리의 이동
- 사운드를 많이 렌더링하면 믹스와 우선순위의 밸런스를 깨트릴 수 있다
- 추가 사운드 및 CPU 비용
다수의 엔드포인트
똑똑한 분들은 다른 오디오 엔드포인트, 즉 다른 스피커 세트 또는 다른 컨트롤러 등 별도의 하드웨어 출력에 오디오를 렌더링하면 어떻겠냐고 제안할 수도 있습니다. 일부 콘솔은 이를 지원하며 PC에서는 서로 다른 엔드포인트에 오디오를 렌더링하는 것이 가능합니다.여기에서 전제 조건은 각 분할 화면 시점의 오디오를 렌더링할 수 있으며 플레이어가 헤드폰을 통해 들을 수 있는 다른 하드웨어 출력으로 이를 전송할 수 있다는 것입니다.
그렇지만 이 게시글의 작성 시점에 언리얼 엔진 4.24를 기준으로 UE 오디오 엔진에서는 이러한 기능이 지원되지 않습니다. (4.25에서는 지원할 예정입니다.) 더욱이 이 기능은 모든 플랫폼에서 동등하게 지원되지 않습니다. 따라서 추가적인 오디오 렌더링을 위한 CPU 비용을 낮추려고 했음에도 여러 하드웨어 엔드포인트에 렌더링하는 기능이 없을 경우 여전히 대체 솔루션이 필요합니다. 또한 저 역시 그렇지만, 우리는 종종 친구를 초대해 분할 화면으로 코옵 플레이 게임을 시작하고는 즉시 헤드폰을 끼고 더 이상 서로 말하지 않곤 합니다.
핵심 내용
오디오 분할 화면을 처리하는 과정은 다소 복잡하고 여러 기술적 요소를 고려해야 하는 주제입니다. 그러나 직관적인 방식과는 반대로, 가장 가까이에 있는 리스너, 즉 근접 분할 화면 뷰를 기준으로 오디오를 렌더링한다면 모든 것이 적당히 잘 작동합니다.이 주제에 대한 자세한 내용은 가이 솜버그(Guy Somberg)가 편집하여 곧 출시될 게임 오디오 프로그래밍 원리 및 실습(Game Audio Programming Principles and Practices) 시리즈 3권에서 제가 작성한 단원을 확인하시기 바랍니다.