수백만을 위한 물리 엔진 확장
작성자 : 케빈 헤(Kevin He) 작성일 : 2012 년 7 월 12 일
[블리자드의 물리 담당이자 지금은 온라인 게임 로블록스의 네트워크 책임자인 케빈이 강체(rigid body) 시뮬레이션의 비밀을 공유한다. 레고 형식의 조립 게임에서 동시에 수백만 명의 플레이어를 수용하면서도 성능과 재미 어느 것도 희생하지 않는 방법을 살펴본다.]
<로블록스(Roblox)>는 종합적인 물리 엔진(physics engine)을 기반으로 하고 있으며, 수백만의 유저들은 그 능력의 한계를 시험하기라도 하듯 계속하여 콘텐츠를 생산해 내고 있다. 우리는 유저들의 무한한 창의력에 부응하기 위해서, 그리고 유저들의 거대하고 복잡한 시뮬레이션에 대한 열망을 충족하기 위해서는 물리 엔진 최적화에 헌신적인 노력을 기울여야 했다.
<로블록스>는 강체에 작용하는 물리 현상을 모두 시뮬레이션한다. 유저들이 벽돌, 블록, 쐐기, 구, 원통 등에 기초하여 스스로 게임을 만들어 내기 때문이다. 이런 요소들은 실제 세계에서와 똑같은 방식으로 행동함으로써 학습곡선을 완만하게 만드는 효과를 가진다.
유저들은 거의 모든 장르의 게임을 만들어 낼 수 있게 되며, 발견 가능성이라는 측면도 더한다. 이런 특징으로 인해 2011 년에만 게임플레이 시간 2 억 5 천만 시간을 달성했다.
복잡한 물리 시뮬레이션이 그 자체로 좋은 게임을 만들지는 못하며, 오히려 자원의 낭비가 될 수도 있다는 점은 짚고 넘어가야 한다. 오히려, 물리 엔진의 복잡성은 게임 플레이의 요구사항에 가깝다고 할 수 있다.
<로블록스>의 물리학 - 맥락적 접근
<로블록스>는 게임에 있어 물리 복잡성 스펙트럼의 극단적 위치에 자리하고 있다. 다른 쪽 끝에는 <에버퀘스트>나 <월드 오브 워크래프트> 같은 MMORPG 가 있다. 이런 게임들은 기본적인 충돌 검출(collision detection)을 도입해 플레이어들이 유효 영역 밖으로 넘어가지 못하게 한다.
<헤일로(Halo)> 등의 일인칭 슈팅게임, <디아블로 3>와 같은 액션 RPG 는 충돌 검출을 한 단계 더 발전시켜 접촉력과 제한적인 충돌 도형(캡슐과 같은)을 사용해 충돌 반응을 만들어낸다. 이들 게임은 또한 캐릭터에 ‘수동적' 랙돌(ragdoll) 상태를 도입하여 사망 후의 쓰러짐, 폭발로 인한 반동과 낙하를 랙돌 상태로 처리한다. 그리고 ‘장식적' 랙돌을 사용하여 - 머리카락의 움직임과 같은 - 동적인 시각효과를 만들어 낸다.
물리 시뮬레이션이 흥미롭고 복잡해지는 시점은 스포츠 게임이다. MMORPG 와 액션게임에서 볼 수 있는 것들에 더하여, <파이트 나이트(Fight Night)>이나 <FIFA 12>같은 스포츠 게임에서는 격투선수와 축구 선수의 관절에 구동부(motor)가 실제 힘을 가하는 ‘능동적' 랙돌을 도입한다. 이런 방식은 부드럽고 생동감 있는 동작과 애니메이션을 만들 수 있게 한다. 이 방식에서 구동부가 없다면, 격투가와 선수의 사지는 생기없이 매달려 있게 되고, 캐릭터는 지면으로 쓰러져 버릴 것이다.
마지막으로, <로블록스>가 자리한다. 완벽한 물리 시뮬레이션이 기본적으로 활성화되어 있으며, 예외적으로만 비활성화되는 게임이다. 지면을 제외한 모든 물리적 물체가 시뮬레이션된다. 엔진의 기능은 다음과 같다.
● 접촉력이 작용하는 충돌검출, 풍부한 충돌 도형(육면체, 구, 원통, 쐐기, 볼록다면체 외 다수)
● 강체 역학, 단일 파이프라인 힘 적분 (중력, 접촉력, 마찰력, 관절/용수철, 부력, 항력, 운동에너지)
● 물리 기반 캐릭터 애니메이션, “수동” 및 “능동” 랙돌, 균형 제어 (서기, 달리기, 뛰기, 낙하, 수영 지원)
● 기계적 탑승물과 배, 다양한 관절 타입 (운동학, 경첩, 결합, 로프, 다각기둥, 회전, 구동 등) ● 부력과 진보한 액체 역학
이들 기능은 모두 네트워크를 통한 멀티플레이어 환경에서 동작한다.
개별에서 총체로
조립 블록을 접한 사람들은 대부분 블록을 최대한 많이 사용해 뭔가 거대한 것을 만들려고 한다. <로블록스>도 예외는 아니어서 고층건물이나 타이타닉 규모의 함선의 구성 부속을 각기 개별적인 강체로 시뮬레이션하려면 네트워크와 CPU/GPU 자원의 소모가 엄청날 것이다.
<로블록스>의 엔진에선 거대한 구조물과 탑승물을 시뮬레이션하는 데 영리한 방법을 사용했다. 고층건물이 지면에 고정되어 움직이지 않는다면, 이 건물은 배경과 결합된 단일 개체로 취급된다. 개별 벽돌에는 동적인 시뮬레이션이 수행되지 않고, 고층건물 전체와 다른 물체와의 충돌 검출만 수행된다. 엔진은 메모리를 적게 소모하도록 전체 고층건물을 정적인 “경량급(featherweight)” 물체로 압축한다. “경량화” 덕분에 최소한의 비용으로 <로블록스> 세계에 수천 개의 복잡한 빌딩을 넣을 수 있었다.
타이타닉 규모의 함선이 항해하는 상황에서는 전체 함선이 동일한 강체 역학 엔진에서 구동되어야 물과의 상호작용 및 다른 부유물과의 충돌을 사실적으로 시뮬레이션할 수 있다. 각 함선의 구성 요소를 개별 강체로 취급하여 시뮬레이션하면 엄청난 비용이 필요하기에, <로블록스> 는 그러한 거대한 결합된 강체는 “어셈블리(Assembly)” 1 로 시뮬레이션하여 시뮬레이션에 소요되는 자원을 더 효율적으로 관리한다.
<로블록스> 는 한 프레임 동안 서로 상대적으로 움직이지 않는 물체 쌍을 동적으로 식별한다. 그러한 물체는 하나로 그룹 지어 어셈블리를 형성하게 된다. 타이타닉 규모의 함선이 천 여 개 이상의 부속이 결합되어 있을지라도 어셈블리로 구성되어 있다면 단일 강체로 시뮬레이션 한다. 물리 시뮬레이션을 수백만 이상의 요소로 확장하고자 할 때에는 이런 식의 효율성이 필요하다.
이 경우에 두 요소는 어셈블리를 형성한다. 한 프레임의 동작 동안 그 둘이 서로 상대운동을 하지 않기 때문이다.
어셈블리가 만능은 아니다. 구현된 어셈블리는 나름의 과제를 안고 있다. 끊임없이 운동, 충돌, 폭발, 인간의 개입이 이루어지는 동적인 환경에서 어셈블리는 언제든지 구성되고, 쪼개지고, 합쳐질 수 있다. 흔히 벌어지는 상황은 다음과 같다.
● 결합된 요소는 충분한 이탈력이 가해지면 분리될 수 있다.
● 분리되어 있던 물체는 한쪽 물체의 “입구”와 다른 물체의 “출구”가 접촉하면 런타임에 하나로 결합될 수 있다.
● 인간형 캐릭터가 죽을 때, 검으로 공격당한 경우라 할지라도 관절이 분리되면 신체가 절단될 수 있다. ● 유저가 LUA 스크립트를 사용하여 두 요소 사이에 관절을 추가하거나 제거하여 어셈블리를 동적으로 합치거나 분리할 수 있다.
우리 엔진은 이런 변화가 생길 때 끊임없이 형성되는 어셈블리를 클라이언트와 서버 간에 실시간으로 동기화해야 한다. 이때 클라이언트와 서버가 동일한 물체를 루트(root body)로 선택해2 어셈블리를 생성하여 네트워크를 통한 동작을 부드럽게 보이도록 한다.
중앙 처리에서 분산 처리로
어셈블리와 더불어, 물리 시뮬레이션을 중앙 처리에서 분산 처리로 전환함으로써 더 많은 플레이어와 더 많은 물리 시뮬레이션을 수용할 수 있는 공유 공간을 만들 수 있었다. 초창기에 <로블록스>는 물리 시뮬레이션을 중앙 처리방식으로, 즉 하나의 게임 서버에서 물리 계산이 처리되고 그 결과가 플레이어에게 전달되어 화면에 표시되는 모델을 사용하였다.
작은 규모, 즉 적은 수의 플레이어, 물리 연산, 시뮬레이션 요소들만 있는 상황에서는 중앙처리 방식이 잘 작동한다. 하지만 <로블록스> 에서 구현된 중앙 처리 모델로는 게임의 성장과 함께 놀랍도록 복잡해진 물리 연산을 감당할 수 없었다. 서버가 너무 많은 요소와 플레이어의 조작을 시뮬레이션해야 하는 상황이 오자 움직임이 실시간으로 돌아가지 않게 되었다.
이 문제는 2010 년에 중앙 처리 엔진을 분산 물리 엔진으로 발전시킴으로써 해결되었다.
이 그림은 분산 물리 엔진 모델을 간략히 보여준다. 실제로는 클라이언트에서 시뮬레이션되는 영역의 모양은 항상 동일하지 않다.
분산 물리 연산은 물리 시뮬레이션을 서버와 플레이어 모두에게 분배한다. 위 그림에서 파란 영역은 서버(서버 시뮬레이션 영역)와 물리적 물체 및 플레이어 전부를 포함한다. 어떤 영역 안에 플레이어가 전혀 없을 때는 서버에서 물리 시뮬레이션을 처리하여 플레이어게 전달하는데, 여기까지는 중앙 처리 모델과 같은 방식이다.
차이점은 각 플레이어가 물리적 대상의 동적 영역을 가지고 있다는 점이다. 각 플레이어가 근접한 영역(클라이언트 시뮬레이션 영역)의 시뮬레이션을 로컬에서 수행하여 서버의 부하를 줄여준다. 이러한 분산 아키텍쳐로 거의 무한정에 가까운 수의 물체에 작용하는 물리 현상을 성능 저하 없이 시뮬레이션 할 수 있게 되었다.
여기에 로드 밸런싱 알고리즘을 구현하여 각 플레이어의 연산 능력과 대역폭에 따라 영역 크기를 늘리거나 줄일 수 있도록 하였다. 하드웨어나 인터넷 회선이 느린 플레이어는 일반적으로 더 적은 수의 물체를 시뮬레이션 하게 되며, 빠른 회선과 최신 장비를 갖춘 경우는 그 반대이다. 분산 물리 연산의 핵심 과제는 두 플레이어 영역의 경계에 있는 물체를 시뮬레이션하는 방법이다.
※ 자세한 내용은 첨부(PDF)화일을 참고하시기 바랍니다.
|