Particle System

Date:     Updated:

카테고리:

태그:

홍정모님의 그래픽스 새싹코스 강의를 듣고 정리한 내용입니다.


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

HongLabGraphicsExample2024-09-2400-06-15-ezgif com-crop


Example 2

HongLabGraphicsExample2024-09-2601-29-32-ezgif com-crop

  • Bill Board 위에 미리 준비한 텍스처 사용
  • 파티클에 중력 대신 위로 올라가는 부력 적용
  • 파티클을 이용해 여러가지 이펙트 효과를 나타낼 수 있음



맨 위로 이동하기

Graphics 카테고리 내 다른 글 보러가기

댓글 남기기