#

GPU Particle System / Geometry Shader Simulation

/ email – joohangi1@naver.com / tel – 010.7249.2623

//

– 유니티 URP 직접 코드로 제작한 메쉬인 비가 내리는 GPU 파티클 시스템.

지금까지 DirectX, 언리얼, 유니티 등 다양한 플렛폼으로 제작해오면서 직접 파티클 시스템을 제작하는 것을 선택사항이 아니었다. 특히 모바일 빌드나 VR 빌드 시 파티클 최적화 작업은 자주 있는 일이다. 게임엔진 내부에서 GPU연산으로 시스템을 설정하여도 모든 물리연산을 GPU로 하지 않기 때문에 눈이나 비와 같은 파티클을 생성할 때는 반드시 코드로 파티클 메쉬를 제작하는 것이 필수가 되어 버렸다. 다수의 파티클을 랜더링할 때 언리얼과 유니티에서 지원하는 유효한 최적한 기능은 인스턴싱 기능 정도일 것이다. 이 인스턴싱 기능조차 대형 게임회사에서는 최적화의 효율성을 높이기 위해 직접 인스턴싱을 구현하기도 한다.

//

– 언리얼 나이아가라 파티클 시스템 예시.
– Unity 파티클 시스템 예시.

필자가 파티클 시스템을 지금까지 시도했던 방식은 특수한 시멘틱 값을 가진 이팩트 메쉬를 생성하여 물리 연산을 버텍스 쉐이더에서 연산하는 방식이었다. 하지만 이 방식은 오로지 최적화를 위한 방식이지 시뮬레이션에 대한 구현이 불가능하였다. 왜냐하면 쉐이더 내부에 선언된 변수는 매 프레임 변수 값을 누적할 수 없기 때문이다. 반대로 언리얼, 유니티에서 실행되는 파티클 시스템은 충돌을 비롯한 시뮬레이션이 가능한데 이는 CPU에서 충돌 연산이 진행되기 때문이다. 그리고 이 사실은 유니티, 언리얼이 CPU 충돌 연산을 한다는 반증이기도 하다.

//

– 후디니에서 작업되는 파티클 제작 예시.

충돌 연산이 시뮬레이션의 메인 연산인데 CPU에서 돌리기에는 매우 무무거운 연산이고 모바일에서는 사용하기 힘들다. 그렇기 때문에 후디니에서 시뮬레이션 된 애니메이션을 구워서 VAT방식으로 게임엔진에서 재생시키는 것이다. 하지만 이 방식은 다른 충돌 조건에서도 동일한 파티클 애니메이션이 재생되기 때문에 진실된 시뮬레이션이 아니며, 1개의 이팩트에 1개의 텍스처를 동반하기 때문에 메모리 소모가 많다.

//

– HDRP의 TTA를 이용한 모션백터 방식.

오랫동안 파티클 시뮬레이션에 대해 고안해 왔는데 Unity HDRP의 Motion Vector Pass 방식과 착안해 여러 가설들을 기획해 보았다. 최근 Unity 2022 버전에서 Custom Deferred Shader를 작성할 수 있게 기능을 제공해 주는데 이 기능도 같이 사용하는 것을 기획했다.

– Unity 내부에서 모션 백터의 설정 과정.
– 실제 유니티 쉐이더 엔진 내부의 MotionVectorPass 실제 코드 내용.

처음에 접근해 보았던 방식은 Unity HDRP의 Motion Vector와 유사하게 카메라 화면에 잡히는 버텍스에 대한 정보를 기록하는 것이다. 동일하게 추가 Pass를 생성하여 이전 버텍스들의 정보들을 픽셀에 정보들을 저장하는 방식이다. 이 방식은 여러 문제점들이 발생하는데 알파 객체의 정보를 기록하는 것과 카메라에 잡히지 않는 것들에 대한 기록이다. 유니티에도 추가로 설정하는 기능들이 세팅되어 있지만 이 기능은 모션블러 정도를 구현하기 위한 수준이다. 실제 유니티 쉐이더 엔진 내부 코드를 뜯어보았다. 그리고 이를 참고해 실제 시뮬레이션을 구현하는 것은 불가능하다고 판단해 다른 방안을 모색하였다.

– 쉐이더 단계에서 버텍스를 텍스처에 기록하는 원리(바로가기).

모션백터와 같이 기존의 렌더링 파이프라인 방식을 사용한다면 픽셀 쉐이더 단계에서 다른 폴리곤에 의해 가려지는 버텍스가 생기게 되는데 가려진 버텍스는 픽셀 쉐이더 단계에서 픽셀에 기록할 수 없다는 점이 고민이었다. 그렇기 때문에 가려진 버텍스를 텍스처에 전부 기록 할 수 있는 시스템이 필요하다고 판단했다. 그래서 최근에 기존 렌더링 파이프라인이 아닌 추가적인 새로운 공간 좌표 파이프라인을 구상했고, 그것을 유니티 URP 환경에서 구현하는데 성공하였다. 자세한 원리는 위 링크에 첨부해두었으니 생략할 것이다.