Particle System
카테고리: Graphics
태그: DirectX
홍정모님의 그래픽스 새싹코스 강의를 듣고 정리한 내용입니다.
Particle System
int newCount = 50;
for (auto &p : m_particlesCPU) {
if (AppBase::m_leftButton && p.life < 0.0f && newCount > 0) {
const float theta = randomTheta(gen);
p.position = Vector3(m_mouseNdcX, m_mouseNdcY, 0.0);
p.velocity = Vector3(cos(theta), -sin(theta), 0.0) * randomSpeed(gen);
p.life = randomLife(gen) * 1.5f;
newCount--;
}
}
- (마우스 클릭 시) 생성되는 파티클은 50개
- 생성 위치는 마우스 위치 & 속도는 랜덤한 방향과 속력
- 파티클마다 radius를 가지고 있는데 랜덤하게 초기값 설정되어 있음
const Vector3 gravity = Vector3(0.0f, -9.8f, 0.0f);
const float groundHeight = -0.8f;
for (auto &p : m_particlesCPU) {
if (p.life < 0.0f)
continue;
p.velocity += gravity * dt;
p.position += p.velocity * dt;
p.life -= dt*2;
if (p.position.y < groundHeight && p.velocity.y < 0.0f) {
p.velocity.y *= -randomLife(gen);
p.position.y = groundHeight;
}
if (p.position.x < -1.0f && p.velocity.x < 0.0f) {
p.velocity.x *= -randomLife(gen);
p.position.x = -1.0f;
}
if (p.position.x > 1.0f && p.velocity.x > 0.0f) {
p.life = -1.0;
}
}
m_context, m_particlesStagingGPU, UINT(sizeof(Particle) * m_particlesCPU.size()), m_particlesCPU.data());
m_context->CopyResource(m_particlesGPU.Get(), m_particlesStagingGPU.Get());
- 파티클의 위치 수정 후 벽에 부딪힌 경우 처리
- 보통 Coefficient of Restitution(복원 계수)를 이용해 계산하지만
- 여기서는 간단하게 랜덤 변수를 이용해 반대 방향으로 튕기게만 작용
- 이후 렌더링 과정은 Density Field와 동일하게 GS/PS (bill-board) 이용
- 이번 예제에서 물리 연산은 CPU에서 진행
- 이런 경우 매 프레임 Staging 버퍼를 이용해 ( CPU에서 물리 연산 -> GPU 버퍼로 데이터 복사 ) 과정이 필요
- 복잡한 물리 연산은 오히려 CPU에서 하는게 좋은 경우도 많음
Result
Example 2
- Bill Board 위에 미리 준비한 텍스처 사용
- 파티클에 중력 대신 위로 올라가는 부력 적용
- 파티클을 이용해 여러가지 이펙트 효과를 나타낼 수 있음
댓글 남기기