ParticleSystem
이 엔진의 파티클 시스템은 DirectX 11의 Stream-Out 기능을 활용한 GPU 기반 구현입니다. 파티클의 생성, 업데이트, 렌더링이 모두 GPU에서 처리되며, 핑퐁 버퍼링을 통해 CPU의 개입 없이 파티클 시뮬레이션이 이루어집니다.
파티클 데이터 구조
파티클 시스템 초기화
ParticleSystem 클래스 초기화 시 세 종류의 버퍼를 생성합니다:
이어서 BuildVB 메서드에서 필요한 버퍼들을 생성합니다:
애미터 파티클은 실제 렌더링 될 파티클을 생성하기 위한 선봉대장의 역할을 하며 Geometry Shader에서 입력된 정점 버퍼의 타입이 애미터라면 새로운 파티클 정점을 생성시킵니다. 이로써 시간이 지남에 따라 점점 많은 수의 파티클 정점(최대 개수를 넘기지 않은)이 StreamOut 버퍼에 저장이 되며 이렇게 GPU에서 생성된 버퍼를 기반으로 파티클을 렌더링 합니다.
파티클 업데이트 과정 (Stream-Out)
파티클 업데이트는 InitParticleSystem.hlsl의 지오메트리 셰이더에서 처리됩니다:
셰이더 코드에선 랜덤 한 값을 생성할 수 없기 때문에 랜덤 데이터가 입력되어 있는 Random 텍스처를 활용하여 파티클의 초기 속도와 방향을 결정할 때 사용합니다.
폭발형 파티클 업데이트
폭발형 파티클은 InitParticleSystem_Bomb.hlsl에서 처리되며, 일반 파티클과 달리 한 번에 다수의 파티클을 생성합니다:
파티클 렌더링 과정
파티클 렌더링은 RenderParticleSystem.hlsl에서 처리됩니다:
InitParticleSystem.hlsl에서 생성된 정점 데이터를 사용하여 실제 파티클 렌더링을 실행합니다. 빌보드 렌더링 기법을 통해 2D인 파티클 입자들이 항상 카메라를 바라보게 하여 입체감 있는 효과를 표현합니다.
RenderPass에서 파티클 처리 방식
초기 설정 및 데이터 준비
먼저 파티클 시스템 컴포넌트를 가져오고, 파티클 타입에 따라 적절한 초기화 셰이더를 선택합니다. FLARE 타입은 일반적인 파티클 분출을, BOMB 타입은 폭발 효과를 위한 것입니다.
파티클 시뮬레이션 데이터 설정
파티클 시뮬레이션에 필요한 데이터를 ParticleBuffer 구조체에 설정합니다:
뷰 및 프로젝션 행렬
게임 시간과 시간 간격(델타 타임)
파티클 생성 종료 여부
카메라 위치
파티클 방출 위치와 방향
gGameTime은 게임이 시작된 이후 경과한 총 시간(초 단위)을 나타냅니다. 이는 계속 증가하는 값으로, 게임 실행 중 누적된 절대 시간을 의미합니다. 이를 통해 셰이더에서 매 프레임마다 다른 랜덤 값을 얻어 사용할 수 있습니다.
gTimeStep은 이전 프레임과 현재 프레임 사이의 경과 시간(델타 타임)을 나타냅니다. 이 값을 통해 파티클 시뮬레이션 속도 제어를 위한 상대적 시간 간격을 설정할 수 있습니다.
파티클 업데이트 단계 (Stream-Out)
이 단계는 파티클의 위치, 속도, 나이 등을 업데이트합니다:
첫 실행 시에는 _initVB(에미터 파티클 1개만 포함)를 입력으로 사용
이후 실행에서는 _drawVB(이전 프레임의 모든 파티클)를 입력으로 사용
지오메트리 셰이더는 Stream-Out 기능을 통해 업데이트된 파티클 데이터를 _streamOutVB에 기록
Draw(1, 0) 또는 DrawAuto()를 호출하여 파티클 업데이트 실행
버퍼를 스왑하여 업데이트된 파티클 데이터를 다음 단계의 입력으로 사용
파티클 렌더링 단계
이 단계는 업데이트된 파티클을 화면에 렌더링합니다:
렌더 상태(래스터라이저, 깊이/스텐실, 블렌드) 설정
파티클 데이터를 포함한 버퍼를 입력으로 설정
렌더링용 셰이더 설정
파티클 텍스처와 변환 정보를 셰이더에 전달
특히 가산 블렌딩(Additive Blending)을 사용하여 파티클의 빛 효과 구현
DrawAuto()를 호출하여 파티클 그리기
주요 특징 및 최적화 요소
GPU 기반 파티클 시뮬레이션:
파티클의 생성, 업데이트, 소멸이 모두 GPU에서 처리됨
CPU는 초기 설정과 렌더링 명령만 담당하므로 부하 감소
Stream-Out 기능 활용:
DirectX의 Stream-Out 기능으로 셰이더 처리 결과를 버퍼에 직접 기록
이전 프레임의 결과가 다음 프레임의 입력으로 즉시 활용
핑퐁 버퍼링:
_drawVB와 _streamOutVB 버퍼를 교대로 사용하여 데이터 흐름 최적화
매 프레임마다 버퍼를 스왑하여 효율적인 메모리 관리
파티클 타입별 최적화:
FLARE 타입과 BOMB 타입에 따라 다른 셰이더 사용
각 타입에 맞는 파티클 행동 패턴 구현
빌보드 기법:
지오메트리 셰이더에서 포인트를 카메라 방향을 향하는 사각형으로 확장
이를 통해 3D 공간에서 효율적으로 2D 텍스처 표현
가산 블렌딩:
blendState->CreateAdditiveBlendState() 호출로 파티클의 빛 효과 구현
여러 파티클이 겹칠 때 더 밝게 보이는 효과 생성
Last updated