icon안동민 개발노트

정적 메시와의 기본 콜리전


 나이아가라 파티클 시스템에서 정적 메시와의 콜리전 처리는 더욱 사실적이고 상호작용적인 시각 효과를 만드는 데 중요한 역할을 합니다.

 이 절에서는 기본적인 콜리전 설정부터 고급 기법까지 다양한 측면을 살펴보겠습니다.

콜리전 모듈 설정

 1. 모듈 추가

  • 나이아가라 에디터에서 'Add Module' 버튼 클릭
  • 'Collision' 모듈 선택

 2. 기본 설정

Collision Mode: Scene Depth Collision
Collision Response: Bounce
Friction: 0.5
Bounciness: 0.3

 3. 콜리전 소스 지정

  • 'Collision Source' 속성에서 사용할 정적 메시 선택

다양한 콜리전 응답 유형 구현

  1. 반사 (Bounce)
void ApplyBounce(inout float3 Velocity, float3 Normal, float Bounciness)
{
      Velocity = reflect(Velocity, Normal) * Bounciness;
}
  1. 정지 (Stop)
void ApplyStop(inout float3 Velocity)
{
      Velocity = float3(0, 0, 0);
}
  1. 파괴 (Destroy)
void ApplyDestroy(inout bool IsAlive)
{
      IsAlive = false;
}
  1. 슬라이딩 (Slide)
void ApplySlide(inout float3 Velocity, float3 Normal, float Friction)
{
      float3 TangentialVelocity = Velocity - dot(Velocity, Normal) * Normal;
      Velocity = TangentialVelocity * (1.0 - Friction);
}

콜리전 이벤트 처리

 1. 이벤트 모듈 추가

  • 'Add Module' > 'Event Handler' 선택
  • 'On Particle Collision' 이벤트 선택

 2. 이벤트 응답 스크립트 작성

void OnCollisionResponse(inout float3 Position, inout float3 Velocity, float3 Normal)
{
      // 충돌 위치 조정
      Position += Normal * 0.01; // 약간의 오프셋 추가로 중첩 방지
      
      // 속도 변경
      ApplyBounce(Velocity, Normal, 0.5);
      
      // 추가 효과 (예: 파티클 생성)
      SpawnCollisionParticles(Position, Normal);
}

콜리전 필터링

 1. 레이어 기반 필터링

  • 'Collision' 모듈의 'Collision Filter' 속성 사용
  • 특정 오브젝트 레이어와만 충돌하도록 설정

 2. 거리 기반 필터링

void FilterCollisionByDistance(inout bool ShouldCollide, float3 ParticlePosition, float3 CollisionPoint, float MaxDistance)
{
      ShouldCollide = distance(ParticlePosition, CollisionPoint) < MaxDistance;
}

콜리전 정보를 활용한 파티클 동작 변경

  1. 표면 속성에 따른 반응
void AdjustParticleProperties(inout float4 Color, inout float Size, float3 SurfaceNormal)
{
      // 표면 기울기에 따른 색상 변경
      Color = lerp(Color, float4(1,0,0,1), abs(dot(SurfaceNormal, float3(0,0,1))));
      
      // 충돌 후 크기 감소
      Size *= 0.9;
}
  1. 충돌 횟수에 따른 동작
void UpdateBasedOnCollisionCount(inout float3 Velocity, inout bool IsAlive, int CollisionCount, int MaxCollisions)
{
      Velocity *= (1.0 - float(CollisionCount) / float(MaxCollisions));
      IsAlive = CollisionCount < MaxCollisions;
}

효율적인 콜리전 처리를 위한 최적화 기법

 1. 공간 분할 구조 활용

  • 옥트리(Octree) 또는 균일 그리드를 사용하여 콜리전 체크 최적화

 2. LOD (Level of Detail) 시스템 구현

void ApplyCollisionLOD(inout bool PerformCollision, float DistanceFromCamera, float MaxDistance)
{
      PerformCollision = DistanceFromCamera < MaxDistance;
}

 3. 배치 처리

  • 유사한 속성을 가진 파티클들을 그룹화하여 한 번에 처리

성능 영향 고려사항

 1. 파티클 수 관리

  • 콜리전 체크가 필요한 파티클 수를 제한

 2. 콜리전 복잡도 조절

  • 단순화된 콜리전 메시 사용
  • 중요도가 낮은 오브젝트의 콜리전 비활성화

 3. CPU vs GPU 콜리전

  • 가능한 경우 GPU 기반 콜리전 사용으로 CPU 부하 감소

설계 전략 팁

 1. 계층적 콜리전 시스템

  • 대략적인 콜리전 체크 후 정밀한 체크 수행

 2. 콜리전 응답 다양화

  • 파티클 유형이나 상황에 따라 다른 응답 적용

 3. 시각적 피드백 강화

  • 콜리전 지점에 추가 이펙트 생성으로 상호작용 강조

적용 예시 : 눈 파티클 시스템

 다음은 정적 메시와 상호작용하는 눈 파티클 시스템의 구현 예시입니다.

void UpdateSnowParticle(inout float3 Position, inout float3 Velocity, inout float4 Color, 
                        inout float Size, inout bool IsAlive, float3 CollisionNormal, 
                        bool HasCollided, int CollisionCount, float DeltaTime)
{
    // 기본 업데이트
    Velocity += float3(0, 0, -9.8) * DeltaTime; // 중력 적용
    Position += Velocity * DeltaTime;
 
    // 콜리전 응답
    if (HasCollided)
    {
        // 눈이 쌓이는 효과
        Position += CollisionNormal * 0.01;
        
        // 속도 감소
        Velocity = reflect(Velocity, CollisionNormal) * 0.1;
        
        // 색상 변경 (쌓인 눈 효과)
        Color = lerp(Color, float4(0.9, 0.9, 1.0, 1.0), 0.5);
        
        // 크기 증가 (쌓인 눈 표현)
        Size *= 1.1;
        
        // 일정 시간 후 사라짐
        IsAlive = CollisionCount < 5;
    }
    
    // 바람 효과
    Velocity += float3(sin(Time * 0.5), cos(Time * 0.4), 0) * 0.1;
    
    // LOD 기반 콜리전
    ApplyCollisionLOD(HasCollided, length(CameraPosition - Position), 1000);
}

 이 예시에서는 눈 파티클이 지형과 충돌할 때 쌓이는 효과를 시뮬레이션합니다.

 콜리전 시 파티클의 위치, 속도, 색상, 크기가 변화하며, 일정 횟수 이상 충돌하면 파티클이 소멸합니다.

 또한 간단한 바람 효과와 거리 기반 LOD 시스템을 구현하여 성능을 최적화합니다.

 정적 메시와의 콜리전을 효과적으로 구현하면 파티클 시스템이 환경과 더욱 자연스럽게 상호작용하는 것처럼 보이게 할 수 있습니다.