3D 가우시안 스플래팅(3DGS): 리얼타임 던전 배경 스캔과 고품질 리소스 반영 가이드

3D 가우시안 스플래팅(3DGS)을 활용해 실제 동굴과 던전 배경을 스캔하고 게임 엔진에 고품질 실시간 리소스로 반영하는 파이프라인과 최적화 기법을 소개합니다.

✓ 복사 완료!
챕터렌더링 파이프라인 & 배칭
난이도중급
상태● 검토 완료
대상 엔진
Engine Agnostic
최종 업데이트
3D 가우시안 스플래팅(3DGS): 리얼타임 던전 배경 스캔과 고품질 리소스 반영 가이드

기존 스캐닝 기술의 한계와 3D 가우시안 스플래팅의 등장

게임 배경을 실사 환경에서 3D 리소스로 전환하는 그래픽 파이프라인은 꾸준히 발전해 왔습니다. 기존 포토그래메트리(Photogrammetry)는 수백 장의 사진으로 정밀한 메시와 텍스처 맵을 만들지만, 동굴 바위 틈새나 식생이 복잡하게 얽힌 곳, 빛이 반사되는 음영 구역에서는 오차가 커질 수 있습니다. 메시가 복잡해질수록 디테일을 유지하면서 실시간 프레임을 확보하기 위한 LOD 및 UV 언랩 최적화에 많은 시간이 듭니다.

2020년 발표된 NeRF(Neural Radiance Fields)는 신경망으로 밀도와 시점별 색상을 표현하고 볼륨 렌더링으로 새로운 시점의 영상을 합성합니다. 원래 방식은 광선마다 신경망을 여러 번 평가하는 비용이 컸지만, 모든 NeRF 계열이 실시간 렌더링에 부적합한 것은 아닙니다. 예를 들어 2022년의 Instant-NGP는 해시 인코딩과 GPU 구현으로 실시간 렌더링 결과를 제시했습니다.

2023년 공개된 3D 가우시안 스플래팅(3D Gaussian Splatting, 3DGS)은 장면을 명시적인 3차원 가우시안 타원체(Gaussian Ellipsoids)로 표현하고 파라미터와 밀도를 최적화합니다. 원 연구는 타일 기반 래스터라이제이션(Tile-based Rasterization)으로 1080p에서 100 FPS 이상의 새로운 시점 합성 결과를 보고했습니다. 이는 연구의 실험 장면과 GPU 구현에서 얻은 결과이며, 임의의 던전 장면이나 게임 엔진에서 같은 속도를 보장하는 수치는 아닙니다.

3D 가우시안 타원체의 3차원 공간 분포는 다음과 같은 수식으로 정의됩니다.

G(x)=e−12(x−μ)TΣ−1(x−μ)G(x) = e^{-\frac{1}{2} (x-\mu)^T \Sigma^{-1} (x-\mu)}

여기서 중심 위치 벡터 μ\mu와 3D 공분산 행렬 Σ\Sigma를 사용하며, 공분산 행렬은 회전 행렬 RR과 스케일 행렬 SS로 다음과 같이 표현합니다.

Σ=RSSTRT\Sigma = R S S^T R^T

원 연구는 이 공분산을 화면 공간으로 투영해 타원형 스플랫을 만들고, 깊이에 따라 정렬한 뒤 알파 합성으로 영상을 구성합니다. 수식만으로 렌더링 속도가 정해지는 것은 아니며 가우시안 수, 화면 점유 면적, 정렬 구현도 비용에 영향을 줍니다.

포토그래메트리 메쉬 방식과 3D 가우시안 스플래팅 래스터라이제이션의 비주얼 품질 비교

던전 배경 데이터 수집과 3DGS 전처리 파이프라인

실제 어두운 동굴이나 유적지 형태의 던전 배경을 3DGS로 스캔하고 게임 리소스로 구축하기 위해서는 명확한 데이터 흐름을 거쳐야 합니다.

스캔 단계에서는 카메라로 동굴 내부의 벽면과 바닥을 여러 위치와 각도에서 촬영합니다. COLMAP 촬영 지침은 충분한 질감, 비슷한 조명 조건, 높은 이미지 중첩을 권장하며 각 대상이 적어도 세 장에 보이도록 안내합니다. 70% 중첩은 촬영 계획의 예시로 삼을 수 있지만 모든 장면에 적용되는 필수 임계값은 아닙니다. 사진을 Structure-from-Motion(SfM) 도구에 넣어 카메라 포즈와 희소 포인트 클라우드(Sparse Point Cloud)를 복원합니다. LiDAR를 보조로 사용한다면 선택한 도구가 지원하는 별도의 좌표 정합과 입력 경로를 확인해야 하며, 사진용 SfM 과정이 센서 데이터를 자동으로 결합한다고 가정하지 않습니다.

추출된 카메라 포즈와 포인트 클라우드로 3DGS를 학습하면 위치, 불투명도, 회전, 스케일과 시점별 색상을 표현하는 구면조화함수(SH) 계수를 가진 가우시안 클라우드가 생성됩니다. 영상 재현 품질이 높더라도 정확한 표면 기하가 복원되었다는 뜻은 아닙니다.

flowchart TD
    A[현장 사진 수집] --> B[COLMAP SfM 카메라 포즈 및 포인트 클라우드 추출]
    B --> C[3DGS 모델 학습 및 밀도 제어]
    C --> D[가우시안 데이터 압축 및 컬링]
    D --> E[게임 엔진 래스터라이저 통합]

게임 엔진 통합: 직접 래스터라이제이션과 하이브리드 파이프라인

생성된 가우시안 데이터를 게임 엔진에 적용하는 기술은 크게 두 가지로 나뉩니다.

첫 번째는 GPU 기반의 직접 래스터라이제이션(Direct Rasterization) 방식입니다. 유니티(Unity)나 언리얼 엔진 5(Unreal Engine 5)에 전용 렌더러를 통합해 가우시안을 투영하고 합성합니다. 원 연구의 래스터라이저는 가우시안이 겹치는 타일마다 항목을 만들고 타일과 깊이로 정렬합니다. 점 전체를 깊이순으로 정렬하는 예제만으로 이 타일 파이프라인이 완성되지는 않습니다. 촬영 시점 주변의 외관을 재현할 수 있지만, 촬영되지 않은 영역이나 실제 표면 기하의 정확도까지 보장하지 않습니다.

두 번째는 메시 추출과 혼합 표현을 사용하는 방식입니다. SuGaR는 표면에 정렬된 가우시안에서 메시를 추출하고, 선택적인 정제 및 텍스처 메시 내보내기를 제공합니다. 2DGS는 방향을 가진 2차원 가우시안 원판으로 표면 재구성을 개선하는 별도의 표현입니다. 이런 도구에서 얻은 메시도 충돌, 레벨 디자인, 라이팅에 사용하기 전에 표면 품질과 텍스처·조명 성분을 점검해야 합니다.

던전 배경 3DGS 렌더러와 프록시 메시를 함께 표시하는 엔진 통합 화면 예시

삽화의 수치와 화면 구성은 개념 설명용이며, 이 글에서 수행한 실측 벤치마크의 결과로 인용하지 않습니다.

실시간 환경을 위한 3DGS 최적화 전략

3DGS를 실시간 게임 프로젝트에 도입할 때 가장 먼저 직면하는 걸림돌은 VRAM 메모리 사용량과 물리 충돌 연산입니다. 방대한 원본 가우시안 파일은 메모리 점유율이 높아 효율적인 최적화 파이프라인이 필수가 됩니다.

mindmap
  root((3DGS 최적화 전략))
    메모리 관리
      가우시안 퀀타이제이션
      불투명도 기반 가지치기
    렌더링 성능
      뷰 프러스텀 컬링
      컴퓨트 셰이더 정렬
    물리 및 인터랙션
      프록시 콜라이더 메쉬
      뎁스 버퍼 연동
  1. 가우시안 압축 및 가지치기(Pruning): 화면 기여도가 낮은 가우시안을 제거하고 파라미터를 양자화하는 경로를 검토합니다. 불투명도만 낮다고 기여가 없다고 단정하지 말고 제거 전후 영상을 비교해야 합니다. 예를 들어 LightGaussian은 가지치기와 복구, SH 증류, 벡터 양자화를 조합해 논문의 평가 데이터셋에서 평균 15배 이상의 압축을 보고했습니다. 단순 불투명도 컷만으로 같은 압축률을 얻는다는 뜻은 아닙니다.
  2. 뷰 프러스텀 컬링(View Frustum Culling): 가우시안의 투영 범위를 고려해 화면에 기여하지 않는 항목을 조기에 제외하면 뒤따르는 타일 처리량을 줄일 수 있습니다. 중심점이 화면 밖이어도 큰 스플랫의 일부가 화면에 걸칠 수 있으므로 점의 위치만으로 판단하지 않습니다.
  3. 프록시 콜라이더(Proxy Colliders) 배치: 가우시안 클라우드는 일반적인 삼각형 메시 콜라이더의 입력과 다릅니다. 전용 충돌 알고리즘을 만들지 않는다면 지형과 벽면에 단순화한 프록시 충돌 메시를 두는 방법을 검토합니다. 뎁스 버퍼는 해당 시점에 보이는 표면의 정보이므로 가려진 벽이나 화면 밖 공간까지 포함하는 월드 충돌체를 대신할 수 없습니다.

가우시안 압축과 렌더링 최적화에서 비교할 메모리 및 성능 항목의 예시

셰이더 구현: GPU 가우시안 정렬 Pre-pass 핵심 로직

다음 HLSL 예제는 Unity의 카메라 공간 규약(전방이 음수 Z)에서 불투명도와 깊이 임계값을 검사하고 정렬 키를 생성하는 축약 예제입니다. 화면 좌우·상하와 원평면을 검사하는 전체 프러스텀 컬링이나 실제 정렬은 포함하지 않습니다. 0.1은 예시 깊이 임계값이며 실제 카메라의 근평면과 자동으로 연동되지 않습니다. 다른 엔진에서는 뷰 행렬의 전방 축 부호에 맞춰 깊이 부호를 조정해야 합니다.

struct GaussianNode {
    float3 position;
    float4 rotation;
    float3 scale;
    float opacity;
};

StructuredBuffer<GaussianNode> g_Gaussians : register(t0);
RWStructuredBuffer<uint2> g_SortedIndices : register(u0);

cbuffer CameraBuffer : register(b0) {
    float4x4 g_ViewMatrix;
    uint g_GaussianCount;
};

[numthreads(256, 1, 1)]
void CS_SortGaussians(uint3 id : SV_DispatchThreadID) {
    uint index = id.x;
    if (index >= g_GaussianCount)
        return;

    GaussianNode node = g_Gaussians[index];
    
    // 예시 불투명도 임계값 필터링
    if (node.opacity < 0.01) {
        g_SortedIndices[index] = uint2(0xFFFFFFFF, index);
        return;
    }
    
    // 뷰 공간 변환
    float4 viewPos = mul(g_ViewMatrix, float4(node.position, 1.0));
    
    // 카메라 뒤쪽과 예시 근거리 임계값 안의 중심점 제외
    if (viewPos.z > -0.1) {
        g_SortedIndices[index] = uint2(0xFFFFFFFF, index);
        return;
    }
    
    // Radix Sort용 뎁스 키 생성
    float linearDepth = -viewPos.z;
    uint depthKey = (uint)(linearDepth * 1000.0);
    g_SortedIndices[index] = uint2(depthKey, index);
}

키의 linearDepth * 1000은 깊이를 0.001 월드 단위 구간으로 나누는 예시입니다. 한 구간의 서로 다른 깊이는 같은 키가 되며, 월드 단위를 미터로 정하지 않았다면 밀리미터 정밀도라는 뜻도 아닙니다. 실제 구현에서는 허용 깊이 범위, 정수 변환의 오버플로, 무효 키 처리, 타일 식별자와 정렬 방향까지 정해야 합니다.

정리하며

3D 가우시안 스플래팅은 인디 게임 제작자와 스튜디오가 실사풍 던전 배경을 구현하는 데 새로운 가능성을 제공합니다. 환경을 처음부터 조형하는 데 드는 시간을 줄일 수 있지만, 실제 게임에 적용하려면 메모리 압축과 셰이더 최적화가 필요합니다.