2014년 4월 9일

UE4 용 케이블 컴포넌트 플러그인

저자: * James Golding

저희 에픽에서는 한 달에 하루를 "에픽 프라이데이"로 지정, 아무거나 원하는 작업을 할 수 있도록 하고 있습니다. 두 달 전 저는, 생동감을 더하기 위해 밧줄 피직스를 사용하여 레벨에 걸어둘 수 있는 정말 간단한 '케이블 컴포넌트' 작업을 했습니다. 다른 게임에서 수년간 보아오던 이펙트이지만, UE4 에 플러그인으로 추가하면 얼마나 쉬울지 확인하고 싶었습니다! 그 결과가 이렇습니다:

시뮬레이션

실제 케이블 시뮬레이션을 하기 위해, 몇 번 가지고 논 적이 있던 소위 'Verlet Integration' 이라는 기법을 사용했습니다. 게임 개발 분야에는 매우 잘 알려져 있어 온갖 종류의 기사를 찾아볼 수 있으며, Thomas Jakobsen 의 글이 가장 먼저 기억에 남습니다 (http://graphics.cs.cmu.edu/nsp/course/15-869/2006/papers/jakobsen.htm).

여기서의 개념은 케이블을 두 종단 사이에 '거리 제약'이 있는 파티클 시리즈로 나타내는 것입니다. 종단의 파티클은 '고정'되어 부착된 것을 따라 움직입니다. 그 가운데 있는 것들은 '자유'로운 것으로, 중력에 의해 낙하됩니다. 매 스텝마다 각 파티클의 속도와 위치를 업데이트한 다음, 제약을 충족시킬 만큼 움직입니다. 케이블의 'stiffness'(강성)은 매 스텝 제약 시행을 위해 반복처리하는 횟수로 제어됩니다.

Diagram

여기서 수학 공식으로 들어가지는 않겠습니다. UE4 소스 코드가 있다면 VerletIntegrateSolveDistanceConstraint 함수 내 UCableComponent 클래스의 60 줄 짜리 코드입니다.

렌더링

튕겨다니는 멋진 파티클 체인이 생겼으니, 렌더링을 해 줘야 합니다. UE4 에서 새로운 유형의 지오메트리를 생성하는 데 매우 좋은 테스트 케이스였는데, 꽤나 쉬운 것으로 밝혀졌습니다. 케이블의 렌더러 표현인 FCableSceneProxy 클래스를 새로 만들어야 했습니다. 각 프레임마다 (TickComponent 내 메인 스레드에서 행해지는) 시뮬레이션에서 얻은 새로운 파티클 위치를 SendRenderDynamicData_Concurrent 함수를 통해 이 프록시에 전달합니다. 렌더 스레드에서 인덱스와 버텍스 버퍼를 잠금 및 업데이트하여 '튜브' 메시를 만듭니다. 각 버텍스에 대해 위치, 텍스처 UV, 세 개의 탄젠트 기저 벡터를 계산해야 합니다. X 는 케이블쪽, Z 는 케이블 수직 아래쪽(법선), Y 는 X 와 Z 에 수직입니다.

Cable Geometry

면 갯수, 튜브 반경, 케이블을 따른 UV 타일링 횟수 등을 컴포넌트에 프로퍼티 노출시켜 뒀습니다.

붙이기

갖고 놀 수 있는 케이블이 보이기 시작했으니, 뭔가에 붙이고 싶습니다. 언리얼 엔진 4 는 이미 SceneComponent 를 다른 것에 붙일 수 있도록 되어 있어, 오프셋과 함께 'end' 파티클을 다른 컴포넌트에 붙이는 옵션을 추가해 뒀습니다. 케이블의 최종 디테일은 이러한 모습입니다:

Materials Screen

다 됐습니다! 레벨에 Cable 액터( 또는 블루프린트에 Cable 컴포넌트)를 추가하여 테스트해 볼 수 있습니다. 확실히 UE4 에 재미있는 추가사항이기는 하지만, 추가되었으면 하는 것이 더욱 많습니다:

  • 월드에 콜리전 추가
  • 힘, 폭발 등에 반응
  • 메인 스레드가 아닌 멀티스레드 시뮬레이션
  • 인덱스 버퍼가 변하지 않으므로 매 프레임 리빌드 중지

여러분은 어떠신지요? 어떤 기능이 추가되었으면 좋겠습니까? 트위터 @EpicJamesG 또는 포럼에서 이야기 나눕시다! 저희 툴이나 이 튜토리얼에 대한 여러분의 피드백은 저희에게 매우 소중하답니다. 한글 사용자 분들은 네이버 카페 를 이용해 주시면 됩니다.