UDN
Search public documentation:

MotionBlurSkinningKR
English Translation
日本語訳
中国翻译

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 홈 > 포스트 프로세스 이펙트 > 모션블러 스키닝 포스트 프로세스 이펙트
UE3 홈 > 시네마틱 아티스트 > 모션블러 스키닝 포스트 프로세스 이펙트

모션블러 스키닝 포스트 프로세스 이펙트


3small.png
각기 다른 방향으로 움직이는 부분에는 모션블러의 방향과 세기도 다릅니다.

문서 변경내역: Martin Mittring 작성. 홍성진 번역.

개요


추천 글: Motion Blur KR

motion blur skinning(모션블러 스키닝) 구현 이전에는 카메라와 오브젝트 모션(옮기기, 회전, 스케일)에 기반한 리짓 모션블러만 지원했었습니다. 스킨된 메시는 오브젝트의 루트에서 오브젝트 모션을 파생해 오는데, 단순한 오브젝트에는 근사치 구하기가 좋을지 몰라도 캐릭터에는 영 아닙니다. 바디의 각기 다른 부분이 각기 다른 방향으로 움직여 버리니 좀 더 세련된 방법이 필요하겠습니다.

PerBoneMotionBlur.jpg
왼쪽: 기능 끔
중간: 기능 켬
오른쪽: 픽셀별 속도를 색으로 표시

스킨된 모션블러는 약간의 CPU와 GPU 성능 및 메모리 비용이 추가로 듭니다. 고로 필요한 데만 써야겠습니다. 기타 모든 오브젝트에 대해 리짓 스킨드 모션 블러는 여전히 사용가능합니다.

기능 켜기


플랫폼이 지원한다면 (추후 관련 토픽 참고) "BaseEngine.ini" 에서찾을 수 있는 "MotionBlurSkinning" ini 세팅을 통해 또는 런타임에 "MotionBlurSkinning" 콘솔 명령을 통해 켤 수 있습니다.

ini 세팅에 지정된 수치는 콘솔 명령이 쓰는 수치와 같습니다. 스위치를 켜고(1) 끌(0) 수 있을 뿐만 아니라, 모든 오브젝트에 강제하기 위한 오브젝트별 덮어쓰기(2)도 가능합니다. 콘솔 명령을 파라미터 없이 내리면 도움말과 함께 현재 상태를 볼 수 있습니다:

ConsoleMotionBlurSkinning.jpg
MotionBlurSkinning 콘솔 명령을 사용한 화면입니다.

스켈레탈 메시 플랙 설정하기


플랙 이름은 bPerBoneMotionBlur (본별 모션블러 여부)이며, (언리얼 스크립트 등의) 코드나 레벨에 오브젝트로 놓았을 때 설정할 수 있습니다.

editorflag.jpg

구현


스킨된 모션블러는 픽셀별 모션 벡터를 속도 텍스처 속에다 출력하는 것입니다. (현재 카메라 모션은 흑백이며 오브젝트 모션은 컬러로, 자세한 것은 Motion Blur KR 참고) 속도를 전부 렌더링한 이후의 단계에서는 리짓 모션블러스킨된 모션블러 나 차이가 없습니다.

프레임에 사용된 모든 오브젝트에 대한 본 데이터 전부는 다음 프레임에서도 사용하기 위해 텍스처에 저장합니다. 즉 동일한 프레임에서 한 텍스처에서는 읽고(GPU) 다른 텍스처에다가는 쓰기에(CPU) 텍스처가 항상 둘 필요하다는 뜻입니다. 이를 통해 텍스처 록 수를 최소화시킬 수 있습니다. 엔진이 삼중 버퍼링을 사용하도록 바꾸면, 누군가는 이 체인에다 버퍼를 또 추가해야 할 것입니다.

버텍스 셰이더 상수로 기능을 구현할 수야 있었지만, 요 상수에는 제한이 있어서 데이터를 셰이더로 가져오는 데 문제가 있었습니다. GPU 스키닝이 이미 상수를 거의 다 사용하고 있기에 스킨된 모션블러용으로는 (현재 본 매트릭스와 이전것 둘 다 필요하니) 두배로 필요한 것입니다. 데이터를 (쿼터니언 + 스케일 + 포지션 식으로) 패킹할 수도 있었지만, 좀 더 복잡하게 하려면 일이 점점 커지는 것입니다. 드로 콜을 본 수 절반 청크로 분할하는 것도 해결책이 될 수 있겠지만, 그런 방법은 다른 패스의 렌더링 성능을 저하시킬 뿐만 아니라 콘텐츠 (쿠킹 / 가져오기) 준비 단계가 더욱 복잡해지게 됩니다.

스킨된 모션블러는 "버텍스 텍스처 펫치"를 사용하여 구현하기로 결정했습니다. 모든 하드웨어에서 지원되지는 않는 GPU 기능으로, 특히 초기 셰이더모델 3.0 하드웨어(AMD/ATI)에서는 지원되지 않습니다.

텍스처 업데이트는 CPU로부터의 본 데이터로 합니다. 나은 텍스처 캐시 성능을 위해 1D 텍스처를 사용합니다.

제한된 본 수(제한된 버텍스 셰이더 상수)를 따르고 머티리얼로 메시를 분할하기 위해 메시를 청크로 분할합니다.

청크별 인덱스를 사용하고, 그 인덱스는 본의 서브셋을 가리키기에 본이 복제되어 나타날 수 있습니다.

제한된 본 수

본 데이터 저장을 위해 1D 텍스처를 사용하기에 본 수에 제한이 있습니다. 현재는 4096 폭 텍스처를 사용하며, 본당 3 텍셀을 저장해야 합니다. stat SceneUpdate 명령으로 이 제한에 걸리나 볼 수 있습니다. 근처의 오브젝트에만 모션블러를 쓰기에 아직 본 수가 문제되는 것을 본 적은 없습니다. 얼굴 애니메이션용 모션블러에는 모션블러 스키닝 기능이 필요하지 않음을 알아두시기 바랍니다.

셰이더 순열

스킨드 모션블러가 있거나 없을 때 셰이더 순열(permutation)을 피하려 노력했습니다. 대부분 코드 복잡도를 낮추기 위함이지만, 전반적인 셰이더 수를 줄이기 위함이기도 합니다. 정적 분기(불 셰이더 상수에 비교)를 사용하기로 결정했는데, 문제도 해결되고 드라이버를 통해 최적화되기 때문입니다.

엑스박스360에서는 셰이더 순열을 피하기 위해 정적 분기를 사용합니다. 확인한 바로는 컴파일한 것 만큼 빠릅니다. 다른 플랫폼에서는 아직 이 기능을 사용하지 않습니다. (최적화 부분 참고)

성능


CPU 데이터 업데이트

스킨된 모션블러는 이전 프레임의 데이터를 저장하고 다음 프레임부터 재사용하기에 CPU 비용이 그리 높지 않습니다. 텍스처 록 연산상의 드라이버 성능은 느릴 수 있는데 그런 연산 카운트를 프레임별로 추적합니다. stat SceneUpdate (씬 업데이트 통계) 콘솔 명령으로 수치를 확인할 수 있습니다. 업데이트된 본의 양도 확인할 수 있습니다.

StatSceneUpdate.jpg
통계에서 록에 대한 CPU 시간과 업데이트된 본의 양을 확인할 수 있습니다.

추가 드로 콜

모션블러된 오브젝트는 (픽셀별 모션 벡터를 저장하기 위해) 속도 렌더링 패스에서 렌더링할 필요가 있습니다. 스킨되지 않은 모션블러에 대해서는 오브젝트 모션이 있을 때만 이 작업을 해 주면 됩니다. 스킨된 오브젝트에 모션이 있는지를 테스트하기 위해서는 데이터를 훨씬 많이 검사해야 할 것입니다. 아직 이 최적화는 하지 않습니다. 할 수야 있었지만 움직이는 오브젝트가 많은 최악의 경우에는 도움이 되지 않을 것입니다.

즉 움직이지 않는 (봇과 같은) 오브젝트에 대해 스킨된 모션블러를 켜 버리면 렌더링에 드로 콜이 추가로 발생한다는 것입니다.

버텍스 텍스처 펫치 GPU 비용

현재 메써드에는 매우 큰 버텍스 포맷 속으로의 버텍스 텍스처 펫치가 12 필요합니다. (본 하나 4x3 매트릭스용 4 플로트, 스키닝용 4 본) 무슨 뜻이냐면 이런 식의 렌더링에는 버텍스가 더 많이 들어가며, 렌더링도 느려진다는 것입니다. 근처의 오브젝트만 이런 식으(속도 렌더링 패스)로 렌더링되게 해야 근처의 액션 다수에서만 렌더링 비용이 정점을 찍게 됩니다.

엑스박스360에서 (모프 포함 빽빽한 트라이앵글 메시의) 속도 렌더링 패스를 프로파일링할 때 리짓 모션블러일 때보다 렌더링이 60% 느려지는 것을 확인했습니다. (모든 오브젝트가 움직여서 렌더링을 생략할 수가 없었던 거죠.)

메모리


이 기능이 차지하는 메모리는 일정한데, 데이터를 저장하는 텍스처 둘의 크기가 고정되어 있기 때문입니다. 이를 통해 재할당 성능 손실 및 메모리 단편화를 피할 수 있습니다. 메모리를 얼마나 차지하는지 살펴보기 위해 이 메모리를 추적합니다. stat memory (메모리 통계) 콘솔 명령을 사용하여 데이터를 들여다 볼 수 있습니다:

StatMemory.jpg

다른 플랫폼 지원


이 구현은 모든 GPU에서 지원되지는 않는 버텍스 텍스처 펫치 기능을 기반으로 하고 있습니다. 현재 Direct3D 9(를 지원하는 하드웨어)와 엑스박스360에서 스킨된 모션블러를 지원하고 있습니다. 플레이스테이션 3도 간단히 지원할 수는 있지만, (텍스처 펫지 구현과 높은 버텍스 수로 볼 때) 너무 느릴 것으로 예상됩니다. 나중의 DirectX 버전은 나중에 가서 지원하겠습니다. 모바일 하드웨어에 대한 지원은 현재 (성능상의 이유로) 계획되어 있지 않습니다.

지원되지 않는 경우 엔진이 자동으로 리짓 스킨된 모션블러 를 대용합니다.

최적화


  • 엑스박스360에서 "vfetch" 기능을 버텍스 텍스처 펫치 대신 사용할 수도 있습니다.
  • 버텍스별 본 룩업을 4 미만으로 할 수도 있습니다. (질이 떨어지겠지만 괜찮은 수준일 듯)
  • 게임 코드가 움직이지 않는 오브젝트를 발견했을 때 끌 수 있도록 하기 위해 런타임에 bPerBoneMotionBlur (본별 모션블러 여부)를 검사할 수도 있습니다. (이것 자체는 간단해도 쓸만해 지려면 게임 코드 작업이 좀 필요)
  • PC와 플레이스테이션 3에서도 정적 분기를 활용하는 것입니다. 현재 엔진에 버그가 있어 사용할 수가 없습니다. 대안으로써 해당 기능을 끄기 위해 플로트의 상태를 체크합니다. (즉 스킨되지 않은 오브젝트도 속도 렌더링 패스에서 셰이더 비용이 엄청 든다는...)
  • 현재 텍스처가 일부만 사용되도 전체 텍스처를 록 합니다.
  • 속도 렌더링이 필요하면 모든 본을 그 전 것에다가 비교하여 테스트합니다.

쓸만한 콘솔 명령


MotionBlurSkinning
(모션블러 스키닝) 위에 설명