본문 바로가기

메시 데이터 세트의 기본 사용법

스태틱·스켈레탈 메시의 표면 위치·노멀·정점 데이터를 읽어 파티클을 스폰하고 메시를 따라 이동시킵니다.

뜨거운 바위에서 증기가 피어오르거나 캐릭터의 몸에서 물방울이 떨어지는 효과는, 입자가 특정한 3D 물체의 모양을 따라 생겨야 자연스럽습니다. 지금까지처럼 이미터의 한 점이나 단순한 도형에서 입자를 만들면 이런 모양을 흉내 내기 어렵습니다. 이럴 때 메시 데이터 인터페이스(Mesh Data Interface)를 쓰면 스태틱 메시(Static Mesh)와 스켈레탈 메시(Skeletal Mesh)의 형태 정보를 나이아가라에서 직접 읽을 수 있습니다. 메시 물체에 입자를 심는 것과 비슷합니다. 이 글에서는 메시 데이터 인터페이스로 무엇을 할 수 있는지 살펴보고, 스태틱 메시의 표면에 입자를 만든 뒤 좌표를 맞추는 방법을 계산해 봅니다.


메시의 형태를 읽는 데이터 인터페이스

메시 데이터 인터페이스는 메시의 정점(vertex), 삼각형 면(triangle), UV, 노멀(normal) 같은 형태 정보를 나이아가라가 읽을 수 있게 바꿔 주는 데이터 인터페이스입니다. 이 정보로 입자를 메시 표면에 만들거나, 특정 지점을 따라 움직이게 하거나, 정점 색과 UV를 입자의 표현에 반영할 수 있습니다. 다만 메시 머티리얼이 셰이딩한 최종 색이 저절로 넘어오는 것은 아닙니다.

자주 쓰는 메시 데이터 인터페이스는 두 가지입니다. Static Mesh 데이터 인터페이스는 모양이 변하지 않는 스태틱 메시의 데이터를 쓰며, 건물이나 바위, 무기 같은 환경 물체에 주로 씁니다. Skeletal Mesh 데이터 인터페이스는 애니메이션되는 캐릭터나 움직이는 물체의 데이터를 쓰며, 캐릭터의 피격 효과나 발밑의 먼지, 몬스터의 특정 부위에서 나오는 효과에 씁니다.


메시 데이터로 할 수 있는 일

표면에 입자 만들기

가장 흔한 쓰임은 메시의 표면을 입자가 생기는 위치로 쓰는 것입니다. 그러면 입자가 물체에서 직접 뿜어져 나오는 것처럼 보입니다. 뜨거운 바위에서 피어오르는 증기, 용암 표면에서 끓어오르는 거품, 무너지는 건물에서 떨어지는 잔해, 수영하는 캐릭터의 몸에서 떨어지는 물방울이 그 예입니다.

메시의 속성 쓰기

메시의 정점 색이나 UV, 노멀 방향을 입자에 넘겨 초기 속성을 정하거나 변화를 줄 수 있습니다. 메시의 텍스처 색을 입자의 초기 색으로 쓰면 물체의 색에 맞는 불꽃이나 스파크를 낼 수 있고, 노멀 방향을 초기 속도의 방향으로 쓰면 표면에서 수직으로 튀어 오르는 효과를 낼 수 있습니다. 다만 UV로 텍스처의 색을 얻으려면 그 텍스처를 따로 샘플링해야 합니다.

메시를 따라 움직이기

메시의 정점 위치나 본(bone), 소켓(socket)을 참조하면 입자가 메시와 함께 움직이거나 메시의 특정 부분을 따라 움직이게 할 수 있습니다. 캐릭터의 손을 따라다니는 마법 불꽃, 검의 날을 따라 흐르는 에너지, 발이 닿는 자리에만 이는 먼지가 그 예입니다.

표본을 고르는 방식도 알아 둘 것이 있습니다. 삼각형 표면에서 고르는 것과 정점에서 고르는 것은 입자가 퍼지는 모양이 다릅니다. 메시의 내부 부피나 모서리에서 고르려면 별도의 데이터나 알고리즘이 필요할 수 있으며, Static Mesh Location에 표면과 부피, 정점, 모서리의 네 가지 선택지가 모두 있다고 가정하지 않습니다.


스태틱 메시 표면에 입자 만들기

Static Mesh 데이터 인터페이스로 스태틱 메시의 표면에 입자를 만들어 봅니다. 먼저 새 나이아가라 시스템을 만드는 창에서 빈 시스템을 골라 NS_MeshSurfaceSpawn을 만듭니다. 예전 버전의 창이라면 New system with empty system으로 만들 수 있습니다.

다음으로 기본 이미터를 구성합니다. Empty Emitter를 추가하고, Emitter Update에 Emitter State와 Spawn Rate(50)가, Particle Spawn에 Initialize Particle이, Particle Update에 Particle State가, Render에 Sprite Renderer가 있는지 확인합니다. 이미 있는 모듈은 다시 더하지 않고, 수명과 크기는 0보다 크게 둡니다.

그다음 위치 모듈을 더합니다. Particle Spawn의 Initialize Particle 아래에 Static Mesh Location을 추가합니다. 이 모듈이 Static Mesh 데이터 인터페이스를 입력으로 쓰므로, 데이터 인터페이스 클래스를 Emitter Update에 따로 모듈처럼 넣지 않습니다. 추가한 모듈의 Static Mesh 입력을 펼쳐 원본을 정하는 방식과 기본 메시를 지정하는데, 처음에는 프로젝트에 있는 큐브나 구처럼 단순한 메시로 시작합니다. 에셋을 원본으로 쓰는 것과 월드에 있는 메시 컴포넌트를 참조하는 것은 서로 다른 선택입니다.

이어서 모듈 버전이 제공하는 삼각형이나 표면 샘플링 방식을 고릅니다. CPU에서 샘플링할 때 데이터에 접근할 수 없다는 경고가 나오면, 메시 에셋의 Allow CPU Access 같은 요구 조건을 확인합니다. 좌표 변환과 모듈의 오류를 해결한 뒤에는 입자가 원점이 아니라 메시 표면에 퍼지는지 비교합니다.

마지막으로 미리보기에서 입자가 퍼진 모양을 봅니다. 원본으로 쓴 메시 자체가 화면에 그려지는 것은 아니므로, 모양을 비교하고 싶다면 같은 메시를 레벨에 놓아 봅니다. 노멀을 속도에 연결하지 않았다면 입자가 표면에서 저절로 솟아오르지도 않습니다.

생성할 때 위치를 한 번 샘플링하면, 그 뒤에 메시가 움직이거나 변해도 입자는 따라가지 않습니다. 표면에 계속 붙어 있어야 하는 효과라면 같은 표본 지점을 알아볼 정보를 남기고 Particle Update에서 다시 샘플링하도록 설계하고, 표면에서 떨어져 날아가는 효과라면 초기 노멀과 속도, 위치 계산을 더합니다.


원본 좌표와 입자 좌표 맞추기

메시에서 읽은 위치는 메시를 기준으로 한 로컬 좌표일 수 있으므로, 입자의 좌표 공간에 맞게 바꿔야 합니다. 메시의 로컬 표본 위치가 (10, 0, 0)cm이고, 원본 컴포넌트는 회전이 0, Scale이 1이며 월드 위치가 (1000, 0, 0)cm라고 해 봅시다. 이때 월드 공간에 써야 할 위치는 컴포넌트의 위치만큼 옮긴 (1010, 0, 0)cm입니다.

방향을 나타내는 노멀에는 위치처럼 1000을 더하지 않습니다. 노멀은 방향만 가지는 값이라 회전의 영향만 받기 때문입니다. 또 실제 모듈이 이미 필요한 좌표 변환을 해 주는지 먼저 확인하고, 같은 변환을 두 번 적용하지 않도록 주의합니다.


메시 데이터를 쓸 때 챙길 것

복잡한 메시나 너무 많은 입자를 메시 표면에 만들면 성능 부담이 커집니다. 필요하다면 샘플링에 쓰는 메시의 LOD(Level of Detail)를 조절하거나 입자 수를 줄입니다. 메시의 UV나 정점 색(Vertex Color) 같은 데이터를 입자의 초기 색이나 텍스처 좌표로 쓰면, 메시의 질감을 입자에 반영할 수 있습니다. 블루프린트에서 월드에 놓인 특정 메시 액터를 데이터 인터페이스의 원본으로 넘기면, 플레이 중에 원본 메시를 바꾸거나 메시의 움직임에 입자가 반응하게 할 수 있습니다.

입자가 퍼진 모양이 이상하다면 원본이 비어 있지 않은지, 좌표 공간과 스케일이 맞는지, 샘플링에 쓰는 LOD가 무엇인지, 삼각형의 면적에 따른 가중치를 쓰는지, 그리고 아래쪽 모듈이 Position을 덮어쓰지 않는지 확인합니다. 모든 삼각형이나 정점을 같은 확률로 고르면, 삼각형의 크기가 제각각인 메시에서는 표면의 밀도가 고르지 않게 나올 수 있습니다. 스켈레탈 메시를 계속 따라가는 경우에는 애니메이션 갱신과 표본 수에 드는 비용도 측정합니다.


정리

  • 메시 데이터 인터페이스는 메시의 정점, 삼각형, UV, 노멀 같은 형태 정보를 나이아가라가 읽게 해 주며, 머티리얼의 최종 색은 저절로 넘어오지 않습니다.
  • 스태틱 메시의 표면에 입자를 만들려면 Particle Spawn에 Static Mesh Location을 두고 그 입력에 원본 메시를 지정합니다.
  • CPU 샘플링에는 메시의 Allow CPU Access 같은 조건이 필요할 수 있고, 원본 메시는 그 자체로 화면에 그려지지 않습니다.
  • 로컬 표본 위치는 원본 컴포넌트의 변환을 적용해 입자의 좌표 공간에 맞추며, 노멀에는 위치의 이동을 더하지 않습니다.
  • 생성할 때 한 번 샘플링한 입자는 메시를 따라가지 않으므로, 계속 붙어야 하면 Particle Update에서 다시 샘플링하도록 설계합니다.

연습 문제

1. 옮긴 컴포넌트와 남은 입자

회전이 0, Scale이 1인 조건에서 로컬 표본 위치가 (-20, 0, 0)cm이고, 원본 컴포넌트의 월드 위치가 (500, 0, 0)cm입니다. 월드 위치를 구해 보세요. 생성하는 순간에만 그 결과를 월드 공간의 Particles.Position에 썼고, Update에서 다시 샘플링하거나 붙이는 경로, 힘이나 속도를 쓰는 모듈이 없다면, 나중에 메시 컴포넌트를 100cm 옮기는 것만으로 기존 입자도 같은 표면을 따라갈까요?

해설 보기

월드 위치는 -20 + 500 = 480이므로 (480, 0, 0)cm입니다.

기존 입자는 따라가지 않습니다. 생성한 뒤에 원본의 이동을 다시 읽거나 입자를 붙이는 경로가 없으므로, 월드 공간에 쓴 위치가 그대로 남습니다. 표면에 계속 붙는 효과라면 같은 표본 지점을 추적할 정보와 Update에서의 갱신을 설계해야 합니다. 메시를 화면에 그리는 일과 위치 데이터를 샘플링하는 일도 서로 다른 일이라는 점을 함께 기억합니다.

2. 한쪽에 몰리는 입자

큰 삼각형 몇 개와 작은 삼각형 수백 개로 이루어진 메시의 표면에 입자를 만들었더니, 작은 삼각형이 모인 쪽에 입자가 몰려 보입니다. 무엇을 확인해야 할까요?

해설 보기

표본을 고르는 방식이 삼각형의 면적을 고려하는지 확인합니다. 모든 삼각형을 같은 확률로 고르면, 작은 삼각형이 많은 쪽은 면적에 비해 더 자주 뽑혀 입자가 몰립니다.

면적에 따른 가중치를 쓰는 샘플링을 고르면 넓은 면에는 더 많이, 좁은 면에는 더 적게 입자가 생겨 표면의 밀도가 고르게 됩니다. 정점에서 고르는 방식도 정점이 모인 곳에 입자가 몰리므로 같은 이유로 확인합니다.

3. 노멀에 위치를 더한 실수

표면에서 튀어 오르게 하려고 메시의 노멀을 초기 속도의 방향으로 썼는데, 다른 사람이 노멀에도 컴포넌트의 월드 위치 (1000, 0, 0)을 더해 버렸습니다. 결과가 어떻게 달라질까요?

해설 보기

노멀은 방향만 나타내는 값이므로, 위치의 이동을 더하면 방향이 크게 틀어집니다. 예를 들어 위쪽 노멀 (0, 0, 1)에 (1000, 0, 0)을 더하면 (1000, 0, 1)이 되어, 입자가 위가 아니라 거의 X 방향으로 날아갑니다.

노멀에는 컴포넌트의 회전만 적용하고 위치의 이동은 더하지 않습니다. 또 모듈이 이미 노멀을 월드 방향으로 바꿔 주는지 먼저 확인해, 변환을 두 번 적용하지 않도록 합니다.

Static Mesh 데이터 인터페이스의 원본 설정은 Epic의 NiagaraDataInterfaceStaticMesh 레퍼런스에서 확인할 수 있습니다.

다음 글 사용자 정의 데이터 인터페이스에서는 기존 데이터 인터페이스로 얻을 수 없는 데이터를 C++로 직접 만든 데이터 인터페이스로 나이아가라에 넘기는 방법을 살펴봅니다.