툴/유니티

VFX Graph guide e-book / 내용 정리

스튜디오 오버그래픽스 2023. 2. 18. 00:14

https://resources.unity.com/games/definitive-guide-to-creating-visual-effects?ungated=true 

 

The definitive guide to creating advanced visual effects in Unity

Learn how to use Unity’s complete set of tools for authoring high-fidelity, richly detailed visual effects with the The definitive guide to creating advanced visual effects in Unity e-book.

resources.unity.com

 

The definitive guide to creating advanced visual effects in Unity.

2022년 말쯤 유니티에서 나온 공식 VFX Graph 가이드 ebook.

아직 유니티 코리아에서 한글화된 자료는 없고 영문 자료만 있음.

2021 LTS 기준 자료.


개요

 

URP, HDRP에서 지원하는 노드 방식의 파티클 시스템.

기존 빌트인에서 쓰던 슈리켄은 CPU연산의 파티클 시스템이었으나,

VFX Graph는 GPU연산으로 퍼포먼스가 더 좋음.

단, 지원하지 않는 플랫폼이 있을수 있으므로 개발전에 체크.

 

추후 사라질수도 있는 실험적인 기능은 일반적으로 꺼져있는 상태

Preferences > Visual Effects > Experimental Operators/Blocks 을 체크해서 실험 기능 활성화 가능

 


VFX Graph 레이아웃

 

  • Toolbar

상단에 있는 토글들

 

  • Node Workspace

VFX 노드를 만들고 연결하며 로직을 짜는 화면 영역

 

  • Blackboard(툴바에서 On/Off가능)

사용 가능한 속성,전역변수를 관리하는 창

 

  • VFX control panel(툴바에서 On/Off가능)

멈춤,재생,레이트 등 이펙트 재생에 관련한 조절 기능 창

 

 

 

VFX Graph를 편집하더라도 유니티 에디터에서 Inspector를 볼수 있는 레이아웃을 남겨두는게 좋음.

VFX Graph에서 블록을 선택하면 디테일한 블록속성을 유니티 에디터 Inspector 창에서 볼 수 있음.

 

 

 


VFX Graph 로직

 

마우스가 빈공간에 있을 때 마우스 우클릭 or  스페이스바 를 사용해서 그래프 요소 생성.

Context,Operator,Property를 생성 할수 있음.

Context안에는 블록을 생성 가능

 

VFX Graph는 시스템이라고 하는 수직 스택을 쌓고, 위에서 아래로 수직 연산.

각 시스템들은 선으로 연결되며, Context와 블록들의 조합으로 이루어짐.

 

 

일반적으로 Spawn, Initialize, Update, Output으로 이루어짐

Spawn : 파티클의 갯수, 유지시간 등을 설정하고 어떻게 생성할지(초당n개,딜레이 등)

Initialize : 초기 파티클의 속성 값

Update : 매프레임마다 파티클의 변화를 계산할 속성들(중력, 움직임 등)

Output : 파티클의 외형,렌더를 어떤식으로 할지

 

 

각각의 시스템은 선으로 연결되며 뿌리가 갈리지듯 여러개로 나뉘어서 하나의 시스템이 하위의 여러시스템에 연결/연산을 하게 할수 있음.

 

*각 블록의 우측 상단에 Local or World를 변경해서 시뮬레이션 공간 전환

 

시스템이 그래프의 수직 연산을 형성하고, 연산자(Operator)는 수평 연산을 구성함(셰이더 그래프 처럼 수평 로직)

 

 

 

Blackboard에서 속성을 만들면(int,float,bool 등등) 전역 변수로 재사용 가능한 블록으로 연결해서 사용 가능

Blackboard의 속성은 Exposed와 Constant로 나눠짐

Exposed로 체크되면 속성명 옆에 녹색점이 있고 Inspector창에서도 조절 가능

Exposed가 체크안되면 Contant로 속성명 옆에 녹색점이 없고 Inspector창에서 확인 불가

 

 

노드 생성 단계에서 Misc-Group Node를 생성하면 노드를 묶어주는 영역이 생기고 이름을 지정해서 정리가능.

마우스 우클릭으로 Sticky Note생성 가능, 주석 처럼 메모를 남길 수 있음.

 

 

노드가 복잡해지고 많아지면 Subgraph를 활용해서 정리가능

여러개의 블록/노드들을 선택하고 우클릭하면 'Convert to Subgraph Operator' 항목이 있음

그러면 선택된 블록/노드들을 하나로 묶어서 저장해주고 Input/Output 부분만 남는 1개블록으로 변환됌.

코드를 함수화,모듈화 하는 것과 비슷한 개념

 

 

각 노드들의 시작과 중지를 관리하는 Event 블록이 있으며, Spawn 보다 위에 배치함

string 타입의 이벤트 명으로 호출,실행 가능

'Output Event'를 사용해서 Spawn이 실행될때 다른 게임오브젝트나 C#스크립트의 호출도 가능(Output Event Handler API를 통해서 사용 가능)

 

 

 

GPU Event 블록

특정 파티클의 동작을 기반으로 다른 파티클을 동시에 생성가능

한 시스템에서 입자가 죽으면 다른 시스템에 알릴수 있으며 기존 파티클의 정보도 불러와서 사용가능

 

GPU Event 조건

-Trigger Event On Die : 입자가 사멸했을때 이벤트 발생

-Trigger Event Rate : 입자가 생성되는 속도에 따라 이벤트 발생

-Trigger Event Always : 생성 파티클의 매 프레임마다 이벤트 발생

 

 

Get Source Attribute Operators or Inherit Attribute Blocks를 사용해서 Initialize에서 설정된 파티클의 정보값을 가져와서 사용할 수 있음

일반적인 VFX Graph 시스템은 수직 논리 시스템에 따라 중복된 속성 설정이 있으면 맨 하위 설정만 반영

ex) Color값을 Initialize,Update,Output에 모두 설정해두었다면 Output에 설정된 값만 반영

 

 

더 자세한 기능들 공식 문서

 

노드 라이브러리

스탠다드 어트리뷰트

VFX 데이터 타입

 

셰이더 그래프로 제작한 셰이더를 VFX Graph의 Output에 연결할수 있음.

VFX Graph로 생성한 파티클의 외형(머테리얼,질감,노멀 등)의 시각적 요소를 제작 가능.

 


VFX Graph 예시

VFX Graph 샘플 프로젝트 - Github

2021.2버전 프로젝트를 기준으로 내용 정리

 

 

 


 

GooBall

페인트 물방울이 튀기는 샘플

 

 

중심에 블롭은 셰이더그래프에서 VAT(Vertex Animation Texture)를 사용해서 유체의 일렁이는 질감을 표현

VAT는 각 Vextex의 움직임(애니메이션)을 채널에 저장해둔 텍스쳐 개념

VAT 텍스쳐가 적용된 셰이더그래프가 VFX Graph의 Output에 적용되어 있음.

셰이더 그래프를 통해서 Vertex Motion외에도 투명하고 녹색 유리같은 물질의 외형도 제작.

 

셰이더 그래프에서 Alpha, AO, RefractionIndex 등이 설정되어 있고, Inspector창에서도 조절할수 있게 Blackboard에서 생성된 변수들이 Exposed 되어 있음

 

 

그리고 사방으로 튀기는 물방울이 부딪히는 효과는 따로 정해진 Collider를 사용하지 않고 Depth Buffer를 사용.

Depth Buffer의 정밀도가 엄청 뛰어나진 않기 때문에 높은 정밀도가 요구 되지 않을때는 사용가능.

 

MainCamera를 기준으로 Depth Buffer를 생성하고 있으며, 해당 Depth Buffer를 활용해 부딪혔는지 판단할수 있다.

부딪히면 파티클의 lifetime이 0으로 감소하게 설정이 되어있고, 파티클이 사멸함과 동시에 GPU Event를 발생 시키고 Decal에 쓰일 파티클을 생성한다.

 

 

 

GPU 이벤트를 발생시킴으로써 벽에 부딪혀서 맺힌 페인트 자국은 'Output Particle HDRP Lit Decal'을 사용하며 지오메트리 방향에 맞게 배치하기 위해 Depth Normals을 계산함.

 

 

VFX Graph는 복잡한 시뮬레이션을 계산하고 Frame Buffer를 읽을수 있지만,

파티클 데이터를 C#으로 가져오거나 기본 물리 시스템에 활용할수 있게 지원하지는 않음.

(GPU에서만 처리되어 계산 결과만 주기 때문에 연산 과정에 있는 파티클 하나 하나를 개발자가 관여할수는 없음)

 

그래서 VFX Graph에서는 물리기반 효과를 만들기 위해서 다음과 같은 방법을 제시함:

-Depth Buffer 사용

-Sphere, Box, Torus 등 기본 도형 셋팅값 활용

-물리기반 제어에 활용 가능한 3D Texture(Vector Field, SDF, Point Cache) 활용

 

발사체(물방울)들이 Depth Buffer를 통해 바닥과 벽에 충돌하고 그 지점에 물방울이 맺혀보이게 (Decal) 했지만,

유체 특성상 바닥에 맺힌 유체는 그 위치에 머물러도 자연스럽지만 벽에 맺힌 유체는 천천히 아래로 흘러내려야함.

그래서 World Position을 기준으로 Y축으로 6.2~11사이이면 Update에서 Gravity Y축의 변화가 적용됌.

 

 

이처럼 GooBall 프로젝트를 통해서 다음과 같은 VFX Graph 기능들을 확인 가능함 :

-Shader Graph를 연동한 VFX Graph의 파티클 외형 표현

-GPU Event 트리거를 활용한 기능

-Depth Buffer, Depth Normals을 사용한 Decal의 적용

 

 

 


 

 

Meteorite Sample

운석이 지구에 충돌했을때 충격을 강조하기 위한 효과들을 보여주는 샘플

아무키나 입력이 되면 타임라인에 따라서 운석이 떨어지고 각각 VFX Graph의 요소들이 제어됌

 

 

먼저 C# 스크립트를 통해 아무키나 누르면 타임라인이 재생되게 되어 있고,

MeteoriteMain의 Event함수 명이 호출되면서 하위에 연결된 다른 여러 개의 그래프를 같이 제어함.

MeteoriteMain의 Spawn 밑으로 'Output Event'들이 호출되면서 다른 오브젝트나 스크립트 기능들을 제어하고, 'SubGraph'가 호출되면서 각각의 다른 VFX Graph를 Play/Spawn 하게 됌.

 

운석이 하늘에서 떨어지면 연쇄반응이 일어나게 됌.

-운석이 떨어질 위치에 미리 빛이 나는 효과

-충돌하는 운석의 연기 자국

-충돌할때 충격으로 생기는 빛의 폭발

-땅과 상호작용하는 파편들

-카메라 흔들림

 

다른 기능들을 전부 컨트롤 하는 MeteoriteMain VFX Graph를 Inspector창에서 보게 되면 SubGraph를 제외한 Output Event에 해당하는 기능들을 확인할수 있음.

 

 

이때 쓰인 Output Event Handler는 Pakcage Manager - Visual Effects Graph - Sample(OutputEvent Helpers)에서 몇가지 샘플들을 추가 할수 있으며,

추가된 샘플은 Assets - Samples - Visual Effect Graph - (Version숫자) - OutputEvent Helpers - Edits에 스크립트로 존재.

이 스크립트들으 Monohaviour로 되어 있지 않고 VFXOutputEventHandlerEditor로 작성되어 있음

Add Component에서 해당 스크립트명(Output Event)을 검색하면 새로 생성할수 있는 Output Event들이 나옴

 

 

 

 

운석이 떨어지면서 운석 주변으로 효과를 생성하기 위한 특정한 Depth Buffer가 필요함

이 프로젝트에서는 특정한 Depth Buffer를 그리기 위한 VFX Graph가 존재하며 이 이펙트는 컬러,이미지를 활용해 Depth Buffer를 그리는 애니메이션 역할을 한다.(3개 Output Particle Quad로 이루어져 있음, GameView에 보이지 않음)

 

 

이 Depth Buffer를 위한 VFX Graph는 Prefab형태로 저장되어 있으며 Output Event Handler Prefab Spawn으로 생성된다

그리고 이 Prefab은 별도의 특정 Layer로 설정되어 있으며 'BufferRecoder'라는 이름의 별도 카메라가 해당 Layer만 렌더하고 해당 렌더 결과물을 RenderTexture로 만들어서 VFX Graph에서 Depth값으로 사용한다.

 

*Camera는 Depth만 Render하기 위해 별도의 Frame Settings Overrides 설정이 된듯하다.

그리고 수직으로 떨어지는 운석을 Depth Buffer로 저장하기 때문에 이 카메라는 위에서 아래로 내려다보는 Orthographic으로 설정되어 있음.

 

 

 

이렇게 생성된 Depth Buffer는 Render Texure로 저장되어서 GrassStrip이라는 VFX Graph에서 활용하게 된다.

Depth Buffer의 애니메이션을 통해 Grass의 파티클들이 사멸하거나 색이 바뀌거나 하는 등의 영역과 애니메이션,속성 변경을 연산하게 된다.

 

 

그리고 운석이 떨어지면서 2차 효과 이펙트들이 발생한다 :

-나뭇잎이 떨어짐

-새들이 흩어짐

-나비들이 사라졌다가 나타남

 

이러한 2차 효과들이 VFX Graph로 생성되어 있으며 Timeline에 의해서 이벤트명이 호출되면서 제어된다

 

 

 

 

 


 

 

Mesh Sampling Effects

 

메시 데이터를 가져와서 활용하는 2가지 기법(Position Mesh Block, Sample Mesh Operator)

Point Cache로 변환하지 않고 Mesh자체의 데이터만으로 사용 가능.

 

-Position (Mesh) Block(일반적으로 Initialize 부분에 추가해서 적용)

 

Vertex : 정점 위치 값

Surface : 정점이 연결된 면적

Edge : 정점이 이어지는 선

 

 

 

 

-Sample Mesh Operator

생략

 


 

 

Skinned Mesh Sampling

 

그냥 메시가 아닌 Skinned Mesh일때 사용할수 있는 기법

일반적으로 애니메이션 되는 캐릭터에 Skinned Mesh Renderer가 적용되어 있고 이 데이터를 가지고 활용하는 기법.

움직이는 캐릭터의 외형에 맞춰서 불이 붙어있는 효과, 홀로그램 효과, 전기가 맴도는 효과 등 표현 가능

 

-적용 방법

의도하는 방식에 따라 Context(Initialize,Update,Output)에 Skinned Mesh Block 추가

Skinned Mesh Renderer를 VFX Graph에 불러올수 있게 Exposed로 Blackboard에 속성 추가

Surface,Vertex,Edge에 대한 추가 액세스가 필요한 경우 Skinned Mesh Operator 사용

Inspector창에서 사용할 Skinned Mesh Renderer 연결 및 참조

(이렇게만 가져올 경우 Skinned Mesh의 외형 데이터만 있고 월드좌표에서의 위치와 방향 정보가 없음)

월드 좌표에서 Skinned Mesh의 위치와 방향 정보를 가진 기준이 되는 오브젝트의 Transform을 Property Binder를 통해 불러온다.

 

 

 

VFX Property Binder에 연결하는 Target(Skinned Mesh Renderer의 중심축이 될 Transform)은 일반적으로 캐릭터의 척추,고관절 부분을 연결함.

 


Interactivity

VFX Graph와 상호작용 할 수 있는 기능들.

 

만약 접촉시에 폭발하는 발사체나 마우스 포인터에 의해서 작동되야 하는 기능이 필요한 경우 다음과 같은 도구를 사용 :

-Event Binders

-Timeline

-Property Binders

-Output Event(위 3개 기능과는 다르게 VFX Graph에서 게임오브젝트나 C#으로 이벤트 전달)

 


Event Binders

이벤트 바인더는 VFX Graph의 이벤트를 호출할 수 있는 Monobehaviour 스크립트.

마우스 움직임,충돌,트리거 및 씬에 보이는 이벤트에 효과가 반응하도록 함.

 

 

OnPlay, OnStop Event

Spawn에는 기본적으로 Start,Stop이 있고 String 타입의 Event를 연결해서 제어 가능

SceneView에서 Play/Stop도 가능하고 Custom Event에 직접 이벤트명을 적어서 테스트도 가능

 

 

Mouse Event Binder

마우스 클릭, 호버링, 드래그를 인식해서 VFX Graph로 메시지를 보내는 바인더

Collider가 있는 게임 오브젝트에만 적용됌

 

 

위와 같이 그래프의 Start는 'OnPlay', Stop은 'OnStop'으로 이벤트명을 지정

VFX Graph 게임오브젝트에 Collider를 만들어주고 'VFX Mouse Event Binder'를 생성하고 각각 이벤트명과 마우스 Activation을 지정해줌

마우스가 콜라이더로 들어가면 파티클이 Stop되고, 마우스가 콜라이더 밖으로 나가면 다시 Play

 

 

Rigidbody Collision Event Binders

Rigidbody컴포넌트가 필요하며 물체가 부딪혔을때 VFX Graph의 특정 Event를 호출한다.

 

 

 

Trigger Event Binder

특정 오브젝트가 특정 트리거 안에 들어왔을때, 나갔을때, 들어와있는 상태.

총 3가지 조건에 따라서 VFX Graph의 Event를 호출.

 

 

 

Visibility Event Binder

카메라에 렌더가 되는 오브젝트, Renderer가 있는 오브젝트에 한해서 

Visible, InVisible을 조건으로 Event를 호출

 

 

 


 

Timeline

정확한 타이밍으로 시각적 효과를 제어해야하는 경우 타임라인과 Visual Effect Activation Tracks을 사용

 

 

Project / Assets에 Timeline에셋을 하나 생성

게임 오브젝트에 Add Component에서 Playable Director를 만들고 Timeline을 연결

Timeline창으로 가서 우클릭 - Visual Effect Activation Track을 하나 생성하고 제어 할 VFX를 연결

 

그러면 Playable Director에 Bindings에 추가됌.

다시 타임라인으로 와서 트랙 타임라인 영역에 우클릭 - Add Visual Effect Activation Clip 생성

이 클립은 시작과 끝에 호출할 2개의 Event명을 설정할수 있고 타임라인에 맞춰서 VFX Graph의 Event 호출

 


Property Binder

Property Binder는 게임내의 값을 VFX Graph의 Exposed된 속성에 연결할수 있는 기능

 

VFX Graph에서 BlackBoard에 Sphere속성을 만들고 이름을 'TargetSphere'라고 작성

VFX Property Binder를 만들고 Sphere를 추가해주고 Property에 Blackboard에서 만든 Sphere명과 똑같이 작성

게임에 Sphere를 만들어주고 Target에 연결하면 게임오브젝트 Sphere의 Transform을 그대로 VFX Graph의 TargetSphere에 적용 가능

 

 


Output Event

게임 오브젝트나 C#이 VFX Graph에 속성,이벤트를 전달하는게 아닌,

역으로 VFX Graph에서 게임오브젝트나 C#으로 이벤트를 전달하는 기능

 

VFX Graph에서 Output Event 블럭을 생성하고 Event명을 적으면, 외부에 있는 Output Event를 받을수 있는 스크립트 중에서 해당 Event명을 가진 함수 및 기능을 호출 할수 있다.

 

 

Package Manager에서 Output Event handler 샘플을 받아서 쓸수 있으며,

샘플로 받은 스크립트는 Assets - Samples - Visual Effect Graph - (Version숫자) - OutputEvent Helpers - Edits에 스크립트로 존재.

이 스크립트들으 Monohaviour로 되어 있지 않고 VFXOutputEventHandlerEditor로 작성되어 있음

Add Component에서 해당 스크립트명(Output Event)을 검색하면 새로 생성할수 있는 Output Event들이 나옴

 


Pipeline Tools

원하는 형태의 이펙트를 만들려고 하다보면 가공된 데이터가 필요함.

그래서 여러 다른 타입의 데이터들을 활용해서 이펙트를 제작하게 되는데 다음과 같은 데이터 제작툴을 지원함 :

 

-Point Cahce : 공간좌표, 트랜스폼,노멀,컬러,UV등이 저장된 데이터

-SDF(Signed Distance Field) : 특정 볼륨이 파티클을 끌고 당기는 힘의 정보가 담긴 데이터

-Vector Field : 샘플링한 파티클의 벡터 정보가 3D 공간에 담긴 데이터.

 


 

Point Cache

점의 위치, 컬러, 노멀 등을 저장한 에셋 데이터

모델링 파일(메시 데이터)을 .pCahce파일로 저장할수 있음

SDF보다 리소스를 덜 사용함. 가벼움

 

Point Cache 생성 방법 :

- 유니티 에디터 Window - Visual Effects - Utilites - Point Cache Bake Tool을 사용해서 변환

- VFX Tools box에서 함께 제공되는 Houdini pCache Exporter를 사용

 

Point Cache Bake Tool

유니티 에디터에서 자체 제공하는 pCache 변환 기능

Mesh 혹은 2D 텍스처에서 점의 위치. 캐시를 데이터로 저장 할수 있음.

그러나 실제 원본데이터의 Vertex나 Edge 그대로 표현되는건 아니라 변환을 거침.

즉 Point의 갯수를 더 촘촘하게 구현하거나, 듬성듬성하게 설정 할수 있음.

 

 

VFX Graph에서 Point cache 연산자를 활용해서 pCache 데이터를 불러올수 있음.

그리고 Set Position from Map, Set Color from Map블록에 연결해서 사용 가능.

 

 

 


 

SDF(Signed Distance Field)

메시 지오메트리의 3D 텍스쳐 표현으로, 각 texel은 메쉬 표면에서 가장 가까운 거리 값을 저장하고 있다.

메시 내부에서는 음수, 메시 외부에서는 양수로 표현되며, 경계 내부 또는 지정된 거리에 파티클이 모이게 할수 있다.

Point Cache 보다 리소스를 더 필요로 하지만 기능이 더 많이 포함되며, 높은 텍스쳐 해상도를 필요로 한다.

 

메시 외부,내부에 파티클을 끌어당기고 밀어내는 힘의 방향이 존재하기 때문에 생성된 파티클들이 서서히 모여들면서 특정 윤곽을 띄게 할수 있는 데이터이다.

Unity는 SDF 데이터를 3D 텍스쳐 볼륨 파일(.vf)로 가져오게 된다.

Update 부분에 Confirm to Signed Distance Field 블록에 적용

 

 

SDF Bake Tool

DCC툴인 Houdini로 SDF파일을 만들수도 있고, VFX Tool box 유틸리티를 활용해서 만들수도 있다.

그러나 이제 유니티 에디터에서도 SDF Bake Tool을 지원하기 때문에 이걸 쓰는게 간편하다.

 

Window - Visual Effects - Utilites - SDF Bake Tool에 사용할 메시를 가져와서 SDF 파일로 Bake 가능.

 

 

 


 

Vector Field

벡터 필드는 입자의 속도나 가속도를 제어하는 벡터의 균일한 집합. 화살표는 각 벡터를 나타내며, 벡터의 크기가 클수록 파티클이 벡터를 통과하는 속도가 빨라짐.

 

SDF와 마찬가지로 Volume File(.vf)형식을 사용하여 벡터 필드를 나타내거나 VFX Tool box를 통해서 벡터 필드를 생성할수 있음.

아래 사진과 같이 유니티 로고 장면(VFX Graph 샘플)에서 파티클은 벡터 필드의 보이지 않는 힘에 의해서 밀려나는 흐름을 보여준다.

 

 

 


 

VFX Tool Box

VFX Tool Box에서 Unity 시각효과 아티스트를 위한 도구가 있음.

SideFX의 Houdini Point Cache Exporter 및 Volume Exporter에서 .pCache 및 .vf 파일을 보낼수 있음.

VFX Tool Box Github링크

 

 


 

Image Sequencer

스프라이트 이미지(N x N 형태로 여러개의 이미지 배열)를 VFX Graph의 Flipbook Texture Sheets에 적용해서 애니메이션 효과를 만들수 있음.

연기,불,폭발 효과를 유니티 엔진에서 직접 시뮬레이션 하면 리소스가 많이 쓰이기 때문에 다른 DCC 툴에서 해당 효과를 미리 시뮬레이션 및 렌더하고 그 이미지만 스프라이트 이미지로 가져와서 Flipbook의 형태로 구현한다.

이런식으로 제작하면 리얼타임에서는 훨씬 적은 리소스로 구현이 가능해진다.

 

-제작 및 적용

시뮬레이션한 효과를 프레임별로 이미지 시퀀스로 만든다.

이 이미지들을 모으고 이미지 시퀀서를 통해서 단일 텍스처 시트로 변환한다.

원하는 구간,재생 타이밍에 맞춰서 조절하고 루핑되게끔 편집한다.

이렇게 단일 텍스쳐로 변환하고 Flipbook Player블록에 적용한다.

 

 

 

에셋스토어에서 'TFlow'를 사용하면 플립북 텍스쳐에 모션벡터,모션블러를 생성해서 품질을 향상 시킬수 있음.

 


 

DCC(Digital Content Creation) Tools

디지털 컨텐츠를 제작하는 툴들

게임 엔진에 있어서는 주로 Mesh,Texture 제작 편집에 쓰이는 툴들.

 

SideFX Houdini

후디니는 오랜 시간 동안 시뮬레이션과 VFX 제작에서 업계 표준이되고 있는 툴.

절차적 제작 방식과 노드 기반 인터페이스를 가지고 있으며 텍스쳐,셰이더,파티클 제작이 용이함.

비선형 개발을 장려하고 3D 제작의 모든 주요 영역이 가능한 툴.

 

Autodesk Maya

마야는 많은 게임 개발 스튜디오에서 쓰이며, 비교적 새로운 Bifrost 시스템은 시각적 프로그래밍 환경에서 정확한 물리 계산과 정교한 시뮬레이션을 가능하게 함.

 

Blender

블렌더는 오픈소스 3D 제작 툴.

모델링, 리깅, 애니메이션, 시뮬레이션, 렌더링 까지 3D 제작의 모든 분야를 다룰 수 있음.

블렌더는 크로스 플랫폼으로 리눅스,맥,윈도우까지 똑같이 작동하기 때문에 커뮤니티 정보 공유가 활발하게 이루어짐.

 

Adobe Photoshop

이미지 편집 소프트웨어로 다른 3D 제작 툴에서 필요한 2D 이미지,텍스쳐 제작에 용이하다.

이미지 편집 및 생성뿐만 아니라 여러 컬러 모델을 지원함.

 

 

 


Optimization

프로그래머가 코드를 프로파일링 하고 성능을 확인해서 최적화를 하는 것처럼, VFX Graph를 작업한 후에 최적화를 위한 프로파일링과 재구성 과정을 진행 할 수 있다.

이펙트가 제대로 작동하고 최종 작업이 끝났다면, 게임이나 응용프로그램으로 배포하기 전에 과도하게 사용되는 리소스를 체크해서 최적화를 진행해야 한다.

 

 


 

The Unity Profiler and Frame Debugger

Unity Profiler(Window - Analysis - Profiler)와 Frame Debugger(Window - Analysis - Frame Debugger)를 사용해서 VFX Graph를 최적화하고 성능을 향상 시킬수 있다.

그러나 유니티 에디터는 프로파일링 정보에 영향을 미쳐 부정확한 결과를 보여줄수 있음.

Profiler Standalone Process 옵션을 쓰거나 실제 성능을 측정해야 할 때 별도의 빌드가 필요함.

 

 

렌더링 통계를 볼때는 FPS보다는 프레임 렌더에 쓰이는 시간에 더 유의해야함.

FPS는 비선형적이기 때문에 원치 않는 정보로 받아들여 질수 있음.

 

60FPS를 목표로 한다면 프레임당 16ms 이하

30FPS를 목표로 한다면 프레임당 33ms 이하

 

 

 

Frame Debugger는 DrawCall 정보를 보여준다.

해당 프레임이 구성되는 과정을 체크해 볼수 있다.

 

 

위의 이미지에서 Frame Debugger의 왼쪽 패널에서는 DrawCall 호출 순서와 렌더링 이벤트를 하이어라키(계층 구조)로 보여준다.

오른쪽 패널에서는 Shader Pass 및 Texture를 포함한 DrawCall의 세부정보가 표시된다.

이를 통해 프레임을 확인하고, 해당 프레임에서 어떤 리소스를 어디에 사용하는지 체크 가능하다.

 

이펙트를 최적화 할때 체크 해야하는 점 :

-Texture size: 텍스쳐가 카메라에 크게 잡히지 않는다면 텍스쳐 사이즈를 줄여도 됌.

-Capacity: VFX Graph에서 파티클 용량(Capacity)을 조절해서 최대 파티클 갯수를 제한해줌.

-Visibility and lifetime: 화면에 보이지 않는다면 이펙트 Play,Spawn을 끄고, 이펙트를 다하면 사라지게 Lifetime 설정.

 

 


 

Debug Modes

VFX Control panel은 디버그 모드를 포함하고 있으며, 성능과 메모리 사용량에 영향을 줄 수 있는 Lifetime과 Capacity를 확인하는데 사용할수 있다.

VFX Graph창 툴바에서 Control을 누르면 해당 창에서 Debug Modes 버튼을 확인 할 수 있다.

None or Efficiency or Alive 중에서 선택 가능

 

 

 

 

Debug Modes는 계산되고 있는 결과를 그림으로 보여주며 재생되고 있는 파티클의 수, 설정된 파티클 용량(Capacity)을 비교한 카운트를 보여준다.

이 결과를 토대로 카운트 및 용량을 조절해서 효율을 향상시킨다.

 

 

 

-Operators and memory: 불필요한 연산자를 단순화하고 크게 다르지 않는 경우 반복 횟수를 적게 사용한다.

-Flipbooks: 모든 파티클을 시뮬레이션 하기 보다는 상황에 따라서 pre-rendering을 통한 플립북 텍스쳐를 이용한다.

-Mesh size: Output Meshes 블록을 사용할 경우 사용되는 Mesh의 폴리곤 수를 줄인다.

-Excessive overdraw: 여러개의 투명한 표면,재질이 있는 경우 Rendering Debugger(Window - Analysis - Rendering Debugger)를 사용해서 과도한 Overdraw(픽셀 중복 연산)가 발생하는지 체크하고 그에 따라 VFX Graph를 수정한다. 또한 가능하면 팔각형 파티클로 교체를 한다.

 

 

Rendering Debugger에서 Overdraw를 체크하는 화면

 

 

또한 특정 기능,블록의 사용 전후 성능을 테스트 해볼 경우 직접 블록을 삭제하거나 연결 해제 할 필요 없이 우측 상단에 체크박스를 해제함으로써 활성화/비활성화가 가능하다.

 

 

 


 

Bound

게임 카메라 앵글 시점(가시성)과 VFX graph의 경계(Bound)를 기준으로 빌트인된 최적화 기능이 적용된다.

Initialize Context에서 몇가지 설정이 표시 된다 :

 

 

만약 VFX의 경계(Bound)가 카메라에 잡히지 않는다면 해당 VFX는 렌더링하지 않게 된다(Culling 효과)

그래서 최적화를 위해서 경계(Bound) 설정이 필요하다.

 

Bound 설정을 위한 셋업 가이드라인 :

Bound가 너무 크다면 파티클 입자가 카메라 앵글에 잡히지 않더라도 VFX를 처리 및 렌더하기 때문에 리소스 낭비로 이어진다.

Bound가 너무 작다면 일부 파티클이 아직 화면에 남아있더라도 갑자기 렌더를 하지 않을수 있다(갑자기 등장하거나 사라지는 Popping 현상 유발)

 

 

기본적으로 Bound는 자동 계산되어서 설정되지만 다음과 같이 모드 변경 가능 :

-Automatic: 이펙트에 따라서 경계가 자동 확장되는 옵션이며, 가장 효율이 떨어지는 모드

-Manual: 직접 Bound의 사이즈를 설정하는 옵션. VFX마다 설정해야하기 때문에 작업 시간이 소요됌.

-Recorded: VFX Graph창 툴바 Control 패널에서 설정할수 있는 옵션이며, Record버튼을 누르면 Bound가 확장되면서 기록되고 Apply Bound를 눌러서 해당 Bound를 적용할수 있다.

 

 

 

 


 

Mesh LOD

Mesh를 이용한 파티클을 사용할 경우, LOD를 사용해서 카메라 거리에 따라 Mesh의 품질을 조절할 수 있다.

Output Mesh블록을 사용할때 Insector 창에서 LOD사용을 켤수 있으며 LOD에 쓰일 최대 4개의 Mesh를 지정 할 수 있다. 

 

 

 

수백만개의 Mesh 파티클을 생성한다면 모든 Mesh가 고품질의 Mesh일 필요가 없을 뿐더러 필요이상의 리소스 낭비로 이어진다.

LOD Value를 설정해서 화면에 몇% 크기로 보여지냐에 따라서 LOD모델을 설정하게 할수 있음.

밑의 설정의 경우 15%일때 LOD1, 10%일때 LOD2, 3%일때 LOD3, 0.1%일때 LOD4

 

 

 

위에서 4종류의 Mesh까지 설정할수 있는 Mesh Count 기능을 꼭 LOD를 위한 기능으로 사용하지 않을 수 있다.

예를 들어 각각 다른 4종류의 Mesh를 적용해서 매번 다른 위치에 배치할수 있는 랜덤성을 위해 사용도 가능하다.

 

4종류의 Mesh를 사용해서 매번 다르게 배치되는 모습

 

 


Particle Rendering

파티클과 Mesh를 렌더링 할때 목표 프레임을 맞추기 위한 팁 :

 

-Triangle particles: Triangle의 Geometry는 Quad의 절반이므로, 빠르게 움직이고 많은 양의 파티클을 렌더링 한다면 Quad보다는 효과적이다.

 

-Simplified lighting: Lit 셰이더가 필요하지 않은 상황이라면 리소스를 덜 사용하는 셰이더로 전환한다. 또는 셰이더 그래프를 사용해서 특정 효과에 필요하지 않은 기능들을 삭제한다든지, 빛 계산을 줄이거나 셰이더를 단순화하는 식으로 최적화가 가능하다.

 

 

-Low resolution transparency(HDRP에서만 해당): HDRP 렌더링 속성에서 'Low Resolution Transparency'로 설정해서 투명한 파티클은 낮은 해상도로 렌더링한다. 이를 통해 성능을 4배 향상 시킬수 있다.

 

-Octagon particles(HDRP에서만 해당): Quad 파티클의 모서리가 투명하다면 해당 영역만큼 Overdraw(픽셀 중복 계산)가 발생할수 있다. Octagon 파티클을 사용하면 모서리를 잘라낸 좀 더 둥근 형태이기 때문에 겹치는 투명 영역은 줄어든다. Quad 보다는 겹치는 투명 영역을 줄이므로 Overdraw 발생이 줄어든다.

 

 


 

Spaceship Demo의 최적화 사례

Spaceship 데모 프로젝트에서 우주선의 Sparkle이펙트는 최적화 및 재사용을 위해 텍스쳐 내에 데이터를 저장할수 있는 방법을 보여준다.

우주선 내부에서 많은 스파크들을 VFX Graph로 구현했으며, 수십 개의 스파크를 인스턴스화 하면 수백 개의 Drawcall이 발생하게 된다.

 

 

 

그래서 이 프로젝트는 해결책으로 VFX Property Binder에서 'MultiPosOrientedParameterBinder'를 사용한다.

이 속성은 많은 양의 Transform을 Point Cache Map으로 변환한다. 그러면 VFX Graph에서는 이 Map에 저장된 정보를 불러와서 활용하게 된다.

 

 

 

 

한번만 시뮬레이션 한 정보를 가지고 각각의 Map으로 데이터를 저장하고, Initialize Context에서 PositionMap, DirectionMap에 접근해서 정보를 가져와서 활용할수 있게 된다.

그러면 굳이 여러번 시뮬레이션을 하지 않고, 앞서 미리 시뮬레이션한 데이터만으로 동일한 효과(타이밍과 배치가 동일한)를 재현할수 있다. 

이 과정을 통해서 Drawcall과 VFX 인스턴스를 줄이게 된다.

텍스쳐에 데이터를 저장하는 것은 리얼타임 이펙트를 위한 일반적인 최적화 기법이다.

Unity 2021LTS 이상을 사용하는 경우 많은 데이터를 전달한다면 Graphic Buffer를 활용하는것도 방법이다.

 

Graphic Buffer를 이용한 샘플 프로젝트

 


 

스튜디오 오버그래픽스
정준희 Technical Artist
ovgrps@gmail.com