본문 바로가기
이펙트 (FX)/이펙트 팁 : Houdini

[Houdini] Mortal Kombat 11: A Bloody Production Talk | Matt Battaglia | SIGGRAPH 2019 소개 (모탈컴뱃, 시그래프)

by Minkyu Lee 2026. 8. 13.

개요

모탈 컴뱃에서 사용한 후디니를 활용한 리얼타임 엔진용 테크닉을 소개한다.

 

내용

  • 영상 제목: Mortal Kombat 11: A Bloody Production Talk | Matt Battaglia | SIGGRAPH 2019
  • 채널명: Houdini
  • 영상 링크: https://youtu.be/k8_6PmSKF2U

 

핵심 요약

NetherRealm Studios가 《모탈 컴뱃 11(Mortal Kombat 11)》 제작 과정에서 후디니(Houdini)를 파이프라인의 핵심 도구로 구축하고 실시간 게임 환경(60fps, 엄격한 메모리 예산)의 제약 조건을 극복한 기술적 사례 발표입니다.

  • 실시간 혈액(Blood) FX 및 지오메트리 캐시 최적화: Vertex Animation Texture(VAT)의 가변 포인트 수 한계를 극복하기 위해 Alembic 기반의 자체 Geometry Cache 포맷(Heterogeneous Case)을 구축했습니다. UV 및 Tangent 데이터를 완전 제거하고 위치(Position) 데이터를 4바이트로 양자화(Quantization)하여 데이터 용량을 1/3로 절감했습니다. Houdini FLIP 시뮬레이션 후 Particle Fluid Surface, Lattice, Delete Small Parts, PolyReduce 노드 워크플로우와 Attribute Transfer를 거쳐 두께 마스크(Thickness Mask) 기반 역광 발광 연출을 구현했습니다.
  • 대규모 해양(Ocean) 시스템: 스토리 모드의 대규모 바다 연출을 위해 고해상도 타일 패치를 4방향 복제 후 노멀을 일치시키고, 수평선 방향으로 폴리곤을 감축하는 Skirt Mesh를 제작했습니다. Ray SOP과 VOP 노드망을 활용해 경계면의 디스플레이스먼트와 노멀을 수직 방향(0)으로 부드럽게 감쇄하는 가성비 높은 구조를 완성했습니다.
  • 루핑(Looping) 및 Wet Map 기술: VDB 시뮬레이션 루핑 시 발생하는 아티팩트를 방지하기 위해 Standard Volume 변환 후 Time Shift/Volume Mix를 거쳐 재변환하는 트릭을 적용했습니다. 또한 Solver SOP을 통해 유체 충돌 지점의 젖음 속성을 프레임별로 누적하고 COPs 기반 플립북으로 변환하여 실시간 Wet Map을 구동했습니다.
  • Volume Slicer HDA 및 절차적 VFX: 화면 전체를 덮는 거대한 연기 효과의 알파 오버드로(Overdraw) 이슈를 해결하기 위해 카메라 클립 플레인을 조절하는 Volume Slicer HDA를 자체 개발했습니다. 단 3장의 슬라이스 카드와 모션 벡터 보간을 통해 0.3ms(Xbox)의 극저비용 고효율 연출을 달성했습니다. 그 외에도 For-Each 기반 UV 스트립 라이트닝, 파티클 속도 기반 스파크 모션 블러(Point Cache), 수천 개 촛불 화염의 절차적 배치 기법을 제시했습니다.

 

타임라인

1. 서론 및 Houdini 도입 배경 (00:00:00 ~ 00:02:21)

  • 발표자 및 스튜디오 소개: NetherRealm Studios의 Technical Art Lead인 Matt Battaglia와 핵심 기여자인 Aaron Gore의 기술 발표입니다. [00:14]
  • 파이프라인 전환 계기: 2016년부터 VFX 및 파이프라인 보조 도구로 후디니를 검토하기 시작했으며, 페이탈리티(Fatality) 등 복잡하고 독특한 시네마틱 연출 요구사항을 해결하며 메인 파이프라인으로 자리 잡았습니다. [01:15]
  • 아트 디렉션 목표: 고어(Gore) 표현이 핵심인 모탈 컴뱃 11의 시네마틱 혈액 연출 수준을 한 단계 끌어올리는 것을 주 목표로 설정했습니다. [02:09]

2. 실시간 혈액(Blood) FX 및 지오메트리 캐시 최적화 (00:02:22 ~ 00:08:22)

  • 비주얼 아트 디렉션 요구사항: 압도적인 혈액 양, 카메라 근접 배치, 슬로모션 연출(Slow-mo choreography), 유체역학적 사실성, 하이 콘트라스트 역광(Backlit) 투과감, 세밀한 아트 디렉팅 수용성이 필요했습니다. [02:41]
  • R&D 및 VAT 기법의 한계: 기존 플립북, 알파 이로전(Alpha Erosion), 메시 파티클 방식으로는 유체 질감을 얻기 어려웠습니다. SideFX의 Vertex Animation Texture(VAT) 기법을 프로토타이핑하였으나, 프레임 변화에 따라 포인트 수가 500개에서 60,000개까지 급증하는 혈액 특성상 텍스처 기반 저장 방식의 한계가 발생했습니다. [03:30]
  • 자체 Geometry Cache 시스템 구축: Alembic 데이터를 기반으로 런타임 전용 지오메트리 캐시 시스템을 제작했습니다. [04:27]
    • Homogeneous Case: 깃발처럼 프레임 간 토폴로지가 동일한 경우로, 프레임 간 애니메이션 압축을 적용합니다.
    • Heterogeneous Case (Mesh Flipbook): 혈액처럼 프레임마다 토폴로지가 전면 교체되는 경우로, 극도의 데이터 압축이 요구됩니다.
    • Point Cache: 파티클 시스템 연동용 포인트 데이터 전달 체계입니다.
  • 메모리 압축 및 양자화(Quantization): 45프레임 혈액 애니메이션 원본(28MB)을 실시간 메모리 예산에 맞추기 위해 최적화를 진행했습니다. [05:24]
    • UV 및 Tangent 데이터 제거: 단색 유체 특성상 노멀 맵과 UV 텍스처링이 불필요하므로 관련 데이터를 완전히 Stripping 했습니다.
    • 위치(Position) 데이터 양자화: 12바이트 위치 데이터를 4바이트로 대폭 양자화했습니다. 위치 오차가 일부 발생하지만 유체 특성상 시각적 차이가 감지되지 않아 버퍼 용량을 1/3로 절감했습니다.
  • Houdini FLIP 시뮬레이션 및 후처리 워크플로우: [06:40]
    • Particle Fluid Surface SOP: Dilate, Erode, Smooth 파라미터를 조절하여 PolyReduce 노드에 입력될 토폴로지 구조를 최적화했습니다.
    • Lattice SOP: 재시뮬레이션 없이 시뮬레이션 결과의 형태를 직접 조형(Sculpt)하여 연출 요구사항을 맞췄습니다.
    • Delete Small Parts SOP (GameDev Shelf): 폴리곤 리덕션 시 걸림돌이 되는 미세 파티클 잔해들을 손쉽게 제거했습니다.
    • PolyReduce 및 Attribute Transfer: PolyReduce 적용 후 위치/노멀 블러를 가하고, High-Poly에서 Low-Poly 메시로 Attribute Transfer를 수행하여 프레임 간 발생하는 시각적 아티팩트(Temporal artifacts)를 완화했습니다.
  • 런타임 메모리 예산: 게임 전체 시네마틱에 쓰이는 15개의 혈액 라이브러리가 상시 글로벌 메모리(155MB)에 로드되어 모든 페이탈리티와 크러싱 블로우 연출에서 재활용됩니다. [07:59]

3. 혈액 셰이딩 및 런타임 제어 (00:08:23 ~ 00:10:14)

  • User Channels 기반 정점 데이터 활용: 버텍스 데이터 내 임의의 속성을 담을 수 있는 User Channel을 활용하여 런타임 제어권을 확보했습니다. [08:31]
  • 두께 마스크(Thickness Mask) 추출: 반전된 메시 노멀(Inverted Mesh Normal) 방향의 Raycast 결과값과 Curvature(곡률) 정보를 조합하여 두께 마스크를 계산한 뒤 User Channel에 탑재했습니다. 런타임 머티리얼은 이 값을 통해 발광(Emissive) 및 가짜 역광(Fake Backlit) 투과 효과를 블렌딩합니다. [09:10]
  • 에디터 상의 오버레이 조작: 스태틱 메시 형태로 씬에 스폰하여 위치, 회전, 스케일을 손쉽게 조정할 수 있으며, 동일 라이브러리 내 다른 캐시 메시로 즉시 교체 가능합니다. 기본 애니메이션 위에 추가적인 전통적 키프레임 애니메이션 레이어링도 지원합니다. [09:39]

4. 스토리 모드 대규모 해양(Ocean) 제작 파이프라인 (00:10:15 ~ 00:13:36)

  • 제약 조건 및 접근법: 스토리 모드 환경에서 수평선까지 퍼지는 해양 연출이 필요했습니다. 프로젝트 후반부 R&D 특성상 Gerstner Waves나 FFT 방식을 신규 구현할 시간이 부족하여 기존 타일링 트릭과 후디니 노드를 결합했습니다. [10:21]
  • 타일링 패치 및 Skirt Mesh 구조: [11:08]
    • Ocean Patch: 근경용 고해상도 타일 패치.
    • Skirt Mesh & Horizon Extension Mesh: 중앙 패치 외곽에서 수평선 방향으로 점진적으로 폴리곤 밀도를 낮추는 전이용 지오메트리.
  • 시밀리스 타일링 노드 워크플로우: 중앙 타일 패치를 4방향으로 복제/트랜스레이트한 후 Attribute Transfer SOP을 실행하여 외곽 경계선의 노멀과 위치를 완벽히 일치시켜 봉합선(Seam) 없는 타일링을 완성했습니다. [11:55]
  • Raycast 및 VOP 디스플레이스먼트 블렌딩: [12:14]
    • Skirt Mesh 내부 포인트 그룹을 지정하여 PolyReduce SOP으로 외곽 폴리곤을 감축했습니다.
    • 복제된 타일 패치 지오메트리에 Ray SOP을 실행하여 수직 디스플레이스먼트(Vertical Displacement)를 클린 지오메트리로 투사했습니다.
    • VOP 노드망을 구축하여 Skirt Mesh 외곽 경계로 갈수록 디스플레이스먼트 값을 0으로, 노멀 방향을 완벽한 수직(Up Vector)으로 Smooth Blend 처리하여 수평선 메쉬와 부드럽게 연결했습니다.

5. 환경 VFX 루핑 및 Wet Map(젖음 효과) 구축 (00:13:37 ~ 00:17:23)

  • VDB 시뮬레이션 루핑 트릭: 일반적인 VDB 타임 루핑 노드 적용 시 VDB 최적화 데이터 구조 특성상 아티팩트가 발생했습니다. 이를 해결하기 위해 VDB를 Standard Houdini Volume으로 변환한 뒤 Time Shift 및 Volume Mix로 블렌딩하고, 다시 VDB로 변환하는 복원 공정을 적용했습니다. [13:55]

 

  • 실시간 Wet Map (젖음 효과) 파이프라인: 60Hz 스테이지 환경의 유체 충돌 연출입니다. [15:06]
    • 충돌 지오메트리 정제: 복잡하게 얽힌 환경 지오메트리를 VDB Convert -> VDB Merge -> Convert to Polygon 공정을 거쳐 단일 클린 충돌 지오메트리로 재구성했습니다.
    • 영역 제어: Kill Volume 및 파티클 속성 삭제 조건을 적용하여 유체가 불필요한 영역으로 튀는 것을 방지했습니다.
    • 포인트 데이터 최소화: 충돌 지오메트리와 교차하거나 인접한 포인트만 추출하여 연산량을 감소시켰습니다. [16:15]
    • Solver SOP 누적 시스템: 유체의 Wet 속성과 지오메트리의 Dry(0) 속성을 Solver SOP 내부에서 프레임 단위로 Attribute Transfer하여 젖음 데이터를 프레임별로 누적(Accumulate)시켰습니다.
    • COPs 및 플립북 출력: COPs(Compositing Operators)를 통해 4x4 플립북 이미지 시퀀스로 렌더링하고, 런타임 셰이더에서 프레임 간 보간을 가해 퍼져나가는 젖음 효과를 표현했습니다.

 

6. 절차적 라이트닝 및 Volume Slicer HDA (00:17:24 ~ 00:22:25)

  • 절차적 라이트닝(Lightning) 제작: [17:24]
    • 입력 지오메트리의 무작위 트라이앵글을 포인트로 축소 후 커브 생성 및 Jitter를 적용했습니다.
    • Sweep SOP으로 게임용 메시를 생성한 뒤, For-Each Loop를 통해 각 번개 줄기의 UV를 스트립 형태(Strip UV)로 일렬 정렬했습니다.
    • 런타임 셰이더에서 U 방향 노이즈 패닝으로 번개의 출현을 제어하고, V 방향 노이즈 패닝으로 버텍스 셰이더 지터링을 구동했습니다.
  • Volume Slicer HDA (로켓 연기 플룸 최적화): [18:43]
    • 문제점: 화면 전체를 덮는 거대한 로켓 배기 연기는 전통적인 3D 파티클 기법 적용 시 극심한 알파 오버드로(Overdraw)로 인해 실시간 성능이 크게 저하되었습니다.
    • Volume Slicer 개념 도입: Andreas Glad의 Volume Slicer 개념을 착안하여 카메라 클립 플레인(Clip Planes)을 조절하여 볼륨 데이터를 여러 단면 카드(Slice Cards)로 분할 렌더링하는 HDA를 제작했습니다.
    • HDA 가시화 기능: HDA 카메라를 뷰포트에 고정하고 체커보드 및 스티플링 형태로 각 슬라이스 영역과 절단면 렌더링을 시각적으로 프리뷰할 수 있도록 구축했습니다.
    • 모션 벡터 연장 및 성능 결과: 단 3장의 슬라이스 카드, 4Kx2K 컬러 맵, 2Kx1K 모션 벡터 맵을 활용했습니다. 모션 벡터 데이터가 타임워프 시 비틀어지는 문제를 해결하기 위해 런타임 머티리얼의 Distortion 파라미터 키프레임을 맞췄으며, 64프레임 시뮬레이션을 224프레임 동안 연장 재생했습니다. 그 결과 Xbox 기준 최악 조건에서도 0.3ms의 극저비용을 달성했습니다.

7. 기타 실시간 VFX 및 질의응답 (00:22:26 ~ 00:27:37)

  • Pyro 플립북 파라미터 변형: 동일한 Pyro 시뮬레이션 환경에서 파라미터 조절만으로 3가지 버전의 플립북을 생성하고, 수동 배치 카드와 소량의 파티클을 조합하여 대형 폭발/연기를 연출했습니다. [22:26]
  • Point Cache 파이프라인 (로봇 스파크): POP 시뮬레이션으로 로봇 지오메트리와 충돌하는 불꽃 파티클을 생성했습니다. Wrangle 노드로 파티클 소멸 조건을 계산한 후, 속도(Velocity) 데이터를 User Channel로 내보내 엔진 내 스프라이트 지오메트리를 모션 블러처럼 스트레칭(Stretch) 표현했습니다. [23:05]
  • 절차적 촛불 배치: 스테이지 내 수천 개의 촛불 메시 심지 위치에 절차적으로 포인트를 배치하고 스프라이트 화염을 일괄 연결하여 배치 작업을 자동화했습니다. [24:15]
  • 질의응답 (Q&A): [25:00]
    • Houdini 사용 인원 변천: 2016년 2명(Matt Battaglia, Aaron Gore)의 주도로 시작하여, 현재는 스튜디오 내 5명의 VFX 아티스트 전체가 업무에 후디니를 적극 활용 중입니다.
    • Houdini Engine 미도입 이유: 프로젝트 특성상 일회성 연출 에셋이 많아, HDA 제작 및 교육 비용보다 직접 구축 후 적용하는 편이 생산성 측면에서 유리하다고 판단했습니다.
    • Wet Map 데이터 매핑: 충돌 지오메트리의 UV 좌표에 Attribute Transfer 결과를 사전에 재투사하여 런타임 머티리얼에서 읽어들이는 방식을 사용했습니다.

댓글