PART 4 · 강의 2/3

Neighbor Grid Simulation

공간 해싱(Spatial Hashing) 기반의 Neighbor Grid 3D로 파티클 간 상호작용을 구현합니다.

01

Neighbor Grid 3D 개념

공간 해싱으로 효율적인 이웃 탐색

Neighbor Grid 3D는 3D 공간을 균일한 격자(Grid)로 분할하고, 각 파티클을 해당 셀에 등록하는 공간 해싱 구조입니다. 이를 통해 특정 파티클의 근접 이웃을 O(1)에 가까운 시간으로 검색할 수 있습니다.

Neighbor Grid 원리
// 전체 공간을 격자로 분할 // 각 파티클은 자신의 위치에 해당하는 셀에 등록 // 이웃 검색 시 인접 셀(3x3x3 = 27개)만 확인 공간 분할 예시 (2D 단순화): +-----+-----+-----+-----+ | | P1 | | | +-----+-----+-----+-----+ | | P0 | P2 | | P0의 이웃: P1, P2, P3 +-----+-----+-----+-----+ (인접 셀에 있는 파티클만 검색) | | P3 | | | +-----+-----+-----+-----+ | | | | | +-----+-----+-----+-----+ 셀 크기(Cell Size) 가 중요: 작은 셀 → 정밀한 검색, 높은 메모리/연산 비용 큰 셀 → 빠른 검색, 불필요한 파티클도 포함
왜 Neighbor Grid가 필요한가

N개 파티클 간 모든 쌍을 비교하면 O(N^2)의 비용이 듭니다. 10만 파티클이면 100억 번의 비교가 필요합니다. Neighbor Grid를 사용하면 각 파티클당 인접 셀의 파티클만 확인하므로, 평균적으로 O(N x K) (K = 평균 이웃 수)로 줄어듭니다.

02

Neighbor Grid 설정 절차

Data Interface 추가부터 Simulation Stage까지

Neighbor Grid 3D 설정 단계
// 전제 조건: GPU Compute Sim 모드 필수 Step 1: Neighbor Grid 3D Data Interface 추가 Emitter Spawn → Set (NeighborGrid3D) { Num Cells X/Y/Z: 32 // 각 축의 셀 수 World BBox Size: 1000.0 // 그리드 전체 크기 (cm) Max Neighbors Per Cell: 16 // 셀당 최대 파티클 수 } Step 2: Simulation Stage 1 - 파티클을 그리드에 등록 Iteration Source: ParticlesNeighbor Grid 3D - Fill Grid Grid: NeighborGrid3D Position: Particles.Position Step 3: Simulation Stage 2 - 이웃 검색 및 힘 계산 Iteration Source: ParticlesCustom Scratch Pad Module // 이웃 파티클과의 상호작용 로직 Step 4: Particle Update - 결과 반영Solve Forces and Velocity

주요 Neighbor Grid 함수

함수 용도
Num Cells.Set 그리드의 셀 수 설정 (초기화)
SetParticleNeighborCount 특정 셀에 이웃 수 기록
GetParticleNeighborCount 특정 셀의 이웃 수 조회
GetParticleNeighbor 특정 셀의 N번째 이웃 파티클 인덱스 반환
NeighborGridIndexToLinear 3D 셀 인덱스를 1D 인덱스로 변환
03

파티클 간 충돌/반발 구현

Neighbor Grid를 활용한 인터랙션

Custom HLSL - 파티클 간 반발력
// Simulation Stage 2의 Scratch Pad 모듈 내부 // 입력: InPosition, InGrid (NeighborGrid3D), InRepelForce, InMinDistance // 출력: OutForce (Vector3) float3 TotalForce = float3(0, 0, 0); int CellX, CellY, CellZ; // 현재 파티클의 셀 좌표 계산 InGrid.WorldToUnit(InPosition, CellX, CellY, CellZ); // 인접 27개 셀 순회 (-1, 0, +1) for (int dx = -1; dx <= 1; dx++) for (int dy = -1; dy <= 1; dy++) for (int dz = -1; dz <= 1; dz++) { int NX = CellX + dx, NY = CellY + dy, NZ = CellZ + dz; int NeighborCount; InGrid.GetParticleNeighborCount(NX, NY, NZ, NeighborCount); for (int i = 0; i < NeighborCount; i++) { int NeighborIdx; InGrid.GetParticleNeighbor(NX, NY, NZ, i, NeighborIdx); float3 NeighborPos; // Particle Attribute Reader로 이웃 위치 읽기 InputDataFloat(NeighborIdx, 0, NeighborPos.x); InputDataFloat(NeighborIdx, 1, NeighborPos.y); InputDataFloat(NeighborIdx, 2, NeighborPos.z); float3 Dir = InPosition - NeighborPos; float Dist = length(Dir); if (Dist > 0.001 && Dist < InMinDistance) { float Strength = 1.0 - Dist / InMinDistance; TotalForce += normalize(Dir) * Strength * InRepelForce; } } } OutForce = TotalForce;
Cell Size 튜닝

World BBox Size / Num Cells가 셀 크기를 결정합니다. 셀 크기는 파티클 간 최대 상호작용 거리(InMinDistance)와 같거나 약간 크게 설정해야 합니다. 너무 작으면 이웃을 놓치고, 너무 크면 불필요한 검색이 늘어납니다.

04

실전 활용 사례

Boids, SPH, 군중 시뮬레이션

Boids (군집 행동)

새떼, 물고기 떼 등의 군집 행동은 Neighbor Grid의 대표적 활용 사례입니다. 3가지 규칙으로 구현합니다.

규칙 설명 구현
Separation 너무 가까운 이웃으로부터 멀어지기 거리 기반 반발력
Alignment 이웃의 평균 방향으로 정렬 이웃 Velocity 평균 계산
Cohesion 이웃의 중심으로 모이기 이웃 Position 평균 방향으로 힘
성능 고려

Neighbor Grid 시뮬레이션에서 Max Neighbors Per Cell은 셀당 저장할 수 있는 최대 파티클 수입니다. 이 값을 초과하면 일부 파티클이 무시됩니다. 너무 높게 설정하면 메모리와 검색 비용이 증가합니다. 일반적으로 8~32가 적절합니다.

SUMMARY

핵심 요약

  • Neighbor Grid 3D는 공간 해싱으로 파티클의 이웃을 효율적으로 검색하는 Data Interface입니다.
  • 구현 절차: Grid 초기화 → Sim Stage 1(Grid 채우기) → Sim Stage 2(이웃 검색) → 결과 반영
  • 셀 크기는 파티클 간 최대 상호작용 거리와 같거나 크게 설정해야 합니다.
  • Max Neighbors Per Cell은 8~32가 적절하며, 초과 시 파티클이 무시됩니다.
  • Boids(군집), SPH(유체), 반발/충돌 등 파티클 간 상호작용의 핵심 기술입니다.
  • GPU Compute Sim에서만 사용 가능하며, Simulation Stage와 함께 동작합니다.
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: 기본 Neighbor Grid 설정

Neighbor Grid3D Data Interface를 추가하고, Particle Spawn에서 그리드에 파티클을 등록, Particle Update에서 이웃 파티클을 검색하는 기본 구조를 만드세요. Grid Cell Size와 Max Neighbors를 실험하세요.

실습 2: 파티클 간 인력/척력 구현

Neighbor Grid로 주변 파티클을 검색한 뒤, 거리에 따른 인력(가까우면 척력, 멀면 인력)을 적용하여 파티클이 균일한 간격을 유지하며 뭉치는 시뮬레이션을 만드세요.

심화 과제: Flocking 시뮬레이션

Boids 알고리즘(Separation, Alignment, Cohesion)을 Neighbor Grid를 사용하여 구현하세요. 수천 개의 파티클이 새떼처럼 군집 행동을 하는 GPU 기반 시뮬레이션을 완성하세요.