Frame at 6.00s

안녕하십니까, 저는 Ivan Cerevko입니다. Hangar 13의 Principal Character Artist로서 'Mafia the Old Country'의 헤어 및 헤드 creation pipeline 작업에 참여하였습니다.

Frame at 15.50s

본 자리에 함께하게 되어 영광이며, 저희가 메타휴먼(Metahuman)을 개발하며 겪었던 여정의 일부를 공유해 드리고자 합니다.

Frame at 25.00s

오늘 다룰 내용은 다음과 같습니다. 먼저, 메타휴먼(MetaHuman)을 사용하기로 결정한 이유와 프로젝트 비전에 어떻게 부합하는지 설명드리겠습니다. 이어서 메타휴먼 커스터마이징 예시와 이를 통해 얻은 생산 유연성에 대해 보여드리겠습니다. 다음으로는 헤어스타일링(grooming)을 할 것인가 말 것인가를 다루며, 헤어컷(haircuts)과 스트랜드(strands)를 비교하고 저희 프로젝트에 가장 효과적이었던 작업 방식을 공유하겠습니다. 마지막으로, 하이폴리(high poly) 헤어스타일링 툴이 게임 에셋 제작에도 어떻게 활용될 수 있는지 등 저희 헤어 제작 워크플로우의 일부를 안내해 드리겠습니다.

Frame at 60.20s

게임 시작 전, 짧은 컷신을 먼저 보여드리겠습니다. 이 방에 있는 모든 남성들은 피로 맺어진 관계입니다. 이것은 곧 가족입니다. 그리고 이 가족 안에서는 명예로운 규범을 따릅니다. 삶의 방식으로서 말입니다. Brotherhood에서는 당신의 행적과 당신 곁에 선 이들의 보증 때문에 이곳에 온 것입니다. 이 삶은 비밀을 동반합니다. 친구를 사귀거나 여성을 만난다 해도, 우리에 대해 알려서는 안 됩니다. 이것은 구속력이 있으며 용서받지 못합니다. 한 명을 배신하는 것은 모두를 배신하는 것입니다. 이 가족에게 당신의 삶을 헌신하시겠습니까? 예, 헌신하겠습니다. 좋습니다. 감사합니다.

Frame at 156.60s

메타휴먼을 사용하기로 결정한 이유는 무엇입니까?

Frame at 160.10s

첫 번째 이유는 높은 수준의 현실감입니다. 'Mafia The Old Country'는 현실주의적 아트 디렉션을 갖춘 스토리 중심 게임으로, 스토리 캐릭터들의 품질을 한 단계 끌어올리는 것이 중요했습니다. MetaHuman Rig는 미묘한 감정까지 표현할 수 있는 고품질 애니메이션을 구현하는 데 도움을 주었습니다.

두 번째 이유는 워크플로우의 효율성입니다. 시간과 예산의 제약으로 NPC 에셋 스캔은 불가능했습니다. MetaHuman 덕분에 약 3개월 만에 메인 캐릭터와 매우 유사한 품질의 NPC 에셋 100개 이상을 제작할 수 있었습니다.

Frame at 203.25s

Asset processing을 위해 저희는 DNA Calibrator와 custom tool을 함께 사용하였습니다. 이를 통해 단 몇 분 안에 rig setup을 업데이트하거나 regenerate하는 유연성을 확보할 수 있었습니다.

Frame at 215.06s

마지막으로, 유연성과 Unreal 5 통합에 관해 말씀드리겠습니다. 메타휴먼 기술의 가장 큰 장점 중 하나는, rig나 animation을 깨뜨릴 위험 없이 프로덕션 후반 단계에서도 애셋을 계속 수정할 수 있다는 것입니다. 실제로 저희는 기본 헤드에 animation을 생성한 후, 애셋이 준비되면 해당 animation을 특정 애셋에 적용하는 방식을 자주 사용했습니다.

Frame at 245.97s

'Mafia the Old Country' 개발은 Unreal 5.1에서 시작되었으며, 몇 달 후에

Frame at 255.27s

DNA Calibrator 툴이 출시되어 asset scalability에 대한 유연성이 크게 향상되었습니다. 주연 캐릭터들의 fidelity 측면에서

Frame at 266.30s

NPC 캐릭터 최적화가 매우 중요했습니다.

Frame at 272.62s

이 워크플로우는 주요 캐릭터 제작에 Mesh2MetaHuman 플러그인과 스캔 데이터를 활용하였습니다. 스캔 데이터를 MetaHuman으로 보내기 전, MetaHuman 측정값에 더 가깝게 일치하도록 스캔 데이터를 먼저 정리하는 과정을 거쳤습니다. 프로젝트 시간 제약으로 인해, 중립적인 표정만 처리하여 주요 캐릭터들이 일반적인 MetaHuman 표정 풀을 공유하도록 하였습니다.

NPC 캐릭터는 스토리 및 컨셉에 기반하여 MetaHuman Creator에서 직접 제작하였습니다. 각 카테고리별 Unreal Engine 구현 방식도 차이가 있습니다. NPC는 군중 장면에서 성능 친화성을 유지하기 위해 추가적인 최적화 과정을 거쳤습니다.

Frame at 331.18s

이제 메인 캐릭터 중 하나의 워크플로우 예시를 공유하겠습니다. 스캔 세션 중에 배우가 옆으로 기울거나 기대는 상황은 흔하게 발생합니다.

Frame at 343.68s

저희 경험상, 스캔 데이터를 MetaHuman Creator에 넣기 전에 이러한 문제를 해결하는 것이 항상 더 좋습니다. 만약 MetaHuman 결과물과 스캔 데이터를 혼합해야 하는 상황이 발생한다면, 두 입력 데이터가 올바르게 정렬되었는지 반드시 확인해야 합니다. 저희의 경우, 입 안쪽(mouth cavity)은 항상 100% 블렌딩했습니다. 이는 치아 위 입술의 부드럽고 깔끔한 슬라이딩 변형(sliding deformation)을 유지하는 데 도움이 되었습니다.

Frame at 372.82s

일부 캐릭터의 경우, mesh penetration 이슈가 발생했던 눈꺼풀 영역에 약 40%의 blend를 적용하였습니다.

Frame at 381.72s

MetaHuman 측정값에 각 스캔을 맞추기 위해 base head를 주요 정렬 지점으로 사용하였습니다.

Frame at 388.72s

남성, 여성, 브루드, 어린이를 포함한 네 가지 기본 헤드(base heads)를 사용하였습니다. 이 모든 헤드는 MetaHuman Creator에서 제작되었으며, 저희의 신체 비율에 맞도록 스케일 조정(scale adjustments)을 거쳤습니다. 기본 헤드의 얼굴 영역(face area)은 전혀 수정하지 않았습니다.

Frame at 404.41s

MetaHuman Creator에서 가져온 그대로 변경되었으며, 나머지 기능들은 프로젝트 요구사항에 맞춰 조정되었습니다. mesh가 정렬된 후, base head topology를 scan 위에 래핑(wrap)했으며, 초기 cleanup pass의 일부로 다음 작업을 진행했습니다.

Frame at 421.09s

이것은 베이스 헤드의 두개골과 목 부분을 블렌딩한 결과입니다.

Frame at 427.34s

이전 단계(pre-processing stage)를 거쳐 MetaHuman Matrix에 적합하고 Mesh2MetaHuman으로 바로 진행할 수 있는, 최소한의 artifact를 가진 스캔 결과를 얻었습니다. 말씀드린 바와 같이,

Frame at 439.50s

최근 저희는 Unreal Engine 5.1 버전을 기반으로 개발을 시작하였으나, 최종적으로는 Unreal Engine 5.4.4 버전으로 게임을 출시하게 되었습니다. 이로 인해 이전 버전의 Unreal Engine 환경에서 작업해야만 했습니다.

Frame at 453.05s

Mesh2MetaHuman plugin과 MetaHuman Creator에 관한 내용입니다. Mesh2MetaHuman 추적을 위해

Frame at 459.70s

기존 설정은 두세 개의 카메라 위치를 사용하는 것이었습니다. 경우에 따라서는 눈꺼풀 가장자리 등 추가적인 tracker를 사용하기도 했습니다. 이는 precision을 좀 더 높여야 했던 영역 중 하나였습니다. 보시는 바와 같이

Frame at 476.38s

이미지 위에 추가적인 landmark를 얼굴 특징에 덧입혔습니다. 이는 주로 부드러움(smoothness)을 위해서였습니다.

Frame at 485.75s

메쉬 to 메타휴먼(Mesh to MetaHuman) 변환 결과는 젊은 단계의 특징을 반영하므로, 트래커(tracker) 조정이 필요한 정확한 위치를 파악하기 어려울 수 있습니다. 거의 모든 메쉬 to 메타휴먼 결과물에서 다음과 같은 조치가 필요했습니다.

Frame at 498.57s

MetaHuman Creator에서 일부 조정을 수행했습니다. 주로 입 주변에 대한 수정이었습니다. 많은 경우 기본 설정이 강한 과개를 유발하거나, 때로는 입 안쪽으로 너무 깊게 삽입되는 문제가 있었습니다.

Frame at 514.73s

이러한 경우 예측 불가능한 애니메이션 결과가 발생했습니다. 히어로 에셋의 경우, 저희는 한 단계 더 나아갔습니다. 배우의 레퍼런스 사진과 가능한 한 가깝게 치아 모양을 맞추기 위해 노력했으며, MetaHuman Creator에서 해당 변경 사항을 적용했습니다. 이는 치아 자체뿐만 아니라 접촉점(contact point)도 중요하기 때문입니다.

Frame at 533.72s

입술과 치아 사이의 영역 또한 해당 변경 사항을 적용할 때 이동합니다.

Frame at 540.50s

Mesh to MetaHuman은 상당한 수준의 결과물을 제공하였으며, 스토리상 중요도가 낮은 캐릭터의 경우 결과물을 그대로 활용할 수 있었습니다. 또한, 사전 준비 덕분에 MetaHuman 결과물은 Scale과 Position 모두 저희 데이터와 잘 부합하였습니다. 그러나 메인 캐릭터의 경우 Likeness가 매우 중요했습니다.

Frame at 563.08s

MetaHuman 출력물을 스캔 위에 덧씌우는 추가적인 단계를 적용하였습니다. 이 단계에서는 모든 mesh loop가 해당하는 feature 위에 정확히 덮여야 하였으며, 그렇지 않으면 facial expression으로 distortion이 이어질 수 있었습니다. 덧씌우기 작업을 마치고 ZBrush에서의 최종 조정 작업으로 넘어가기 전에,

Frame at 581.74s

랩핑(wrapping)이 성공적으로 이루어졌는지 확인하기 위해 몇 가지 테스트를 진행합니다.

Frame at 585.24s

그리고 expressions가 문제 없이 작동하는지 확인하십시오.

Frame at 591.74s

ZBrush 패스 작업 시, 최종 토폴로지에 스캔 데이터를 reprojection하여 디테일을 복원하고, 필요한 부분에는 수작업으로 artistic adjustment를 추가하였습니다. Custom expressions를 사용하지 않았으므로, neutral pose에서 feature 조정을 통해 breaking expressions를 보완해야 했습니다.

Frame at 610.82s

기본 포즈에서 나타나는 날카로운 보조개를 피하기 위해 입꼬리에 약간의 디테일을 더하는 것은 흔한 작업이었습니다.

Frame at 623.54s

마지막 미세 조정 단계에서는 아트 디렉터 또는 애니메이션 팀의 피드백을 반영하여 머리 특징에 약간의 수정을 가했습니다. 이는 주로 특정 특징을 강조하거나, 인게임 라이팅 환경의 한계를 보완하기 위해 모공과 주름의 디테일을 강화하는 방식으로 이루어졌습니다.

Frame at 644.83s

추가적인 미세 디테일을 위해 textureXYZ의 고품질 데이터를 사용하였습니다.

Frame at 653.13s

Diffuse 텍스처에서 추출한 displacement map을 사용했습니다. 이를 통해 스캔 지오메트리 자체만으로는 얻을 수 없었던 추가적인 사실감을 구현할 수 있었습니다.

Frame at 674.58s

MetaHuman 결과물에 커스텀 변경 사항을 적용하기 위해 DNA Calibrator 위에 구축된 자체 개발 툴을 활용하였습니다. 이 툴을 사용하여 헤드, 치아, 눈 및 기타 메쉬에 맞춰 joint와 vertex의 위치를 재조정할 수 있었습니다. MetaHuman 소스의 초기 처리 과정의 일환으로, 프로젝트 요구 사항에 맞게 LOD(Level of Detail)를 재구성하였습니다. 테이블에서 보시는 바와 같이, 원본 7개 대신 4개의 LOD만을 사용하였습니다. 헤드 지오메트리의 경우, 메인 캐릭터를 포함하여 MetaHuman LOD0과 모든 morph를 완전히 제거하였습니다.

Frame at 713.12s

LOD1은 시네마틱에서 고품질을 유지하기 위해 LOD0으로 사용되었습니다. LOD2는 게임 내 클로즈업 상황에 사용되었으며, 시네마틱에서만 중요했던 메시 엘리먼트(mesh elements) 수를 줄였습니다.

Frame at 728.46s

LOD 0의 경우, 기본 MetaHuman에는 포함되지 않는 eyeblur이라는 추가 메쉬가 있음을 확인하실 수 있습니다. 이는 추후 슬라이드에서 설명해 드리겠습니다. 마지막 LOD에서는 원거리 캐릭터의 성능을 극대화하기 위해 매우 공격적인 최적화를 적용하였습니다.

Frame at 747.46s

Body meshes에는 MetaHuman의 모든 네 가지 LOD(Level of Detail)를 사용하였습니다.

Frame at 752.95s

human LODs에 적용된 유일한 토폴로지 변경은 LOD 0의 feed area 부분에서 LOD 0과 LOD 1 간의 blend를 구현한 것입니다. LOD 0을 완전히 생략했기 때문에, corrective blend shapes 역시 모두 생략되었습니다. 본 예시에서는 일부 표정에서 품질 저하가 눈에 띄는 것을 확인할 수 있습니다. NPC 에셋의 경우 이는 큰 문제가 되지 않았고 인게임 상황에서도 완벽하게 작동했지만, 컷씬의 메인 캐릭터들에게는 더욱 부자연스럽고 고무 같은 느낌을 주기 시작했습니다.

Frame at 792.49s

애니메이션을 위해, 익스프레션(expression) 품질 저하를 부분적으로 보상하고자 LOD0과 LOD1 간의 메시 차이를 저희 자체 wrinkle map으로 다시 베이크(rebake)하기로 결정하였습니다. 만약 wrinkle map 작업에 추가적인 스컬핑(sculpting) 과정이 필요했다면, 하이 폴리 메쉬(high poly mesh)에서 베이크하였습니다.

Frame at 810.10s

이것은 속도는 느리지만 품질 지향적인 옵션이었습니다. 두 번째로 더 빠른 옵션은 Substance Designer를 사용하는 것이었습니다. 거기서는 LOD 0과 1 간의 Topology 차이를 분리할 수 있었습니다.

Frame at 820.62s

이후 기존 wrinkle map과 차이를 결합합니다. Substance Designer는 저희 파이프라인의 중요한 부분이었습니다. 저희는 메타휴먼 소스(metahuman sources)의 베이킹(baking) 및 처리에도 이를 활용했습니다.

Frame at 834.63s

WrinkleMap1의 경우, 여러 겹쳐진 표현들의 조합으로 인해 세 개의 분리된 bake 결과가 필요했습니다. 이 bake 결과들은 Substance Designer 내에서 자동으로 하나의 텍스처로 결합되었습니다. WrinkleMap2와 3의 경우, 과정은 단순했습니다.

Frame at 853.87s

이러한 경우, 여러 세트가 필요하지 않았습니다.

Frame at 859.03s

이전에 언급해 드린 바와 같이, Substance Designer는 저희 텍스처링 워크플로우의 중요한 부분이며, 이 결정을 내린 데에는 몇 가지 핵심적인 이유가 있습니다. 첫 번째 이유는 당연히 자동화입니다. 기술적인 부분의 경우, 제한된 시간과 많은 애셋으로 인해 수작업을 최대한 피하고자 했습니다. 수작업 단계는 버그를 쉽게 유발할 수 있기 때문입니다.

두 번째 이유는 유연성과 일괄 업데이트 기능입니다. 프로덕션 과정에서 많은 기능들이 발전했습니다. 특히 NPC와 최적화 관련하여 새로운 파라미터가 자주 추가되었습니다. 이러한 변경 사항으로 인해 프로덕션 중에 애셋을 여러 번 다시 작업해야 했습니다.

세 번째 이유는 대규모 텍스처 리소스 관리입니다. 메인 캐릭터 애셋의 경우 MetaHuman 소스의 전체 세트를 임포트해야 했습니다.

Frame at 910.78s

일부 에셋은 8K resolution으로 제작되었으며, 대부분의 그래프는 다수의 texture mask를 사용했습니다. 따라서 Substance Designer가 이러한 모든 것을 관리 가능하게 하는 데 큰 도움을 주었습니다.

Frame at 925.74s

처음 설정은 다소 과도하게 복잡했습니다. Substance Designer에 익숙하지 않은 일반 아티스트들에게는 따라오기가 매우 어려웠습니다. 이러한 이유로, 나중에 모든 processing tool은 하나의 node로 통합되었고, 모든 small graph는 simple parameter로 노출되었습니다.

Frame at 951.64s

이곳에서는 scan-based asset을 위해 bake한 네 가지 주요 texture output을 확인하실 수 있습니다. 이 단계부터는 이미 LOD0으로 MetaHuman LOD1을 사용하고 있었습니다.

Frame at 963.45s

가장 위에 있는 첫 번째 텍스처는 AO map입니다. 이 텍스처는 non-directional AO와 world space normal map의 green channel을 blend하여 생성됩니다. 여러 ambient lighting 시나리오에서의 실험 결과, 이 조합이 가장 우수한 결과를 도출하였습니다. 두 번째 텍스처는 cavity map입니다.

Frame at 984.81s

Substance Designer에서 normal map의 최종 출력물로부터 직접 추출되었습니다. 이는 believable specular을 위한 가장 중요한 pass 중 하나로 판명되었습니다.

Frame at 995.18s

ZBrush에서 fine detail 레이어에 약간의 inflate deformation을 적용하여 cavity map에 더욱 화려하고 유기적인 느낌을 부여하는 것이 좋은 practice입니다.

Frame at 1006.17s

그리고 세 번째 텍스처는 processed color map이며, 마지막은 당연히 normal map입니다. 이 비교를 통해 차이점을 알 수 있습니다.

Frame at 1018.73s

텍스처에 베이크된 secondary shapes의 양이 있습니다. MetaHuman 텍스처는 LOD0 geometry에서 상당한 양의 디테일이 처리되므로 다소 평평하게 보입니다. 여기에는 기본 MetaHuman 컬러 맵과 저희 커스텀 결과물 간의 비교를 제시합니다. 저희 커스텀 컬러 맵은 원본 MetaHuman 텍스처와 베이크된 wrinkle maps에서 추출한 추가 정보를 결합하여 생성되었습니다. NPC 캐릭터의 경우, 개별 텍스처 전체 세트를 사용하는 대신 셰이더를 수정하여 더 저렴한 블렌딩 방식을 사용했습니다.

Frame at 1056.01s

Generic 립스틱(wrinkle) 및 컬러 맵(color maps)을 위한 공유 풀(shared pool)을 구성하였으며, 세 개의 컬러 맵을 하나의 RGB 텍스처에 압축하였습니다. 하지만 이 설정은 NPC가 인게임 시나리오(in-game scenarios)에서 시네마틱 LOD(cinematic LODs)를 로드해야 하는 경우에만 적용되며, NPC 자체는 립스틱 또는 컬러 맵을 전혀 사용하지 않습니다.

Frame at 1078.76s

shader 측면에서는 모든 material에 대한 추가 최적화 작업과 더불어 프로젝트에 필요한 몇 가지 기능을 도입하였습니다. 몇 가지 변경 사항을 공유하고자 합니다. 스토리 진행 중, 캐릭터는 상당히 힘든 상황을 겪게 됩니다. 이러한 충격 효과와 진행 상황을 보여주기 위해 dirt, sweat, blood에 대한 cinematic mask를 도입하였습니다. 이 예시에서 볼 수 있듯이, 초기 이벤트의 효과가 계속 남아 있으며 새로운 이벤트의 효과와 겹쳐 보이는 것을 확인할 수 있습니다. 이 mask들은 모두 texture array에 packing 되었으며, 간단한 방식으로 활성화할 수 있었습니다.

Frame at 1117.24s

`selector slider`. 각 캐릭터의 게임 내 역할을 더 잘 강조하기 위하여,

Frame at 1126.37s

다양한 치아 프리셋(presets)을 추가하였습니다. 치아 색상 변형에는 단일 채널 마스크(one-channel masks)를 사용하였으며, 무작위적인 스케일(scale)이나 손상 효과는 월드 포지션 오프셋(world position offset)과 마스크를 조합하여 구현하였습니다. 이는 매우 사소하지만 중요한 디테일 중 하나입니다.

Frame at 1141.38s

대부분의 플레이어는 인지하지 못하겠지만, 이를 알아차리는 순간 좋은 인상을 남길 것입니다.

Frame at 1149.12s

다음으로 조정한 부분은 eye specular를 개선한 것입니다. 게임 내 라이팅의 제약으로 인해 흔히 발생하는 문제입니다.

Frame at 1157.12s

눈의 사실적인 표현은 매우 어려운 과제이며, 특히 주변광(ambient lighting) 환경에서는 더욱 복잡해집니다. 이러한 이유로, 눈 셰이더(eye shader)에 간단한 가짜 스페큘러(fake specular)를 도입했습니다. 이는 기본적으로 카메라 정렬 반사 벡터(camera-aligned reflection vector)와 텍스처를 결합한 것으로, 시네마틱(cinematic) 장면을 위해 조정하거나 교체할 수 있는 옵션을 유지하였습니다.

눈과 관련하여 저희가 직면했던 두 번째 난제는 안개(fog)와 오클루전 메시(occlusion mesh)였습니다. 이 메시는 추가적인 앰비언트 오클루전(ambient occlusion)과 눈꺼풀과 안구 사이의 부드러운 전환을 위해 사용됩니다. 두 효과 모두 본래 투명 블렌딩(translucent blending) 방식을 사용하는 단일 셰이더로 처리되었으나, 구현의 복잡성으로 인해 특정 환경에서 예측 불가능한 셰이딩(shading) 현상이 발생했습니다. 예를 들어, 안개 낀 장면에서 눈이 빛나는(glowing) 문제가 나타났습니다.

Frame at 1212.72s

다수의 실험 끝에, 저희는 Eyelid Transition과 Eyelid Eye Occlusion 효과를 각각 별도의 셰이더와 메쉬로 분리하는 솔루션을 채택했습니다. Eyelid Transition에는 기존의 Translucent Blending 방식을 유지하고, Fogging을 활성화하여 적용했습니다. 이것이 저희가 'Eye Blur'라고 명명한 새로운 애쉬(ash)입니다. Occlusion 셰이더의 경우, Translucent 방식 대신 Modulate Blending 방식을 사용하도록 전환했습니다.

Frame at 1237.72s

Apply Fogging을 활성화한 상태를 유지했습니다. 보시는 바와 같이 결과는 상당히 성공적이었습니다.

Frame at 1248.66s

언급된 수정 사항들은 프로덕션 과정에서 이루어진 수많은 변경 중 일부에 불과합니다. 적용된 모든 변경 사항으로 캐릭터가 어떻게 진화하는지를 보여주는 작은 비교를 제시합니다. 그리고 또 다른 예시도 있습니다.

Frame at 1268.22s

이어서 스토리 캐릭터와 NPC 간의 간단한 비교를 보여드리고자 합니다. 왼쪽 캐릭터는 모든 부가 기능과 함께 커스텀 컬러 및 링클 맵을 사용했으며, 오른쪽 NPC는 제네릭 풀의 링클 및 컬러 맵을 활용했습니다. 물론 가시적인 품질 차이는 존재하지만, 이 NPC가 메인 캐릭터들과 함께 컷신에 등장하더라도

Frame at 1289.76s

주요 캐릭터들에 대해 Full High Poly Treatment이 적용되었으며, 이는 여전히 상당한 수준의 퀄리티를 유지하고 있다고 생각합니다.

Frame at 1298.96s

NPC는 low poly mesh 레벨에서만 처리되었습니다. 이로 인해 LOD 간 표현뿐만 아니라 neutral normal map에서도 품질 저하가 발생했습니다. high poly에서 baking하는 대신,

Frame at 1312.90s

LOD0 메시에서 직접 정보를 bake 하였으며, Metahuman 소스에 포함된 normal map과 결합하였습니다.

Frame at 1322.54s

먼 거리에서 얼굴의 부드러운 전환과 더 나은 셰이딩을 얻기 위해, LOD0에서 추출한 정보를 마지막 LOD까지 베이크(bake)하였습니다. 이를 위해 256x256 크기의 작은 텍스처만을 사용했습니다. 이어서 메타휴먼(MetaHuman) 최적화에 대해 간략히 말씀드리겠습니다.

Frame at 1345.76s

총 4개의 LOD(Level of Detail)만을 사용했습니다. MetaHuman의 LOD1을 기본 LOD0으로 설정하고, 가장 낮은 LOD는 LOD6를 사용하여 이후 단계에서 제거했습니다.

추가적으로, 특정 미션에서 화면상의 캐릭터 수를 기준으로 LOD 거리를 동적으로 조절하는 LOD 시스템을 구현했습니다.

또한, 낮은 LOD에서 Post-Process를 토글하고 Leader Pose로 공격적으로 전환하도록 했습니다. 커스텀 Tick Batching을 Game Thread에 적용하기도 했습니다.

마지막으로, 인게임 시나리오에서는 Half-Res Subsurface Scattering을 사용했습니다. 일부 품질 저하가 있었으나, 콘솔의 성능 확보를 위해 필수적이었습니다.

Frame at 1411.35s

이 인물은 우리의 주인공이며, 'Zofavara', 'Isabella', 'Galante', 그리고 주인공의 친구이자 멘토인 'Luca Trapani'가 함께합니다.

Frame at 1426.28s

엔진에서 렌더링된 몇 가지 클로즈업 샷입니다. 이제 가장 중요한 질문으로 넘어가겠습니다.

Frame at 1444.78s

프로젝트 초기에 직면했던 첫 번째 질문은 'Grooming을 할 것인가, 말 것인가?'였습니다.

Frame at 1453.28s

이것은 다른 게임 개발자분들께도 자주 듣는 질문 중 하나입니다. 따라서 Strength-based system과 Card-based system의 간단한 비교부터 시작하겠습니다. Strength-based system의 장점부터 설명드리겠습니다.

Frame at 1468.28s

유연한 변경 가능성입니다. 반복 작업이 많고 아트 친화적이라는 강점이 있습니다. 반복 과정에서 아티스트가 기술적 수정에 시간을 더 많이 소요하는 대신, 예술적 표현에 집중하는 상황을 방지하는 데 훨씬 용이합니다.

Frame at 1484.66s

창의적인 측면에서 두 번째 장점은 당연히 더욱 높은 visual fidelity입니다. Strength 기반의 hair는 보다 사실적인 hair specular, strength thickness, shadowing, line transmissions 등을 제공합니다. 세 번째 장점은 Unreal Engine polygrooms에서의 쉬운 transferring 및 runtime binding입니다. binding assets 덕분에 여러 asset에 걸쳐 adapt하는 것이 훨씬 수월해집니다.

Frame at 1507.87s

기하학적 형태가 매우 다양하더라도 적용 가능합니다. 물론 몇 가지 단점도 존재하며, 이에 대해 살펴보겠습니다. 첫 번째는 성능 및 메모리 비용입니다.

Frame at 1519.22s

스트랜드 기반 헤어 렌더링은 많은 리소스를 소모합니다. 정교한 셰이딩 기법이 요구되어 프레임 레이트를 상당폭 저하시킬 수 있습니다.

Frame at 1527.30s

특히 저사양 하드웨어 환경에서 그렇습니다. 더불어 복잡한 헤어스타일은 메모리 사용량이 기하급수적으로 증가할 수 있으며, 이는 Groom assets와 연관된 Binding assets의 복잡성과도 연결됩니다.

Frame at 1544.61s

두 번째로는 'loss maintains'입니다. Groom assets는 강력한 툴을 제공합니다.

Frame at 1550.23s

실제 게임 환경, 특히 콘솔 및 저사양 PC에서는 LOD(Level of Detail)를 제어하는 것과는 별개로, 헤어컷의 카드 기반 버전을 구현해야 합니다. 이때 가장 까다로운 부분은 스트랜드(strand)와 카드(card) 간의 눈에 띄는 품질 저하를 방지하는 것입니다.

Frame at 1564.01s

대부분의 경우 헤어컷을 두 번 만들어야 하는데, 이는 strand와 card를 각각 사용하여 제작 시간을 크게 늘릴 수 있습니다. 이제 card system에 대한 간략한 개요를 살펴보겠습니다. 장점부터 시작하겠습니다. 첫 번째 장점은 다음과 같습니다.

Frame at 1586.01s

자산 전체에 대한 자동화된 strand decimation 대신, 일관된 scalability를 제공합니다.

Frame at 1592.65s

아티스트는 silhouette 보존을 위해 어떤 clamp를 distance에 남길지 정확하게 선택할 수 있습니다. 또한, 헤어컷의 inner layers와 같은 개별 조각에 더 강력한 optimization을 적용할 수 있습니다. 두 번째 장점은 modularity입니다. rigid meshes인 car와 마찬가지로 modular hat이나 outfit를 swapping하는 것이 훨씬 부드럽습니다.

Frame at 1615.12s

And when it comes to clips, ribbons or braids, this also works better with rigid clumps.

Frame at 1620.51s

세 번째 장점은 물론 메모리 사용량입니다. Card-based meshes는 훨씬 더 예측 가능한 메모리 사용량을 가집니다.

단점은 다음과 같습니다. 첫 번째이자 아마도 가장 심각한 단점은 긴 iteration time입니다. Card는 여전히 많은 수작업을 필요로 합니다.

Frame at 1639.83s

얼마 전까지만 해도 게임 내 헤어에 1만~2만 개의 트라이앵글을 사용했지만, 이제는 히어로 캐릭터 헤어에 10만 개까지 사용하는 것이 일반적입니다. 만약 파이프라인이 유연하지 않고 기존 방식으로 헤어를 제작하려 한다면,

Frame at 1655.03s

모든 피드백 루프와 반복 작업이 아티스트에게 끝없는 악몽으로 변할 수 있습니다. 시각적 수정에 5분이 걸리는 동안 기술적 수정에 30분이 소요될 수 있기 때문입니다.

Frame at 1665.03s

두 번째는 렌더링 문제입니다. 카드(card)로는 사실적인 셰이딩(shading) 구현이 훨씬 어렵고, 거기에 더해 알파 블렌딩(alpha-blending)과 예측 불가능한 헤어 섀도잉(hair shadowing) 문제도 여전히 발생하고 있습니다.

Frame at 1680.78s

저희 프로젝트에서는 더 높은 Poly Count 숫자를 유연하게 유지하기 위해 High Poly Hair Creation의 일부 측면을 차용하기로 결정했습니다. 또한, Unreal Engine의 Groom Assets를 활용하여 Automated Binding의 이점을 취함으로써, 더 폭넓은 캐릭터 다양성을 확보할 수 있었습니다.

Frame at 1699.16s

저희의 작업 공정에 대한 간략한 개요를 말씀드리겠습니다. 첫 번째 단계는 ZBrush block out입니다. 이 단계에서 후반 작업의 불확실성을 최소화하기 위해 대부분의 예술적 난제를 초기에 해결하고자 합니다.

다음은 Ornatrix를 사용한 hair guides placement입니다. 메인 캐릭터의 경우 헤어스타일 전체를 Ornatrix 내에서 작업했습니다. NPC의 경우 이 과정은 초기 card placement 속도를 높이기 위한 중간 단계에 가까웠습니다.

card geometry에 대해 간략히 설명드리겠습니다. 여기 두 가지 옵션, proxy cards와 bound cards가 있습니다. hero haircut은 polycount가 훨씬 높아 card가 더 얇고, high polygroom처럼 다루며 procedural modifiers의 이점을 활용할 수 있습니다.

NPC는 낮은 polycount로 인해 card placement와 rotation에 대한 더 세밀한 제어가 필요합니다. 이러한 제어는 Maya의 GS curve plugin 등으로 구현할 수 있습니다.

마지막 단계는 Unreal Engine implementation입니다. NPC와 hero asset 모두 구현 방식은 동일했습니다. 물리(physics) 적용 여부가 유일한 변수였습니다. 물리 적용이 필요한 경우, Groom Assets physics가 저희 시나리오에 너무 비쌌기 때문에 skeletal meshes로 구현했습니다.

실질적인 부분으로 넘어가 ZBrush block out부터 시작하겠습니다. 이 단계에서는 모든 각도에서 헤어스타일의 사진이나 컨셉을 얻기 어려운 경우가 많으므로, 누락된 부분을 파악하고 해결하는 데 중점을 두었습니다. 또한 hair layering, volume, silhouette을 여기서 확립했습니다. 보통 이 단계는 며칠이 소요되었습니다.

Frame at 1816.53s

해결할수록 나중에 추측할 필요가 줄어들었습니다. 이제 식재 가이드에 대해 말씀드리겠습니다.

Frame at 1824.38s

간단한 예시를 통해 시연해 드리겠습니다. 이 단계에서는 앞서 언급한 Ornatrix를 사용하였지만, 다른 하이폴리 헤어 제작 솔루션도 사용 가능합니다. 초기 헤어 배치는 일반적인 형태를 수동으로 트레이싱하여 시작하였고, 나머지 부분은 Ornatrix strands multiplier를 사용하여 채웠습니다. 완성된 주인공의 헤어스타일 예시입니다. 전체 과정을 반복 작업에 용이하게 만들기 위해 여러 개의 groom을 활용하였으며, 개별 clump에 대한 추가적인 제어를 위해 Ornatrix strand groups를 사용하였습니다.

Frame at 1861.33s

From this point, depending on the complexity of the haircut, we had two options. Either use proxy meshes directly in Ornatrix or extract curves and bind cars over them.

Frame at 1874.33s

Hero haircut의 경우, proxy mesh 옵션을 사용하였습니다.

Frame at 1880.83s

이 헤어컷은 poly count가 높아, high poly hair에 적용하는 것과 유사하게 procedural modifiers를 사용할 수 있었습니다. 영웅과 NPC의 헤어컷 복잡성을 비교한 작은 예시입니다.

Frame at 1897.33s

NPC의 경우, hero asset 대비 poly count가 거의 두 배 낮을 것을 이미 인지하고 있었기에 Ornatrix에서 보내는 시간을 줄입니다. 이는 각 card를 더욱 신중하게 배치해야 함을 의미했습니다.

Frame at 1907.83s

이러한 이유로 NPC 헤어스타일의 최종 조정은 Maya에서 수동으로 또는 JS curve plugin을 사용하여 수행되었습니다. 해당 과정에서는 추출된 curve 위에 card를 bind하였습니다.

Frame at 1917.33s

Ornatrix에서.

Frame at 1923.33s

Hero와 NPC 헤어스타일의 간략한 비교입니다. 짧은 머리, 수염, 퍼(fur)의 경우, 생성 과정을 최대한 절차적으로(procedural) 유지하려 노력했습니다. 이러한 유형의 헤어스타일은 더 중요했기 때문입니다.

Frame at 1942.23s

전반적인 룩을 제어하는 데 중점을 두었으며, 세부적인 부분에 집착할 필요가 없었습니다. 이 단계에서 디테일한 블록아웃이나 수동 가이드 배치 작업은 불필요했습니다. 접근 방식은 하이폴리 헤어 제작과 동일했지만, 대신에

Frame at 1958.43s

스트랜드(strands)의 출력 결과는 프록시 메쉬(proxy meshes)였습니다. 여기서 저는 어떻게

Frame at 1964.09s

고폴리 Groom 위에 프록시 메시(proxy meshes)를 적용하였습니다. 이 경우, 헤어스타일은 Modifier들로부터 많은 다양성이 파생되었기 때문에 몇 가지 다른 카드(cards)만으로 충분했습니다. 긴 머리에서처럼 가이드(guide)마다 하나의 카드를 할당하는 대신, 짧은 머리에서는 카드의 수가 스트랜드(strands)의 양에 의해 제어되었습니다. 이 접근 방식을 통해 프로시저럴 Modifier를 사용하여 자연스러운 분산과 다양성을 도입할 수 있었습니다. 물론 Modifier의 효과는 카드의 밀도(density)와 카드 크기(card size)에 따라 달라집니다. 또한 짧은 머리의 경우, 최종 외형의 상당 부분은 Groom에서 베이크(baked)된 헤어 쉘 텍스처(hair shell texture)에서 나왔는데, 이는 나중에 변환되었습니다.

Frame at 2009.95s

오케이, 이제 언리얼 엔진 파트로 넘어가겠습니다. Groom export의 경우 Ornatrix를 사용했습니다.

Frame at 2020.13s

Alembic 및 자동차 Geometry는 단순한 static mesh로 Export되었습니다. 이전에 언급했듯이, 캐릭터의 Strands는 Cinematic에서도 사용하지 않았습니다. 몇 가지 Engine modification을 통해 LOD 0부터 Strands 대신 자동차를 표시할 수 있었습니다. 이를 위해 네 개의 LOD를 사용하였으며, 각 LOD는 이전 LOD 대비 50% 이상씩 줄였습니다. 마지막 LOD에서는 solid shell로 전환하였습니다.

Frame at 2048.33s

슈퍼 최적화된 셰이더 버전의 메시를 사용하였습니다. 하지만 눈썹과 같은 경우, 저희는 약간 다른 접근 방식을 채택했습니다. NPC 캐릭터의 경우, 저희는 카드(cards)를 다음과 같은 방식으로만 유지했습니다.

Frame at 2060.39s

LOD 0 및 기타 모든 LOD는 눈썹 쉘 텍스처에 전적으로 의존하였습니다.

Frame at 2066.85s

얼굴 수염의 경우, 모든 변형에 대해 새로운 Alembic setup을 export 할 필요가 없었습니다. 여러 실험 끝에, 본 그림에서 보시는 바와 같이 표준화된 setup을 마련하였으며, 이는 저희 작업물의 90%에 사용되었습니다.

Frame at 2083.50s

헤어컷은 각 변형마다 고유한 Alembic setup을 생성해야 했기에 더 복잡했습니다. 유연성을 유지하기 위해

Frame at 2101.17s

texture usage 및 texture specking 관련하여, groom asset 내부에서 texture inputs를 사용하지 않기로 결정하였습니다. 대신 shader adjustments를 진행하였으며, hair attribute node를 활용하여 정보를 전달하였습니다.

Frame at 2109.63s

the groom into the material and that allowed us to override attributes directly from the material instance. To create more natural looking hair to skin

Frame at 2121.55s

transition we used hair shell textures. As long as character haircut doesn't

Frame at 2127.44s

헤어스타일 변경 시 쉘(shell)은 헤드 텍스처에 직접 페인팅될 수 있습니다. 일반적인 방식은 헤드 메시 위에 추가적인 쉘 토폴로지를 덧입히는 것이었습니다. 하지만 MetaHuman LOD1에서도 추가 토폴로지가 최적의 해결책이었습니다.

Frame at 2144.60s

헤드 토폴로지는 이미 상당히 밀집되어 있으며, 모든 필요한 영역을 쉘(shells)로 커버하면 각 LOD(Level of Detail)별로 헤드 에셋의 폴리곤 수가 거의 두 배로 증가할 것입니다.

Frame at 2153.46s

더불어, shell mesh는 최소 세 개의 추가 draw call을 발생시킬 수 있습니다.

Frame at 2158.46s

언리얼 엔진은 Masked Alpha를 헤어에 사용하는데, 눈썹이나 잔머리와 같이 가는 머리카락 표현에는 사용하기 매우 어렵다는 점을 고려해야 합니다.

Frame at 2167.46s

이러한 이유로 다른 해결책을 선택했습니다. 추가적인 topology 대신 head mesh에 second UV set을 사용하였습니다.

Frame at 2176.46s

이 설정으로 모든 헤어 쉘(hair shells)은 헤드와 함께 단일 Draw Call을 공유하게 되었습니다. 마스크드 메시(masked mesh) 대신 스킨 텍스처(skin texture)와 직접 블렌딩(direct blend)되기 때문에 짧은 머리카락도 표현할 수 있게 되었습니다. 이제 그룸(groom) 최적화에 대해 몇 가지 말씀드리겠습니다.

Frame at 2194.96s

사용된 자동차(used cars)에는 스트랜드(strands)를 사용하지 않았습니다. 다음으로, 낮은 LOD(Level of Detail)에서는 스킨드(skinned) 대신 리지드 모드(rigid mode)로 전환하고 인스턴스 버퍼(per instance buffers)를 정리했습니다. 셋째, 부모 바운드(parent bounds)를 사용하고 가능한 경우 티킹(ticking)을 비활성화했습니다. 마지막 LOD의 경우, 폴백(fallback)으로 간단한 스태틱 메시 셸(static mesh shell)을 사용했습니다. 마지막 LOD를 위해 최적화된 셰이더 버전(optimized shader version)으로 전환하기도 했습니다. 그리고 가장 중요한 최적화는 시칠리아의 태양(Sicilian Sun)입니다. 저희 게임 속 사람들은 대부분 모자를 쓰고 있습니다. 이제 저희 헤어컷의 몇 가지 예시를 공유해 드리고자 합니다.

Frame at 2250.55s

NPC 헤어스타일 렌더링 예시입니다. 또한 다른 NPC 헤어스타일도 보실 수 있습니다. 여기는 영웅 헤어스타일의 예시입니다. 또 다른 영웅 헤어스타일과 짧은 영웅 헤어스타일도 준비되어 있습니다.

Frame at 2268.42s

원본 Mafia 게임에는 특정 조건에서 발견할 수 있는 작은 이스터 에그가 있었습니다.

Frame at 2273.52s

플레이어는 개의 모자를 착용할 수 있었습니다. 이는 추후 Baskerville Outfit으로 알려지게 되었습니다. 이처럼 전통을 이어가고 있습니다. 따라서 이 asset 또한 다음과 같이 제작되었습니다.

Frame at 2286.82s

MetaHuman을 사용했습니다. 필수는 아니었지만 재미를 위해 시도했습니다. Fur는 Ornatrix 내에서 grooming되었으며, 실제로는 cards로 구현되었습니다. 마지막으로 말하는 강아지가 등장하는 짧은 컷씬을 보여드리겠습니다.

Frame at 2303.96s

읽으실 수 있을지 확신하지 못했습니다. 그래도 기회를 잡으셨군요.

Frame at 2312.08s

했습니다.

Frame at 2316.60s

저에게 왜 편지를 쓰셨습니까?

Frame at 2318.43s

'어째서 오셨습니까?'

Frame at 2321.81s

싸움에 대해 사과드리고 싶습니다. 그런 일은 일어나지 말았어야 했습니다.

Frame at 2329.11s

맞습니다.

Frame at 2330.63s

네, 그렇습니다. 그저... 무엇일까요? 아마 좋은 생각이 아닐지도 모릅니다. 그러한 미팅은 말입니다.

Frame at 2342.31s

이와 같이 사람들은 이야기할 수 있습니다.

Frame at 2346.52s

그들이 뭐라고 말하겠습니까?

Frame at 2350.25s

I have to be careful and work hard. Your father is who he is.

Frame at 2356.75s

"그리고 당신은 누구십니까, Enzo?"

Frame at 2359.75s

저의 아버지가 이미 당신의 삶을 조종하고 있습니까?

Frame at 2364.52s

MetaHuman으로 창의력을 마음껏 발휘하실 수 있습니다. 마지막으로, 화면에 등장한 모든 팀에게 감사의 말씀을 전하고 싶습니다. 그들의 노고와 MetaHuman 여정 동안 보여주신 엄청난 지원에 깊이 감사드립니다. 여러분의 관심에도 감사드립니다.