2019년 7월 22일
RWU 학생이 언리얼 엔진으로 수천 개의 큐브를 동시에 아름답게 애니매이션화한 방법
이 과제에는 제한이 없었기 때문에 저희는 이야기를 추상적인 작품이나 심지어는 2D 애니메이션으로도 만들 수 있었습니다.
예전에도 언리얼 엔진으로 작업을 해왔고, 엔진이 출시되었을 거의 초기 단계부터 개발 관련 업데이트 소식을 접해온 저는 이 과제를 첫 리얼타임 영화를 제작할 기회로 삼아야겠다고 마음먹었습니다.
평소에도 저는 각각 최소한의 기능만 지닌 단순한 셰이프나 지오메트리가 충분한 양으로 모여있을 때 전체적으로 상세한 디테일을 갖춘 그림을 묘사할 수 있다는 사실에 흥미를 갖고 있었습니다.
픽셀은 색이나 강도를 변경하는 역할밖에 수행하지 못합니다. 제가 제작한 버추얼 3D 큐브가 할 수 있는 것은 위, 아래로 움직이는 정도가 전부라고 할 수 있죠. 이는 큐브의 양을 조절하여 시각적인 차이를 만들어내는 것에 그칠 뿐이었습니다.
저는 단순하고 정적인 큐브를 사용해 미래지향적으로 보이는 핀 테이블을 만드는 실험을 시작했고, 동색 회로판과 유사한 디자인을 떠올렸습니다.
이제까지 원해왔던 스타일을 정한 다음, 큐브들의 움직임을 연산할 수 있는 시스템의 프로토타입을 만들었습니다.
저에게 필요했던 시스템 요구사항은 다음과 같습니다.
- 동시에 수천 개 큐브의 움직임을 연산
- 랜덤/노이즈, 특정 움직임 허용
- 에디터에서 안정적으로 작동할 수 있도록 퍼포먼스에 대한 영향 최소화
- 편리한 사용과 미세조정(이것이 무엇보다도 중요했습니다)
일반적인 방식으로 애니메이션시키거나 블루프린트를 사용해 수십 개의 큐브를 움직일 수는 있었겠지만, 저는 퍼포먼스의 큰 손실 없이 특정 신(Scene)에서 최대 55만 개의 큐브를 역동적으로 움직일 방법은 셰이더 솔루션뿐이라는 사실을 알고 있었습니다.
우선 저는 인스턴싱을 통해 샷에 따라 원하는 해상도를 얻을 수 있도록 2만 5,600개의 큐브로 핀 테이블을 생성했습니다. 큐브의 바닥면은 보이지 않기 때문에 퍼포먼스 향상을 위해 제거했습니다.
윗면과 아랫면에 다른 버텍스 컬러를 할당하여 이동 가능한 부분을 마스크 아웃함으로써 큐브 윗면만 움직이고 바닥면은 그대로 있도록 만들 수 있었습니다.
텍스처로 움직임을 주도하려면 4개 버텍스 전부가 UV 공간의 한 점에 매핑되고 0-1 공간에 균등하게 뿌려지도록 UV 맵을 생성하는 것이 중요합니다.
이렇게 해야 4개의 점을 모두 똑같이 움직이게 할 수 있습니다. 그렇지 않으면, 이 점들은 각 점마다 다른 픽셀을 샘플링하기 때문에 상부가 평평하지 않게 될 수도 있습니다.
머티리얼 에디터에서 VertexColor 노드의 출력값을 Lerp 노드의 알파값으로 두어 선형보간을 통한 마스크로 사용합니다.
Lerp 노드의 출력을 Constant3Vector(0,0,1) 노드와 곱하게 되면 혹시 모를 X, Y축 방향의 이동이 제거되며 위, 아래 방향으로만 움직이게 됩니다.
Clamp 노드로 결과값을 최소 0으로 제한하여 베이스 레벨 밑으로 움직임지 않도록 만들었습니다. Clamp 노드 출력이 월드 포지션 오프셋(World Position Offset)으로 들어가면 기본 프레임워크가 끝납니다.
여기서부터 재미있어집니다. Lerp 노드의 A 입력은 이 프로젝트에서 가장 창의력을 발휘해야 하는 부분이라고 할 수 있습니다. 준수해야 할 엄격한 규칙은 없으며, 다음과 같이 다양한 형태의 접근법을 시도해보는 것이 중요했습니다.
- 텍스처를 U와 V 방향으로 스케일 조절
- 텍스처 회전 또는 패닝
- Time 노드와 Sine 노드 활용
- 여러 핀보드에 걸쳐 지속적인 움직임을 만들도록 월드 정렬 텍스쳐(World Aligned Texture)로 변경
월드 파라미터 컬렉션을 사용하여 실제 움직임을 만들기 위한 시퀀서의 키프레임 작업은 뒤로 미룰 수 있었습니다.
드라마틱한 장면을 만들기 위해 디렉셔널 라이트와 다이나믹 스카이라이트는 각각 0.17lux와 0.1cd/m²로 상대적으로 낮은 강도를 사용하였습니다. 이는 반사 표면에 이미 빛 산란이 표현되고 있기에 충분한 수치였습니다.
일부 신에서는 필요한 경우 스포트라이트나 포인트라이트를 사용해 작은 하이라이트를 만들었습니다.
그 다음, 시네마틱 카메라로 장면을 미세조정하고 정밀하게 다듬었습니다. 뎁스 오브 필드를 광범위하게 사용하여 큐브의 크기와 양을 시각적으로 개선했습니다.
다음 단계는 시퀀서 내에서 여러 샷을 구성하고 모션 키프레임을 잡는 것이었습니다. 저는 오디오를 임포트하고 시퀀서에서 다양한 자리표시용 샷을 생성하는 작업부터 시작했습니다.
다음으로 적절한 카메라 각도를 찾고 월드 파라미터 컬렉션에 저장된 머티리얼 파라미터를 키프레임했습니다. 언리얼 엔진 4의 카메라 릭 레일과 크레인은 카메라 자체의 안정적이면서 흥미로운 움직임을 표현할 때 많은 도움이 됐습니다.
언리얼 엔진 4를 활용해 이 프로젝트를 만드는 작업은 정말 놀라운 일이었습니다. 엔진에서 제공하는 리얼타임 렌더링과 툴의 품질 덕분에 놀랍도록 빠른 반복작업이 가능했습니다.
교수님으로부터 피드백과 아이디어를 받아도 이전 과정으로 돌아가서 다시 신을 렌더링할 필요가 없었습니다. 만약 그랬다면 며칠이 걸렸겠죠. 그 대신 색, 포스트 프로세싱 이펙트, 심지어는 같은 샷에 대한 얼터너티브 트랙 같은 여러 측면을 실시간으로 즉시 변경할 수 있었기 때문에 같은 시퀀스의 여러 변형을 빠르게 시각화할 수 있었습니다. 덕분에 프로세스가 매우 빨라졌습니다.
다른 어떤 소프트웨어의 도움 없이, 오직 언리얼 엔진 4만 활용하여 제가 전체 시네마틱 시퀀스를 만들 수 있었다는 사실이 믿어지지 않습니다. 이로서 저는 UE4가 뛰어난 설명서와 많은 도움을 주는 커뮤니티를 갖춘 강력하면서 역동적인 비디오 제작 툴이라는 사실을 다시 한번 느낄 수 있었습니다.
도움을 주신 분들
- 마커스 라우터바흐(Markus Lauterbach) 교수님
- 호르헤 S 소토(Jorge S Soto)
- 그레고리 닐(Gregory Neale)
- 디비전게임즈(Division Games) UG
- 사용 음향: 젤리그 사운드(Zelig Sound)가 저작권을 소유한 "인간 대 기계(ManVsMachine)"