렌더링 효과 적용
Sprite·Mesh·Ribbon·Light Renderer의 표현과 비용을 비교하고 Mesh Renderer로 회전하는 폭발 파편을 만듭니다.
폭발 효과 하나에도 여러 표현이 섞여 있습니다. 불꽃과 연기는 평평한 이미지로, 튀어 나가는 돌 조각은 입체적인 모양으로, 순간의 섬광은 주변을 비추는 빛으로 보여야 자연스럽습니다. 앞의 두 글에서 머티리얼로 입자의 픽셀을 다루는 방법을 익혔다면, 이번에는 입자를 어떤 형태로 그릴지 정하는 렌더러를 효과에 맞게 고르고 조합하는 방법을 살펴봅니다. 렌더러 모듈의 역할과 기본 사용법에서 렌더러의 종류를 한 번 둘러봤으니, 이 글에서는 각 렌더러의 쓰임과 비용을 비교한 뒤 Mesh Renderer로 회전하며 떨어지는 폭발 파편을 만들어 봅니다.
렌더러마다 다른 표현
렌더러는 입자가 화면에 어떻게 그려질지 정합니다. Sprite Renderer 말고도 입자를 3D 메시로 그리는 렌더러, 이어진 띠로 궤적을 그리는 렌더러, 실제 빛을 내는 렌더러가 있습니다. 자주 쓰는 네 가지를 살펴봅니다.
Sprite Renderer
Sprite Renderer는 가장 기본적이고 널리 쓰는 렌더러로, 입자를 2D 이미지인 스프라이트로 그립니다. 주요 속성은 가장 중요한 Material과, 면이 바라볼 방향을 정하는 Facing Mode, 면 안의 정렬을 정하는 Alignment, 반투명 입자의 순서를 정하는 Sort Mode, 그리고 스프라이트 시트를 나누는 Sub Image Size와 프레임을 고르는 Sub Image Index 바인딩입니다. 불꽃, 연기, 먼지, 비, 폭발 파편, 마법 효과처럼 2D로 표현하는 거의 모든 입자 효과에 씁니다.
Mesh Renderer
Mesh Renderer는 입자를 2D 스프라이트 대신 지정한 3D 스태틱 메시로 그립니다. 주요 속성은 그릴 메시(Particle Mesh, 버전에 따라 메시 목록)와 머티리얼을 바꾸는 Override Materials, 크기를 읽는 Scale 바인딩, 방향을 읽는 Mesh Orientation 바인딩, 그리고 바운드와 거리 컬링 설정입니다. 돌이나 나무 조각, 유리 파편 같은 물리적인 파편, 날아다니는 곤충, 작은 건물 조각, 총알의 탄피처럼 3D 모양을 유지해야 하는 입자에 알맞으며, 입자가 회전하거나 부딪힐 때 실감 나는 모습을 줍니다.
Ribbon Renderer
Ribbon Renderer는 여러 입자를 Ribbon ID와 Link Order에 따라 이어 띠 모양의 메시를 만듭니다. 입자가 지나간 자리에 페인트를 칠한 것 같은 모습이 되지만, 입자 하나의 이동 기록을 저절로 모두 저장하는 기능은 아닙니다. 주요 속성은 Material과, 리본이 바라볼 방향인 Facing Mode, 그리고 곡선을 얼마나 부드럽게 나눌지 정하는 Tessellation 범주의 Mode와 Max Tessellation Factor입니다. 리본의 두께는 렌더러의 고정값이 아니라 Ribbon Width 바인딩이 읽는 입자 속성으로 정합니다. 빛의 궤적(light trail)이나 마법 주문의 흔적, 검을 휘두른 자국, 떨어지는 물방울의 흔적처럼 선을 따라 이어지는 궤적이 중요한 효과에 씁니다.
Light Renderer
Light Renderer는 입자가 게임 월드에 실제 빛을 내게 합니다. 주요 속성은 Color Binding과 Color Add, Radius Binding과 Radius Scale, 그리고 Alpha Scales Brightness이며, 그림자를 지원하는지와 그 옵션은 엔진 버전과 조명 방식에 따라 확인해야 합니다. 폭발 순간의 섬광이나 빛나는 마법 구체, 타오르는 불꽃처럼 주변 환경을 밝혀야 할 때 씁니다. 비용이 큰 편이므로 아주 적은 수의 입자에만 적용하는 것이 좋습니다.
렌더러를 더하고 설정하는 방법
렌더러는 이미터의 Render 그룹에 추가합니다. 시스템 개요(System Overview)에서 이미터를 선택하고 Render 그룹의 + 버튼을 누른 뒤, Mesh Renderer나 Ribbon Renderer처럼 원하는 렌더러를 검색해 추가합니다. 추가한 렌더러를 선택하면 선택(Selection) 패널에 그 렌더러만의 속성이 나타납니다.
Sprite와 Mesh, Ribbon 렌더러는 머티리얼을 쓰므로, 기본 머티리얼 설정과 적용에서 익힌 방법으로 알맞은 머티리얼을 지정합니다. Mesh Renderer에는 3D 메시에 맞는 머티리얼을, Ribbon Renderer에는 리본에 맞는 머티리얼을 씁니다. Light Renderer는 표면을 그리지 않으므로 머티리얼 칸 대신 조명 속성을 씁니다.
렌더러에 따라 필요한 입자 속성도 다릅니다. Ribbon Renderer는 입자를 묶을 Ribbon ID가 필요할 수 있고, Mesh Renderer는 스프라이트 크기 대신 메시의 크기 속성을 읽습니다. 필요한 속성이 없다면 Particle Spawn이나 Particle Update에 그 속성을 정하거나 갱신하는 모듈을 더해야 합니다.
폭발 파편 만들기
이제 폭발할 때 튀어 나가는 파편을 Mesh Renderer로 만들어 봅니다. NS_BasicSpawn을 복제해 열고, 계속 만드는 Spawn Rate는 끈 뒤 Emitter Update의 Spawn Burst Instantaneous로 0초에 20개를 만들게 합니다. Emitter State는 Life Cycle Mode를 Self, Loop Behavior를 Once로 두어, 한 번 터진 입자들이 수명을 다할 때까지 처리되게 합니다.
다음으로 렌더러를 바꿉니다. 기존의 Sprite Renderer를 선택해 지우고, Render 그룹의 + 버튼으로 Mesh Renderer를 추가합니다. Mesh Renderer를 선택해 그릴 메시에 프로젝트의 큐브 메시를 지정하는데, 에셋의 이름과 크기는 프로젝트마다 다르므로 실제 치수를 확인합니다. 아래의 크기 계산은 한 변이 100cm인 큐브를 기준으로 합니다. 머티리얼은 메시에 지정된 기본 머티리얼을 그대로 써도 되고, 파편이 빛나게 하고 싶다면 앞에서 만든 M_SimpleFire처럼 Additive와 Unlit을 쓰는 머티리얼을 지정해도 됩니다.
그다음 Particle Spawn으로 가서 크기와 움직임을 정합니다. Initialize Particle에서는 스프라이트 크기 대신 메시 크기(Mesh Scale)를 다룹니다. Vector의 세 축을 모두 0.05로 두면 100cm 큐브가 약 5cm가 됩니다. Sprite Renderer를 지웠으므로 스프라이트 크기를 0으로 만들 필요는 없습니다. Lifetime은 1초에서 2초 사이로 두고, 필요하면 무작위 범위로 크기에 변화를 줍니다. Add Velocity의 Velocity 입력에 Random Range Vector를 연결하고 Minimum을 X(-50), Y(-50), Z(100), Maximum을 X(50), Y(50), Z(100)으로 두어, 위로 튀어 오르면서 사방으로 흩어지게 합니다.
회전과 중력도 더합니다. Particle Spawn에 Initial Mesh Orientation을 추가해 초기 방향을 정하고, Particle Update에는 Particle State, Gravity Force, Solve Forces and Velocity를 둔 뒤 Update Mesh Orientation으로 회전 속도를 줍니다. 쓰는 버전에서 표시되는 회전 입력의 단위를 확인하고 작은 각속도부터 시작합니다. 중력은 Solve Forces and Velocity 앞에 두고, 회전을 갱신하는 모듈은 그 모듈의 의존 관계 안내를 따라 배치합니다.
마지막으로 Mesh Renderer의 Scale과 Orientation 바인딩을 확인합니다. 메시의 Pivot Offset은 우선 0으로 둡니다. 원점이 가운데에 있지 않은 메시라면 에셋의 피벗과 오프셋의 좌표 공간을 확인한 뒤 맞추는데, 2.5 같은 고정된 숫자가 모든 메시의 중심을 맞춰 주지는 않습니다.
이제 미리보기에서 스프라이트 대신 작은 큐브들이 튀어 올랐다가 중력에 끌려 떨어지는 파편 효과를 볼 수 있습니다.
에셋 크기와 입자 크기 맞추기
Mesh Scale은 메시 에셋의 원래 크기에 곱해지는 배율이므로, 원하는 크기를 내려면 에셋의 실제 치수를 알아야 합니다. 이 실습의 100cm 큐브에 세 축이 같은 배율 0.05를 적용하면 한 변은 100 × 0.05 = 5cm입니다. 같은 5cm 파편을 만들고 싶은데 에셋이 200cm 큐브라면, 배율은 5 ÷ 200 = 0.025여야 합니다.
에셋의 이름이 Cube라고 해서 실제 치수와 피벗이 같다고 가정하지 않습니다. 또 Mesh Scale은 보이는 크기만 바꿀 뿐, 입자마다 물리 액터나 강체를 만드는 설정은 아니라는 점도 기억해 둡니다.
렌더러를 조합할 때의 비용
하나의 이미터에 렌더러를 여러 개 둘 수 있습니다. 예를 들어 폭발 효과의 이미터에서 Sprite Renderer로 불꽃과 연기를, Mesh Renderer로 파편을, Light Renderer로 섬광을 함께 표현할 수 있습니다. 다만 같은 이미터의 렌더러들은 같은 입자를 그리므로, 불꽃과 파편의 수명이나 생성 조건이 달라야 한다면 이미터를 나눕니다.
렌더러마다 드는 비용도 다릅니다. Sprite Renderer는 화면에서 차지하는 면적과 반투명의 겹침, 셰이더의 복잡도에 따라 비용이 커집니다. Ribbon Renderer는 띠를 만드는 메시 계산이 더 필요하고, Mesh Renderer는 3D 메시를 그리므로 메시의 복잡도와 입자 수에 따라 비용이 크게 늘 수 있어, 복잡한 메시를 대량으로 그리는 일은 피해야 합니다. Light Renderer는 동시에 켜지는 조명의 수와 반경을 제한하고, 지원되는 그림자 기능을 쓴다면 그 비용을 따로 측정합니다. 렌더러의 종류만 보고 비용의 순서를 늘 똑같이 단정할 수는 없으므로 실제 장면에서 측정합니다.
반투명 블렌드 모드를 쓰는 렌더러들은 그리는 순서에 따라 앞뒤가 뒤바뀌어 보이는 정렬 문제가 생길 수 있습니다. 한 렌더러 안의 입자 순서는 Sort Mode로, 같은 시스템 안 렌더러 사이의 순서는 Sort Order Hint로, 서로 다른 컴포넌트 사이의 순서는 Translucency Sort Priority로 조절하며, 각 설정이 다루는 범위를 구분합니다. 우선순위를 바꾸는 것만으로 서로 교차하는 반투명 면의 문제까지 모두 해결되지는 않습니다.
여러 렌더러의 특성을 알고 의도에 맞게 조합하면, 평평한 입자를 넘어 입체적이고 풍부한 효과를 만들 수 있습니다.
더 깊이: 파편 메시 에셋에서 덜어 낼 것
Mesh Renderer의 비용은 렌더러 설정만이 아니라 메시 에셋 자체에서도 생깁니다. Scalability and Best Practices 문서는 나이아가라가 쓰는 스태틱 메시 에셋을 단순하게 만들면 그 메시를 만들고 그리는 일이 더 빨라진다고 설명하며, 덜어 낼 것을 몇 가지 꼽습니다. 입자로 쓰는 메시에는 필요 없는 콜리전을 지우고, 그림자가 필요 없다면 나이아가라가 쓰는 LOD에서 그림자 드리우기(Cast Shadow)를 끕니다.
거리 필드도 확인합니다. 문서는 그 LOD의 Distance Field Resolution Scale을 0.0으로 두라고 권하고, 쓰지 않는 UV 채널을 더 두지 말라고 안내합니다. 그래서 레벨 배치용으로 만든 바위 메시를 파편 입자로 그대로 가져다 쓰기보다, 이런 설정을 정리한 입자 전용 메시나 LOD를 따로 두는 편이 알맞습니다. 이 설정들은 메시 에셋의 것이므로, 같은 메시를 레벨에서도 쓴다면 그쪽의 그림자와 거리 필드에도 영향이 가는지 함께 확인합니다.
정리
- Sprite는 2D 이미지, Mesh는 3D 메시, Ribbon은 Ribbon ID와 Link Order로 이은 띠, Light는 주변을 비추는 빛으로 입자를 표현합니다.
- 렌더러는 Render 그룹의
+로 추가하며, Sprite와 Mesh, Ribbon은 머티리얼을, Light는 조명 속성을 씁니다. - Mesh Renderer의 크기는 메시 에셋의 원래 치수에
Mesh Scale을 곱한 값이므로, 에셋의 실제 치수와 피벗을 확인합니다. - 회전하는 파편은
Initial Mesh Orientation과Update Mesh Orientation으로, 떨어지는 움직임은Gravity Force와Solve Forces and Velocity로 만듭니다. - 한 이미터의 렌더러들은 같은 입자를 그리며, 비용과 정렬은 렌더러마다 다른 항목으로 확인합니다.
연습 문제
1. 비균일 크기와 두 렌더러
200cm 큐브에 Mesh Scale (0.025, 0.05, 0.1)을 적용하면 각 축의 크기는 얼마일까요? 버스트로 20개를 만든 이미터에 Mesh Renderer와 Sprite Renderer를 함께 두었고, 두 렌더러가 같은 20개를 읽으며 다른 생성이나 제거, 표시 필터는 없다고 합시다. 입자가 40개로 늘었다고 세어도 될까요?
해설 보기
축마다 원래 치수에 배율을 곱하면 200 × 0.025 = 5cm, 200 × 0.05 = 10cm, 200 × 0.1 = 20cm입니다.
입자는 여전히 20개입니다. 같은 20개의 상태를 두 렌더러가 각각 다른 모양으로 그릴 뿐입니다. 화면에 그릴 항목과 렌더링 비용은 늘 수 있지만, 렌더러를 더한 것을 생성이 20번 더 일어난 것으로 계산하지 않습니다. 불꽃과 파편의 수명이나 생성 조건이 달라야 한다면 이미터를 나누는 식으로 상태 구성을 구별합니다.
2. 가운데에서 돌지 않는 파편
다른 메시로 바꿨더니 파편이 자기 중심이 아니라 한쪽 모서리를 축으로 크게 돌며 움직입니다. 무엇을 확인해야 할까요?
해설 보기
메시 에셋의 피벗이 가운데가 아니라 모서리에 있을 가능성이 큽니다. 입자는 메시의 피벗을 중심으로 회전하므로, 피벗이 모서리에 있으면 그 모서리를 축으로 돕니다.
먼저 에셋의 피벗 위치를 확인하고, 에셋을 고칠 수 있다면 피벗을 가운데로 옮깁니다. 렌더러의 Pivot Offset으로 맞춘다면 오프셋이 어느 좌표 공간의 값인지 확인한 뒤 그 메시의 치수에 맞는 값을 넣습니다. 다른 메시에서 쓰던 숫자를 그대로 쓰면 맞지 않습니다.
3. 섬광을 모든 불꽃 입자에
폭발 이미터의 불꽃 입자 300개 모두에 Light Renderer를 붙였더니 프레임이 크게 떨어졌습니다. 섬광의 느낌은 유지하면서 비용을 줄이려면 어떻게 구성하면 좋을까요?
해설 보기
Light Renderer는 입자마다 빛을 만들 수 있어, 300개 모두에 붙이면 동시에 켜지는 조명이 크게 늘어 비용이 커집니다. 섬광은 대개 짧은 순간 한두 개의 밝은 빛이면 충분합니다.
불꽃 입자는 Sprite Renderer로만 그리고, 섬광은 입자 한두 개만 만드는 별도 이미터에 Light Renderer를 붙여 반경과 밝기를 조절합니다. 또는 Light Rendering Enabled 바인딩으로 일부 입자만 빛을 내게 할 수 있습니다. 바꾼 뒤에는 같은 장면에서 비용을 다시 측정합니다.
쓰는 버전에서 각 렌더러의 속성은 Epic의 나이아가라 렌더러 레퍼런스에서 확인할 수 있습니다.
다음 글 파티클과 조명 상호작용 기본 이해에서는 입자가 장면의 조명을 받는 방법과 입자가 빛을 내는 방법을 구분하고, 각각의 설정과 비용을 살펴봅니다.