3D 가우시안 스플래팅(3DGS)을 인디 게임 배경 파이프라인에 적용하기 위한 기술 스택
3D 가우시안 스플래팅으로 실사 배경 에셋을 게임 엔진에 이식할 때 검토할 도구와 편집·압축·렌더링·충돌 분리 워크플로우를 정리합니다.

3D 가우시안 스플래팅(3DGS)의 배경 제작 활용 검토
라디언스 필드(Radiance Fields) 표현인 3D 가우시안 스플래팅(3D Gaussian Splatting, 이하 3DGS)은 학습한 가우시안의 파라미터와 타일 기반 래스터라이제이션(Tile-based Rasterization)으로 새로운 시점의 영상을 합성합니다. 원 연구는 실시간 렌더링 결과를 제시했지만, 모든 기기에서 같은 성능을 보장하거나 정확한 표면 메시 복원을 자동으로 해결하는 기술은 아닙니다. 반사체나 움직이는 물체가 포함된 촬영 데이터는 별도로 품질을 점검해야 합니다.
이 글은 특정 스튜디오의 도입 사례나 제작 기간 단축을 입증하는 사례 연구가 아니라, 인디 팀이 실험할 수 있는 도구와 파이프라인의 설계안입니다. 사진 촬영, 학습, 데이터 정리, 엔진 통합에 드는 시간을 함께 측정해야 기존 제작 방식과 비교할 수 있습니다.

3DGS 기반 실전 배경 제작 파이프라인 & 핵심 기술 스택
게임 엔진에 3DGS 배경을 넣는 실험에서는 학습 외에도 데이터의 경량화, 물리 충돌 처리, 렌더러 통합을 설계해야 합니다. 아래는 이를 네 단계로 나눈 예시이며 특정 팀이 실제로 채택한 스택이라는 뜻은 아닙니다.
1단계: 에셋 캡처 및 데이터 전처리 (COLMAP & Nerfstudio / Postshot)
배경으로 구현하려는 대상을 여러 위치와 각도에서 촬영합니다. 100~500장은 촬영 계획의 예시이며 필요한 수는 장면 규모, 질감, 겹침에 따라 정합니다. COLMAP 같은 SfM(Structure-from-Motion) 도구로 카메라 포즈와 희소 포인트 클라우드를 추정합니다. 학습 도구로는 오픈소스 Nerfstudio의 Splatfacto나 Jawset의 Postshot 등을 검토할 수 있습니다. Splatfacto는 학습한 스플랫의 PLY 내보내기를 지원하지만 Nerfacto의 학습 결과를 같은 명령으로 내보낼 수는 없습니다. 학습 시간과 지원 형식은 도구 버전, 장면, GPU에서 직접 확인합니다.
2단계: 가우시안 데이터 편집 및 경량화 (SuperSplat & SOG)
학습한 .ply에는 가우시안의 위치, 색상, 불투명도, 회전, 크기, 구면 조화 함수 계수 등이 들어갈 수 있습니다. 파일 크기는 가우시안 수, 속성 개수와 저장 형식에 따라 달라지며 모든 학습 결과가 수백만 개의 가우시안을 갖는 것은 아닙니다. 예를 들어 가우시안당 62개의 32비트 실수를 저장하는 바이너리 표현이면 100만 개의 속성 데이터는 헤더를 제외하고 약 248MB(236.5MiB)입니다.
PlayCanvas의 오픈소스 에디터인 SuperSplat은 스플랫 선택·삭제와 영역 크롭을 지원합니다. SOG 형식은 양자화와 코드북 등으로 데이터를 압축하며 공식 문서는 동등한 PLY보다 파일이 통상 15~20배 작다고 설명합니다. 이 파일 크기 비교가 모든 엔진의 VRAM 절감률을 뜻하지는 않습니다. 런타임이 압축 표현을 유지하는지, 다시 풀어 저장하는지와 정렬·작업 버퍼까지 포함해 GPU 메모리를 측정합니다.

3단계: 실시간 게임 엔진 연동 (Unity & Unreal Engine)
경량화된 가우시안 데이터는 엔진 전용 플러그인을 통해 실시간 렌더링 파이프라인으로 탑재됩니다.
- Unity 스택: Aras Pranckevičius의 오픈소스 UnityGaussianSplatting을 실험용 렌더러 후보로 검토할 수 있습니다. 저장소는 스스로 실험용 시각화 프로젝트라고 설명하므로 배포용 기능과 호환성을 별도로 평가합니다.
- Unreal Engine 5 스택: 지원하는 UE 버전과 라이선스가 명시된 전용 3DGS 렌더러를 선택합니다. 스플랫이 Nanite 메시나 Lumen용 표면과 같은 방식으로 자동 처리된다고 가정하지 말고 깊이 합성, 그림자, 동적 조명 지원을 플러그인별로 확인합니다.
4단계: 시각적 표현과 물리 충돌(Physics Proxy)의 분리 설계
원본 3DGS 데이터는 일반적인 삼각형 메시의 토폴로지를 제공하지 않으므로 메시 콜리전(Mesh Collision)은 별도 작업입니다. 이 설계안에서는 하이브리드 구조를 사용합니다.
시각적 요소는 3DGS로 렌더링하고 플레이어의 이동과 레이캐스트(Raycast)를 처리하는 단순 충돌 메시(Low-poly Collision Proxy Mesh)를 따로 만듭니다. Poisson 표면 복원은 표면 샘플과 법선 같은 입력이 필요하므로 원본 가우시안의 중심점만 바로 넣으면 적합한 충돌 메시가 나온다고 가정하지 않습니다.
flowchart LR
A[현장 캡처: DSLR / Drone] --> B[COLMAP / SfM 포즈 추정]
B --> C[3DGS 학습: Nerfstudio / Postshot]
C --> D[편집 및 압축: SuperSplat & SOG]
D --> E1[비주얼 렌더링: Compute Shader]
A --> E2[별도 기하 제작: Low-Poly Proxy Mesh]
E1 --> F[실시간 인디 게임 배경 통합]
E2 --> F
엔진 내 스플랫 제어 및 최적화 C# 스크립트 예제
다음은 오브젝트와 카메라 사이 거리를 사용자 정의 셰이더에 전달하는 Unity C# 예제입니다. _SplatScaleMultiplier와 _MaxDistanceCutoff는 이 글에서 정한 이름이며 위 렌더러의 공통 API가 아닙니다. 해당 값을 읽는 별도의 셰이더가 있어야 효과가 있고, 크기를 줄이는 것만으로 GPU 데이터의 크기나 정렬할 항목 수가 줄어들지는 않습니다. 실제 LOD와 메모리 절감에는 데이터 교체·컬링·언로드를 추가해야 합니다.
이 예시는 시작할 때 MainCamera 태그의 카메라가 존재하고, 제어기마다 독립된 머티리얼을 할당한다고 가정합니다. 같은 머티리얼을 공유하면 마지막으로 기록한 값이 다른 오브젝트에도 적용될 수 있습니다. minSplatScale은 0~1 범위로 설정합니다.
using UnityEngine;
namespace GaussianPipeline
{
/// <summary>
/// 카메라 거리에 따른 사용자 정의 셰이더 파라미터 전달 예제
/// </summary>
[ExecuteInEditMode]
public class GaussianSplatLODController : MonoBehaviour
{
[Header("Render Settings")]
[SerializeField] private Material splatMaterial;
[SerializeField] private float maxRenderDistance = 40.0f;
[SerializeField] private float minSplatScale = 0.2f;
private Transform mainCameraTransform;
private static readonly int SplatScaleMultiplierID = Shader.PropertyToID("_SplatScaleMultiplier");
private static readonly int MaxDistanceCutoffID = Shader.PropertyToID("_MaxDistanceCutoff");
private void Start()
{
if (Camera.main != null)
{
mainCameraTransform = Camera.main.transform;
}
}
private void Update()
{
if (mainCameraTransform == null || splatMaterial == null || maxRenderDistance <= 0f) return;
float distance = Vector3.Distance(transform.position, mainCameraTransform.position);
// 사용자 정의 셰이더가 해석할 스케일 값을 전달한다. 데이터 개수나 VRAM 할당량은 바꾸지 않는다.
float scaleFactor = Mathf.Lerp(1.0f, minSplatScale, distance / maxRenderDistance);
scaleFactor = Mathf.Clamp(scaleFactor, minSplatScale, 1.0f);
splatMaterial.SetFloat(SplatScaleMultiplierID, scaleFactor);
splatMaterial.SetFloat(MaxDistanceCutoffID, maxRenderDistance);
}
}
}
3DGS 배경 파이프라인의 현재 한계 및 극복 과제
3DGS를 상용 게임에 적용하려면 렌더링 외에도 해결해야 할 과제가 있습니다.
- VRAM 점유율 및 정렬 연산 부담: 원 연구처럼 깊이순 합성을 사용하는 렌더러에서는 시점 변화에 맞춘 정렬 비용을 고려합니다. 화면이 정지한 경우의 재사용이나 근사 OIT 등 다른 설계도 가능하므로 매 프레임 전체 정렬이 유일한 방법은 아닙니다. Chunked Spatial Partitioning(공간 분할)으로 가시 구간을 제한하는 경로를 실험하고 실제 비용을 비교합니다.
- 동적 조명(Dynamic Lighting) 상호작용: 원본 3DGS의 SH 색상은 촬영 당시의 외관을 표현하며 PBR의 albedo·normal·roughness를 각각 제공하지 않습니다. 재조명을 위해서는 이런 재질 정보를 추정하는 별도 방법이나 메시·재질 파이프라인이 필요합니다. 기본 데이터에 동적 라이트를 더하는 것만으로 촬영 조명이 제거되지는 않습니다.
인디 팀은 작은 배경 구간에서 이 도구 조합을 실험하고 제작 시간, 빌드 크기, 프레임 비용, 수정 편의성을 기록해 도입 여부를 판단할 수 있습니다.



