피벗 페인터 툴 2.0

인터랙티브 애니메이션용 버텍스 안에 모델 피벗과 회전 데이터를 저장하는 피벗 페인터 2.0 MAXScript 가이드입니다.

Choose your operating system:

Windows

macOS

Linux

피벗 페인터 2.0(Pivot Painter 2.0) MAXScript는 모델의 텍스처에 피벗 및 회전 정보를 저장합니다. 해당 텍스처를 언리얼의 셰이더 시스템에서 참조하여 인터랙티브 이펙트를 만들 수 있습니다.

샘플 영상에 보이는 모션은 버텍스 셰이더를 이용해 실시간으로 절차적 생성된 것입니다. 피벗 페인터 머티리얼 함수는 모델의 잎과 가지에 대한 모션 상속 정보를 형성합니다. 각 엘리먼트에 적용되는 애니메이션에는 자체 개별 피벗 포인트, 방향 벡터, 바운드 크기, 상속된 모션이 사용됩니다. 그 결과 부드럽고 사실적인 애니메이션이 나옵니다.

피벗 페인터 2의 머티리얼 함수가 추가되어 해당 유형의 머티리얼 제작이 훨씬 간단해졌습니다. 콘텐츠 예제에 제공된 것과 같은 샘플 콘텐츠로 위와 같은 기능을 지닌 애니메이션을 어떻게 만드는지 볼 수 있습니다. 이제 서브 오브젝트 피벗 포인트가 필요하면 3D 스튜디오 맥스(3D Studio Max)에서 피벗 페인터 스크립트로 메시를 처리하고, 파일을 임포트한 뒤 적절한 피벗 페인터 함수를 사용해 머티리얼을 만들면 됩니다. 샘플 폴리지 모션 머티리얼 함수는 최대 4레벨의 계층구조와 30,000개의 모델 엘리먼트를 지원합니다.

이렇게 모션을 만들었을 때의 장점이 있습니다. 이 기법으로 처리한 모델은 UV 채널을 표준 스태틱 메시보다 1개만 더 사용하는 반면, 애니메이션을 실시간으로 계산하므로 스켈레탈 애니메이션보다 훨씬 적은 비용을 소모합니다. 모델에 있는 버텍스의 수가 모델이 그리는 픽셀 수보다 훨씬 적기 때문에, 대개 버텍스 셰이더의 인스트럭션 수는 픽셀 인스트럭션 수보다 그래픽 측면에서 퍼포먼스 문제가 덜 발생합니다.

해당 페이지에서 선보인 예제를 몇 가지 살펴보려면 에픽게임즈 런처에서 콘텐츠 예제 프로젝트를 다운로드하고 PivotPainter2 맵을 여세요.

CE_PivotPainter2Map.png

피벗 페인터 2.0 에서 새로워진 점

피벗 페인터 2.0 출시 이후, MAXScript에 약간의 향상 및 변화가 있었을 것입니다. (계층구조 페인터처럼) 삭제되거나 (오브젝트별 페인터를 버텍스 알파 페인터로 바꾼 것처럼) 이름이 바뀐 옵션도 있는 한편, 디테일한 에셋 유형을 만드는 프로세스를 단순화할 수 있게 전반적인 워크플로를 향상했습니다. 이전보다 훨씬 좋은 결과물을 위해 피벗 페인터 2의 성능을 강화한 덕에, 이제 사용자 여러분도 콘텐츠를 만들면서 폭넓은 옵션을 사용하실 수 있습니다! 추가 개선점은 아래를 참고하시기 바랍니다.

워크플로 개선 사항

리깅 사전 처리 단계는 오토데스크 3ds 맥스(Autodesk 3ds Max)의 표준 링크(Link) 툴을 통해 이루어집니다. 단순한 나무 모델링은 별도로 진행하고, 잎과 가지는 논리 엘리먼트로서 진행합니다. 피벗의 위치와 방향이 (X축이 오브젝트의 길이와 맞닿음) 맞게 되었는지 확인하고 기존 리깅처럼 하나로 링크하세요.

그 결과 복잡한 폴리지를 훨씬 간단하게 만들 수 있습니다. 가지 하나에 리깅을 하고 복제한 뒤 배치합니다. 부모를 변경한 가지는 그 자식의 계층구조 배치도 유지합니다.

나무 리깅과 모델링을 완료했으면 나무의 엘리먼트 중 어느 것이든 선택한 뒤, 렌더 옵션(Render Options) 섹션의 선택한 오브젝트 계층구조 처리(Process The Selected Object Hierarchy) 버튼을 누릅니다. 스크립트에서 선택된 엘리먼트 계층구조를 자동으로 탐색하여 루트를 알아낸 뒤, 체인을 거슬러 올라가며 모든 자손을 수집하고 처리한 다음, 마지막으로 선택된 렌더 옵션의 데이터를 사용해 텍스처를 렌더링합니다.

ScriptMotion_UI.png

해당 메서드는 개별 및 연결된 엘리먼트 모두 동시에 지원합니다. 풀과 나무가 합쳐진 모델의 경우, 모든 풀잎을 한꺼번에 선택한 뒤 나무에서 엘리먼트를 하나 선택하고 선택한 오브젝트 계층구조 처리(Process Selected Object Hierarchy) 버튼을 클릭합니다.

텍스처 좌표 제어

이제 어느 UV를 작성할지 제어하여, 해당 시스템을 버텍스 애니메이션 툴 같은 대상과 결합할 수 있습니다. 또한 피벗 페인터 2.0에서 선택한 환경설정은 최종 출력 텍스처 이름에 명시되어 기억을 되살려 줍니다.

자동 명명 규칙은 다음과 같습니다:

[메시 이름]_rgb_[현재 텍스처 RGB 선택]_a_[알파 선택]_[UV 채널]

최종 출력 예제는 다음과 같습니다.

ExampleMesh_rgb_PivotPos_a_ParentIndex_UV_2

확장성

코드의 처리 및 렌더링 과정을 철저히 추상화하여, 앞으로 새 렌더링 옵션을 추가할 때 드는 노력을 최소화했습니다.

새 렌더링 옵션

MAXScript에 대한 개선 사항 중 일부로 씬 내부에 사용되는 비트 시프트 알고리즘을 추가했습니다. 이 알고리즘은 integer를 float 데이터로 저장합니다. 덕분에 계층구조의 깊이 있는 구성이 가능해지고, 복잡한 폴리지를 표현하는 데 필요한 최대 오브젝트 수가 3,000개에서 30,000개로 늘었습니다.

이 나무 에셋에는 14,431개의 서브 모델이 있습니다.

  • 16비트 RGB:

    • 피벗 포인트 위치

    • 원점 위치

    • 원점 범위

  • 8비트 RGB:

    • 오브젝트 기본 벡터(한 번에 벡터 하나)

  • 16비트 알파:

    • 부모 인덱스(Int를 float로)

    • 루트에서 비롯한 여러 스텝

    • 엘리먼트당 0-1 랜덤 값

    • 바운딩 박스 지름

    • 선택 순서 (Int를 float로)

    • 노멀화된 0-1 계층구조 위치

    • 피벗 위치에서부터 오브젝트 X, Y, Z의 바운드 길이

    • 부모 인덱스(Float - 최대 2048)

  • 8비트 알파:

    • 노멀화된 0-1 계층구조에 위치

    • 엘리먼트당 0-1 랜덤 값

    • 오브젝트 X, Y, Z의 바운드 길이(최대 2048)

바운딩 박스 재생성

3ds Max를 사용할 경우, 모델링 프로세스 도중 서브 오브젝트의 지오메트리가 옮겨지면서 모델의 바운딩 박스가 확장됩니다. 이제 오브젝트의 바운딩 박스가 더이상 해당 프로세스 도중 메시를 향하거나 정렬되지 않도록 바뀌었습니다. 메시의 피벗 트랜스폼을 변경할 때도 같은 일이 일어납니다. 이 문제를 해결하기 위해, 선택한 메시의 바운딩 박스를 메시 피벗 포인트에 맞게 적절히 방향 변경 및 정렬된 바운딩 박스를 바운딩 박스 재생성(Recreate Bounding Boxes) 섹션으로 대체합니다. 이는 다른 데이터의 수집 기능(버텍스 알파 페인터, 바운드 정보)을 하는 스크립트로 사용할 때도 아주 유용합니다.

BoundingBox.png

왼쪽 그림을 보시면 모델의 피벗 트랜스폼이 변경되었지만, 평행 및 방향 설정이 잘못되었습니다. 반면 바운딩 박스 재생성(Recreate Bounding Boxes) 섹션의 선택 오브젝트 처리(Process Selected Objects) 버튼을 누른 경우, 오른쪽 모델처럼 평행 및 정렬 처리가 제대로 완료되었습니다.

선택된 모델의 노멀 병합

선택된 모델의 노멀 병합(Merge Selected Model's Normals) 기능은 다수의 열린 에지 버텍스가 서로 포개진 경우 모델들의 노멀 평균값을 구하는 기능입니다. 해당 옵션으로 하나의 모델을 (특히 피벗 페인터에서 쓰기 위해) 여러 조각으로 나눌 때 발생하는 노멀 간 이음새 관련 문제를 해결할 수 있습니다.

MergeMeshNormalsButton.png

이전

이후

메시 노멀 병합(Merge Mesh Normals) 버튼을 눌러 접해있는 열린 면의 노멀을 조정합니다.

노멀을 병합하기 전 각 면에 평행을 맞춥니다. 병합 이후 평행이 더욱 잘 맞아 에지가 보다 자연스럽게 블렌딩됩니다.

3ds Max 버전 및 스크립트 정보

이 툴은 현재 3ds Max 20152016 으로 테스트했습니다. 다른 3ds MAX 버전을 구체적으로 테스트하지 않았기에 문제가 발생할 수 있다는 점 참고하시기 바랍니다.

MAXScript는 [UE5Directory]/Engine/Extras/3dsMaxScripts/PivotPainter2.ms 에서 해당 파일을 찾아 3ds MAX의 뷰포트로 드래그 앤 드롭하면 저절로 실행됩니다.

이 스크립트를 자주 사용한다면 언제든 툴바나 쿼드 메뉴에 추가하면 됩니다. 방법을 잘 모르겠다면 과정을 설명하는 오토데스크(Autodesk)아주 자세한 안내서를 참조하세요.

3ds Max 단위 설정

툴을 사용하기에 앞서 3ds Max에서 사용하는 척도 단위가 언리얼 엔진에서 사용하는 척도 단위와 일치하도록 설정해야 합니다. 같은 단위를 설정하면 3ds Max에서 익스포트한 데이터를 에디터에서도 동일한 방식으로 작업할 수 있습니다. 에디터에서는 기본 척도 단위로 센티미터를 사용하므로, 3ds Max에서도 센티미터를 사용하는지 확인해야 합니다. 3ds Max에서 해당 설정을 바꾸는 방법은 다음과 같습니다.

  1. 3ds Max를 열고 메인 툴바에서 커스터마이즈(Customize) > 단위 설정(Unit Setup) 을 선택합니다.

  2. 다음으로 시스템 단위 스케일(System Unit Scale) 섹션의 시스템 단위 설정(System Unit Setup) 버튼을 클릭합니다. 드롭다운을 사용하여 세팅을 인치(inches) 에서 센티미터(centimeters) 로 변경합니다. 그리고 확인(OK) 버튼을 클릭합니다.

  3. 마지막으로 단위 스케일 표시(Display Unit Scale)일반 단위(Generic Units) 로 변경하고 확인(OK) 버튼을 누릅니다.

에셋 임포트

에셋을 임포트할 때 최적의 결과를 얻기 위해 알아둬야 하는 사항이 몇 가지 있습니다. 스태틱 메시텍스처 는 다음과 같이 설정하세요.

스태틱 메시

임포트 옵션(Import Options) 창에서 스켈레탈 메시(Skeletal Mesh) 옵션을 비활성화하고 메시 합침(Combined Meshes) 옵션을 활성화합니다.

스태틱 메시 임포트 옵션

이미지를 클릭하면 최대 크기로 볼 수 있습니다

  • 스켈레탈 메시: 비활성화

  • 메시 결합: 활성화됨

[선택사항] 스태틱 메시 빌드 세팅

이미지를 클릭하면 최대 크기로 볼 수 있습니다

  • 프로젝트에서 메시 디스턴스 필드(Mesh Distance Fields) 옵션을 활성화한 경우, 스태틱 메시 에디터 빌드 세팅에서 양면인 것처럼 디스턴스 필드 생성(Generate Distance Field as if Two-Sided) 옵션도 켜는 것이 좋습니다. 단, 콘텐츠에 따라 디스턴스 필드를 활성화하지 않는 편이 좋을 수도 있습니다. 이 경우 디스턴스 필드 해상도 스케일(Distance Field Resolution Scale) 을 0으로 설정하거나, 레벨 디테일(Level Details) 패널에서 디스턴스 필드 라이팅에 영향(Affect Distance Field Lighting) 옵션을 비활성화하면 됩니다.

  • 일부 콘텐츠에서 잎이 원래 위치를 벗어날 경우, 최대 정밀도 UV(Full Precision UVs) 옵션을 활성화해야 할 수도 있습니다.

업데이트할 때마다 리임포트 옵션 대신 ‘전체' 리임포트(기존 모델 덮어쓰기)를 추천합니다. 머티리얼 관련 문제를 피하는 가장 안전한 방법입니다.

텍스처

피벗 페인터 2.0으로 생성한 텍스처를 임포트한 후에는 텍스처 에셋을 열고 다음과 같이 설정해야 합니다.

8비트 BMP 텍스처 세팅

이미지를 클릭하면 최대 크기로 볼 수 있습니다

  • 밉 젠 세팅(Mip Gen Settings): 밉맵 없음(NoMipMaps)

  • 압축 세팅(Compression Settings): VectorDisplacementMap(RGBA8)

  • sRGB: 비활성화

  • 필터(Filter): 가장 가까움(Nearest)

16비트 EXR 텍스처 세팅

이미지를 클릭하면 최대 크기로 볼 수 있습니다

  • 밉 젠 세팅(Mip Gen Settings): 밉맵 없음(NoMipMaps)

  • 압축 세팅(Compression Settings): HDR(RGB, no sRGB)

  • sRGB: 비활성화

  • 필터(Filter): 가장 가까움(Nearest)

셰이더 작성

피벗 페인터에서 렌더링되는 모든 텍스처는 나무의 서브 오브젝트(가지와 잎)를 간단한 연산으로 표현하는 툴을 제공합니다. 이 정보를 가지고 바람의 근원지에 대한 서브 에셋들의 반응 추정을 시작하고, 세부적인 엘리먼트별 계층구조를 생성해 자연스러운 모션을 만들 수 있습니다.

셰이더를 자체 제작하려는 경우 언패킹할 데이터 유형을 몇 가지 알아야 합니다. 언패킹 함수의 명명 규칙은 다음과 같습니다:

ms_PivotPainter2_*

PivotPainter2FolaigeShader 머티리얼 함수는 이름처럼 자신을 유용한 머티리얼로 사용할 수 있으며, 요구에 맞으면 자체 버전의 폴리지 셰이더를 만드는 기반 역할을 할 수도 있습니다. 피벗 페인터에 사용할 수 있는 머티리얼 함수와 관련된 추가 정보는 피벗 페인터 머티리얼 함수 레퍼런스 페이지를 참조하세요.

피벗 페인터 2 폴리지 셰이더

많은 백엔드 작업 세팅을 완료한 덕분에, 피벗 페인트 2.0에서는 애니메이션을 머티리얼에서 더욱 쉽게 구현할 수 있습니다. 머티리얼 코드에 PivotPainter2FoliageShader 를 입력하고 머티리얼 어트리뷰트(Material Attributes)의 입력 핀에 마지막으로 연결하면 됩니다. 머티리얼 디테일 패널에서 탄젠트 스페이스 노멀(Tangent Space Normals) 옵션이 비활성화되었는지도 확인하세요.

PivotPainter2FoliageShader.png

해당 머티리얼 함수에서는 여러분이 피벗 페인터의 기본 UV 및 텍스처 세팅으로 에셋을 처리했다고 가정합니다.

머티리얼 인스턴스를 생성한 후 사용 가능한 바람 세팅(Wind Settings)에 액세스해 서브 오브젝트의 계층구조를 제어할 수 있습니다. 이 옵션을 활용하려면 영향을 미치려는 레벨의 바람 세팅(Wind Setting) 을 활성화해야 합니다.

EnableWindSettings.png

바람 세팅이 활성화되면 해당 계층구조 깊이에 사용할 수 있는 옵션이 등장하며 편집할 수 있습니다.

이제 공유 바람 세팅(Shared Wind Settings) 에 액세스해 피벗 페인터에서 렌더링한 텍스처를 할당할 수 있습니다.

SharedWindSettings.png

  • 위치 및 인덱스 텍스처(Position and Index Texture): 렌더링된 피벗 위치(Pivot Positional) 텍스처를 해당 슬롯에 할당합니다.

  • X-벡터 및 X-익스텐트 텍스처(X-Vector and X-Extent Texture): 렌더링 된 X-벡터(X-Vector) 및 X-익스텐트(X-Extent) 텍스처를 해당 슬롯에 할당합니다.

텍스처를 제대로 할당했으면 바람 세팅(Wind Settings) 그룹을 열고 원하는 기능을 활성화하면 됩니다. 모든 바람 세팅 그룹은 특정 계층구조 깊이의 메시를 제어합니다. 나무를 예로 들면 Wind Setting 1은 몸통을, 다음 그룹은 가지를 제어합니다.

바람 난기류 및 돌풍

해당 옵션으로 아주 멋진 폴리지 애니메이션을 만들 수 있습니다. 결과물이 마음에 들지 않으면 바람 난기류 및 돌풍 세기 텍스처를 새로 만들면 됩니다. 이를 위해 벡터의 RGB 값을 사용해 바람 벡터에 오프셋을 적용한 뒤, 알파 값을 사용해 바람의 세기를 조절합니다. 이 두 채널 세트는 셰이더에서 별도로 샘플링됩니다.

텍스처를 사용하면 바람의 벡터 오프셋 및 세기를 다양하게 제어할 수 있습니다.

최적화

결과를 최적화할 때 머티리얼의 작동 방식을 이해하면 도움이 됩니다. PivotPainter2FoliageShader 머티리얼 함수는 다양한 용도로 사용하기 위해 만들어졌습니다. 이 함수는 하나의 바람 반응 코드를 4차례 실행합니다. 실행할 때마다 다른 세팅 세트를 사용해 계층구조의 레벨이 한 단계씩 깊어집니다. PivotPainter2FoliageShader 머티리얼 함수를 열면 작동 방식을 확인할 수 있습니다.

PivotPainter2FolaigeShader 머티리얼 함수를 열면 머티리얼 인스턴스를 생성할 때 노출되는 바람 계층구조 깊이(Wind Hierarchy Depths)의 셰이더 함수 기능 네트워크를 찾을 수 있습니다.

여러분이 사용 가능한 최적화 기법을 이해하려면 다음 섹션을 참고하세요.

머티리얼 인스턴스

셰이더 기능을 전부 활성화하면 비용이 상당히 높은 머티리얼이 생길 수 있습니다. 셰이더는 애니메이션이 불필요한 바람 세팅 그룹(또는 나무의 계층구조 레벨)을 비활성화하여 최적화할 수 있습니다. 예를 들어 바람 세팅 4만 활성화하면 모델의 잎에만 애니메이션을 적용할 수 있습니다. 계층구조 깊이로 바람에 대한 반응 세팅을 그룹화한다는 것은 모델의 엘리먼트도 같은 방식으로 그룹화된다는 뜻입니다. 모든 잎은 루트 오브젝트로부터 ‘X' 스텝만큼 떨어지게 됩니다. 비슷한 방식으로 작동하는 가지도 전부 같이 그룹화됩니다. 그러므로 쉽게 다중 계층구조를 만들 수 있는 나무 같은 에셋에 ‘부모' 또는 ‘마스터' 머티리얼 인스턴스를 설정하는 것을 권장합니다.

InstanceParents.png

베이스 머티리얼의 인스턴스화를 통해 ‘마스터' 머티리얼 인스턴스를 만들고, 이를 사용하여 한 곳에서 모든 바람 세팅을 정의할 수 있습니다. 이후 추가 머티리얼 인스턴스를 만들어 몸통, 가지, 잎에 쓸 베이스 컬러 텍스처 같은 계층구조의 픽셀 셰이더 컴포넌트를 정의합니다. 이렇게 하면 계층구조 깊이에 필요 없는 프로퍼티를 비활성화하고 최적화하는 효과도 있습니다.

예를 들어 잎의 머티리얼 인스턴스는 몸통, 양쪽 가지 세트, 잎 자체를 전부 시뮬레이션해야 나무의 나머지 부분과 제대로 움직이게 할 수 있지만, 몸통은 몸통의 애니메이션만 시뮬레이션하면 됩니다. 다시 말해 불필요한 잎과 가지에 대한 계층구조를 비활성화할 수 있습니다.

벤드 노멀

이외에도 고려해 볼 만한 최적화 방법으로 (특히 별도 셰이더를 작성 중이거나 수정할 계획이 있는 경우) 벤드 노멀을 들 수 있습니다. PivotPainter2FoliageShader 머티리얼 함수는 사용자가 셰이더 안에서 노멀을 업데이트하기로 했을 때 서피스 노멀을 실제로 회전합니다. 이때 커스텀 UV와 BlendAngleCorrectedNormals 머티리얼 함수를 사용하면 (부작용이 생길 위험을 감수하고) 낮은 비용으로 작업을 해낼 수 있습니다.

기타 용례

위치 정보와 계층구조 깊이를 사용하면 다음과 같은 절차적 성장 또는 건물 애니메이션을 만들 수 있습니다. 콘텐츠 예제 맵 PivotPainter2 에서 이러한 예제 유형을 어떻게 설정했는지 살펴볼 수 있습니다.

해당 예제는 에픽게임즈 런처의 학습(Learn) 탭에 있는 콘텐츠 예제(Content Examples) 프로젝트에서 찾을 수 있습니다. PivotPainter2.umap 을 열어보면 이 맵을 포함해서 다른 예제도 확인할 수 있습니다.

문제 해결

모델 애니메이션이 조악해 보이면 다음의 해결책을 시도해 볼 수 있습니다.

  • 에셋을 리임포트합니다.

  • 모델 및 텍스처 세팅을 확인합니다.

  • 머티리얼에 탄젠트 스페이스 노멀(Tangent Space Normals) 옵션이 비활성화됐는지 확인합니다.

  • 3ds Max 내부의 비균등 스케일 메시에서 잘못된 트랜스폼 값을 반환하여 결과가 깨질 수 있습니다. 이 문제가 의심될 경우 ‘Reset XForm' 명령을 실행해 보세요. 비균등 스케일 메시는 무조건 오브젝트 레벨보다는 서브 오브젝트에서 진행하는 편이 더 안전합니다. 모델 엘리먼트를 복제, 부모설정, 배치하기 전에 시작하시길 권합니다.

  • 셰이더 내 최적화로 인해 일부 메시의 워프 현상이 발생할 수 있습니다. 가지에 대한 바람의 효과를 제대로 계산하려면, 각 잎의 피벗과 잎의 벡터에서 바람의 효과를 계산한 후 메시 회전을 실행해야 합니다. 모든 회전 및 오프셋 작업은 높은 비용을 소모하므로, 엘리먼트별 메시 회전은 로컬 스페이스에서(다른 회전을 고려하기 전에) 수행합니다. 이후 회전으로 생긴 결과 메시 오프셋을 다른 트랜스폼에 추가합니다. 이 방식은 정확도가 떨어지지만 비용이 크게 절감됩니다. 이렇게 감소한 정확도로 인해, 가끔 오프셋의 조합에 따라 폴리지 스케일이 약간 변할 수 있습니다. 이 경우엔 다음과 같은 조치를 시도해 볼 수 있습니다.

    • 바람 시뮬레이션 강도를 낮춥니다.

    • 애니메이션을 적용할 계층구조 레벨 수를 줄입니다.

    • 메시를 회전하여 스케일이 변하는 빈도를 낮춥니다.