Unity VFX Graph와 Shader Graph 연동으로 화염·폭발 입자 구현하기
Unity VFX Graph와 Shader Graph를 연동해 화염과 폭발 입자의 색·왜곡·소멸을 제어하는 방법을 정리합니다. 노이즈, 커스텀 데이터, 블렌딩, 성능 최적화까지 단계별로 설명합니다.

화염과 폭발 입자는 VFX Graph가 입자의 수명·속도·스폰을 담당하고 Shader Graph가 픽셀 단위의 색 변화·노이즈 왜곡·발광을 담당하도록 분리하면 안정적으로 제작할 수 있다. 핵심은 입자마다 전달한 age, lifetime, random, custom1.x 값을 Shader Graph에서 정규화해 알파와 색, 왜곡 강도를 같은 시간축으로 제어하는 것이다.
VFX Graph와 Shader Graph를 왜 함께 사용해야 할까?
VFX Graph만으로도 스프라이트, 크기, 색, 속도를 바꿀 수 있다. 하지만 화염 가장자리의 불규칙한 침식, 폭발의 열 왜곡, 시간에 따른 발광 변화처럼 픽셀 단위 제어가 필요한 표현은 Shader Graph가 더 적합하다.
| 역할 | VFX Graph | Shader Graph |
|---|---|---|
| 입자 생성량과 버스트 | Spawn Context | 해당 없음 |
| 위치·속도·중력 | Update Context | 해당 없음 |
| 메시에 전달할 데이터 | Set Attribute, Custom Attribute | Vertex/Fragment 입력 |
| 노이즈 마스킹과 왜곡 | 제한적 | Texture Sample, Simple Noise, UV 연산 |
| 발광 색과 알파 | Color Attribute | HDR Color, Alpha Clip, Additive Blend |
권장 파이프라인은 Universal Render Pipeline 또는 High Definition Render Pipeline에서 Visual Effect Graph와 Shader Graph를 함께 사용하는 구성이다. 두 패키지와 프로젝트의 렌더 파이프라인 버전은 Unity Package Manager에서 같은 Unity LTS 계열에 맞춰 유지한다.

화염·폭발 연동 구조는 어떻게 설계할까?
화염은 위로 흐르는 지속형 입자이고 폭발은 짧은 시간에 에너지가 팽창한 뒤 사라지는 버스트형 입자다. 하나의 셰이더를 공유할 수는 있지만 스폰 방식과 수명 곡선은 분리하는 편이 제어하기 쉽다.
flowchart LR
A[Spawn Context] --> B[Initialize Particle]
B --> C[Set Lifetime, Velocity, Custom Data]
C --> D[Update: Force and Drag]
D --> E[Output Particle Quad]
E --> F[Shader Graph: Noise Mask]
F --> G[HDR Emission and Alpha]
전달할 입자 데이터
다음 네 값만으로도 화염과 폭발의 대부분의 시간 기반 표현을 만들 수 있다.
| 데이터 | 용도 | 권장 범위 |
|---|---|---|
age | 현재 생존 시간 | 0 이상 |
lifetime | 전체 생존 시간 | 0.3~3.0초 |
random | 입자별 변주 | 0~1 |
custom1.x | 화염/폭발별 왜곡 또는 밝기 보정 | 0~1 |
정규화 시간은 다음처럼 계산한다. saturate는 값을 0~1 범위로 제한한다.
VFX Graph에서는 Set Lifetime으로 수명을 지정하고 Set Custom Attribute 또는 출력 컨텍스트의 커스텀 버텍스 스트림 설정으로 custom1.x를 전달한다. 프로젝트 버전에 따라 노드 이름과 출력 UI가 다를 수 있으므로 Output Particle Quad의 Vertex Attributes 목록에서 셰이더가 요구하는 속성이 실제로 활성화됐는지 확인한다.
화염 이펙트를 단계별로 구현하기
1. VFX Graph에서 화염의 움직임 만들기
지속형 화염은 일정한 Rate Spawn과 약한 난수성이 중요하다.
- Spawn Context에
Constant Spawn Rate를 넣고 초당 30~100개 수준에서 시작한다. - Initialize Context에서 Position은 작은 원 또는 박스 범위로 분산하고 Lifetime은 0.6~1.4초로 랜덤화한다.
- Velocity에 위쪽 방향 속도와 작은 난수를 적용한다. Update Context에는
Turbulence또는 Curl Noise 기반 힘과 Drag를 더한다. - 크기는 수명 초반에 빠르게 커지고 후반에 줄어들도록 Curve를 설정한다.
화염의 시작이 너무 균일하면 토치나 화염방사기처럼 보인다. Position, Velocity, random 중 최소 두 항목에는 난수 분산을 준다.
2. Shader Graph에서 불꽃 마스크 만들기
Unlit Shader Graph를 만든 뒤 Graph Inspector에서 Surface를 Transparent로 설정한다. 일반적인 발광 화염에는 Additive 또는 Premultiply 블렌드가 적합하다. 배경이 밝을 때 형태를 유지해야 하면 Premultiply가 관리하기 쉽다.
그래프는 다음 순서로 구성한다.
UV에 Tiling and Offset을 적용해 세로로 흐르는 노이즈 좌표를 만든다.Time의 Time 값을 Y 오프셋에 더해 노이즈가 위로 이동하게 한다.Sample Texture 2D또는Gradient Noise결과와 원형 그라디언트 텍스처를 Multiply한다.- 정규화 시간
t가 커질수록 Threshold를 올려 가장자리가 침식되게 한다. - 결과를 Alpha와 Emission 입력에 연결한다.
노이즈 좌표의 한 예는 다음과 같다.
여기서 random은 VFX Graph에서 전달한 입자별 난수다. 모든 입자가 같은 UV 애니메이션을 공유하면 반복 무늬가 눈에 띄므로 난수 기반 오프셋을 반드시 추가한다.

3. 시간에 따라 색과 발광을 바꾸기
불꽃의 색을 단순한 노랑 하나로 고정하면 평면적으로 보인다. t를 기준으로 흰색 또는 노랑에서 주황, 붉은색으로 이동시키고 후반에는 알파를 빠르게 낮춘다.
// Custom Function 노드에 넣을 수 있는 개념 예시
float normalizedAge = saturate(age / max(lifetime, 0.001));
float heat = saturate(1.0 - normalizedAge * 1.25);
float3 fireColor = lerp(float3(1.0, 0.08, 0.0), float3(1.0, 0.85, 0.25), heat);
float emissionStrength = lerp(0.4, 3.0, heat) * custom1x;
float alpha = noiseMask * smoothstep(1.0, 0.65, normalizedAge);
Shader Graph에서는 같은 로직을 Divide, Saturate, Lerp, Smoothstep 노드로 만들 수 있다. Emission에는 HDR Color를 사용하고 Bloom을 활성화하면 고온 영역이 자연스럽게 퍼진다. 다만 Bloom은 화면 전체 후처리 비용을 늘리므로 화염 머티리얼의 과도한 HDR 강도로 문제를 해결하려 하지 않는 편이 좋다.
폭발 입자는 화염과 무엇이 달라야 할까?
폭발은 불꽃 한 종류가 아니라 역할이 다른 여러 레이어의 조합이다. 최소한 섬광, 화염 덩어리, 연기, 파편을 분리한다.
| 레이어 | Spawn 방식 | 수명 | 셰이더 핵심 |
|---|---|---|---|
| 섬광 | 단발 Burst | 0.05~0.15초 | 강한 HDR Emission, 빠른 알파 감소 |
| 화염 덩어리 | 단발 Burst | 0.3~0.9초 | 팽창 노이즈, 주황·적색 변화 |
| 연기 | 지연 Burst 또는 Rate | 1.5~4초 | 낮은 대비, 느린 UV 이동 |
| 파편 | 단발 Burst | 0.8~3초 | Mesh 출력, 중력, 회전 |
폭발 중심부의 밝기는 시간에 따라 급격히 감소해야 한다. 지수 감쇠 형태를 쓰면 선형 보간보다 순간적인 에너지 방출에 가깝게 보인다.
Shader Graph에 Exponential 노드가 없거나 플랫폼 호환성을 단순하게 유지하고 싶다면 Pow(1 - t, k)로 근사할 수 있다. k는 3~8 범위에서 시작해 조정한다.
열 왜곡은 어떻게 추가할까?
열 왜곡은 투명한 화염 입자에 직접 적용하기보다 별도의 왜곡 전용 Output으로 분리하는 편이 안전하다. URP에서는 화면 색상 텍스처 설정과 렌더러 기능 구성이 필요할 수 있으며 HDRP에서는 Distortion 출력과 해당 프레임 설정을 사용한다. 파이프라인별 지원 방식이 다르므로 프로젝트에서 사용하는 렌더 파이프라인의 왜곡 경로를 먼저 확인한다.
- 회색조 노이즈 텍스처 또는 두 장의 서로 다른 노이즈를 준비한다.
- 노이즈 값을 -0.5~0.5로 중심 이동한 뒤 X/Y 벡터로 사용한다.
custom1.x와 알파 마스크를 곱해 왜곡이 입자 중심에서만 강하게 보이게 한다.- 왜곡 강도는 화면 UV 기준 0.002~0.015 정도의 작은 값부터 검증한다.
왜곡이 지나치면 배경이 물결치는 효과로 보이고 카메라 이동 시 깜빡임도 커진다. 모바일이나 다수의 폭발이 동시에 발생하는 상황에서는 왜곡 레이어를 생략하거나 최대 동시 개수를 제한하는 것이 낫다.
VFX Graph와 Shader Graph 연동에서 자주 생기는 문제
알파가 사각형으로 보이는 이유는 무엇인가?
대부분 원형 마스크의 Alpha를 출력에 연결하지 않았거나 Transparent Surface의 블렌드 설정과 프리멀티플라이 색 계산이 맞지 않은 경우다. 마스크는 Emission뿐 아니라 Alpha에도 연결하고 Premultiply 모드라면 최종 RGB에 Alpha를 곱하는 흐름을 점검한다.
입자마다 노이즈가 똑같이 움직이는 이유는 무엇인가?
셰이더가 Time과 UV만 사용하기 때문이다. VFX Graph의 random 또는 particleId 기반 값을 노이즈 UV 오프셋에 더해 입자별 위상을 분리한다. particleId는 매우 큰 정수일 수 있으므로 frac(sin(id) * 43758.5453) 같은 해시로 0~1 난수로 변환해 사용할 수 있다.
폭발이 멀리서 지나치게 밝아지는 이유는 무엇인가?
Additive 블렌드 입자가 겹치면서 밝기가 누적되기 때문이다. 버스트 개수와 입자 면적을 먼저 줄이고 Emission 강도를 낮춘다. 필요하면 중심 섬광만 Additive로 유지하고 화염 덩어리는 Alpha 또는 Premultiply 블렌드로 분리한다.
성능을 지키는 최적화 체크리스트
- 폭발을 하나의 거대한 시스템으로 만들기보다 레이어별 최대 입자 수를 명시한다.
- 모바일에서는 Gradient Noise보다 텍스처 샘플 수가 적은 마스크를 우선 검토한다.
- 투명 파티클은 오버드로를 만들기 쉬우므로 큰 쿼드를 여러 장 겹치지 않는다.
- Alpha Clip은 형태를 선명하게 만들지만 경계 앨리어싱과 픽셀 폐기를 유발할 수 있다. 화염에는 낮은 임계값으로 제한적으로 사용한다.
- 연기와 화염의 그림자 투사는 필요한 장면에서만 켠다.
- VFX Graph의
Max Capacity는 실제 동시 발생량을 기준으로 잡고 플레이 중 Visual Effect 디버그 정보로 실제 입자 수를 확인한다.
자주 묻는 질문 (FAQ)
VFX Graph 전용 셰이더 대신 일반 Shader Graph를 사용할 수 있나?
가능하다. 다만 VFX Graph Output이 요구하는 Position, Color, UV, Custom Attribute 같은 버텍스 스트림을 셰이더가 사용하도록 구성해야 한다. 사용하지 않는 속성은 제거해 대역폭을 줄인다.
화염과 연기에 같은 Shader Graph를 써도 되나?
기본 마스크 로직은 공유할 수 있다. 하지만 화염은 HDR Emission과 빠른 색 변화를 연기는 낮은 발광과 느린 알파 변화를 요구하므로 노출 파라미터가 다른 변형 또는 별도 머티리얼이 필요하다.
Custom Attribute는 언제 사용해야 하나?
Color, Age, Lifetime만으로 부족할 때 사용한다. 예를 들어 폭발 중심으로부터의 거리, 왜곡 강도, 입자 종류 인덱스를 전달해 하나의 셰이더에서 서로 다른 레이어를 제어할 수 있다.
정리
VFX Graph와 Shader Graph의 연동은 입자의 물리적 움직임과 화면상 질감을 분리하는 작업이다. VFX Graph에서는 수명, 속도, 난수, 커스텀 데이터를 설계하고 Shader Graph에서는 정규화 시간과 노이즈 마스크를 이용해 색·알파·발광·왜곡을 계산한다. 먼저 화염 한 레이어를 완성한 뒤 섬광, 연기, 파편을 독립 레이어로 추가하면 폭발 연출의 품질과 성능을 함께 관리할 수 있다.



