UnitySplats
요약
UnitySplats는 3D Gaussian Splatting(3DGS) 콘텐츠를 Unity 환경에서 가져오고, 로드하며, 렌더링할 수 있도록 설계된 크로스 플랫폼 패키지입니다. Built-in Render Pipeline, URP, HDRP 등 다양한 파이프라인을 지원하며, GPU 및 휴대용 CPU에 최적화된 런타임 경로를 제공합니다.
핵심 포인트
- 3DGS 콘텐츠의 Unity 통합을 위한 전용 크로스 플랫폼 패키지입니다.
- URP, HDRP 등 주요 Unity 렌더링 파이프라인을 지원합니다.
- Direct3D, Vulkan, Metal, OpenGL, WebGL 2 등 다양한 그래픽 백엔드를 선택할 수 있습니다.
- PLY, SOG, GLB 등 여러 표준 및 PlayCanvas 형식을 지원합니다.
UnitySplats는 3D Gaussian Splatting (3DGS) 콘텐츠를 가져오고(importing), 로드하며(loading), 렌더링하기 위한 크로스 플랫폼 Unity 6 패키지입니다. Built-in Render Pipeline, URP, HDRP를 지원하며, GPU 및 휴대용 CPU 정렬 경로가 런타임에 선택됩니다.

프로젝트 계보 및 출처(Project lineage and attribution)
UnitySplats는 wuyize25/gsplat-unity의 수정되고 실질적으로 확장된 포크입니다. 원본 Unity 렌더러는 Copyright (c) 2025 Yize Wu 소유이며 MIT 라이선스 하에 배포됩니다.
이 패키지는 또한 PLY, SOG, GLB 구현체에서 사용되는 개념을 포함하여 PlayCanvas Engine의 Gaussian-splat 아키텍처 및 형식 동작 일부를 적용합니다. 이 Unity 작업 중 사용된 PlayCanvas 참조 버전은 v2.21.0-beta.14 (d5fe88878e338936fe763bbce1a58bc315e89cbe)입니다. PlayCanvas Engine은 Copyright (c) 2011-2026 PlayCanvas Ltd 소유이며 MIT 라이선스 하에 배포됩니다.
UnitySplats는 ARLOOPA가 유지 관리하는 Unity 구현체입니다. 이는 공식적인 PlayCanvas 제품이 아니며 PlayCanvas JavaScript 엔진을 포함하지 않습니다. 기존의 상위(upstream) 저작권 및 라이선스 고지 사항은 소스 코드와 Third Party Notices에 유지됩니다.
기능
- Standard binary 3DGS PLY 및 PlayCanvas 압축 PLY의 임포트 및 런타임 로딩 지원.
- 번들링 및 언패킹된 PlayCanvas SOG v1/v2 지원.
- Zstandard 압축 SPZ v4 속성을 포함한 SPZ v1~v4 지원.
KHR_gaussian_splatting을 사용한 Gaussian-splat GLB 지원.- 파일 경로, 바이트 배열 및 스트림으로부터의 런타임 로딩.
- Spark 패킹 및 압축되지 않은 Unity 에셋 표현.
- 업로드 중 선택적 렌더링이 가능한 비동기 GPU 업로드.
- 직교 카메라(Orthographic cameras), MSAA, 커팅아웃(cutouts), 활성 소스 범위(active source ranges), 그리고 XR 통합 지원.
- Direct3D, Vulkan, Metal, OpenGL, WebGL 2에 대한 런타임 그래픽 백엔드 선택 기능.
지원 형식 (Supported formats)
| 형식 (Format) | 임포트 (Import) | 런타임 로드 (Runtime load) | 참고 사항 (Notes) |
|---|---|---|---|
.ply | 예 (Yes) | 예 (Yes) | 이진 리틀 엔디안 표준 3DGS 및 PlayCanvas 압축 PLY |
| ... |
The 임포터의 Auto 좌표 모드는 GLB의 glTF LUF 프레임을 사용하고, PLY, SOG, SPZ에는 일반적인 3DGS/OpenGL RUB 프레임을 사용하여 데이터를 Unity RUF로 변환합니다.
플랫폼 및 그래픽 API 지원 (Platform and graphics API support)
UnitySplats는 런타임에 가장 빠르고 호환되는 정렬 및 렌더링 경로를 선택합니다.
| 플랫폼 (Platform) | 그래픽 API (Graphics APIs) | 정렬/렌더링 경로 (Sort/render path) |
|---|---|---|
| Windows | Direct3D 12, Vulkan | 웨이브(wave)/서브그룹 요구 사항이 사용 가능한 경우 GPU radix sort; 그렇지 않은 경우 CPU 폴백 (fallback) |
| ... |
OpenGL ES 경로는 버텍스 스테이지 저장소 버퍼(vertex-stage storage buffers) 대신 RGBA8 바이트 패킹 및 부동 소수점 샘플링 텍스처를 사용합니다. 이는 일부 모바일 GPU가 SSBO 지원을 보고하지만 Unity가 생성한 BufferBlock 바인딩을 거부할 때 발생하는 드라이버 실패를 방지합니다. OpenGL ES 3.1은 최소 지원 Android OpenGL 버전입니다.
유지보수자 테스트는 OpenGL ES, Vulkan, Metal을 사용하는 여러 Android 및 Apple 기기에서 진행되었으며, Samsung 및 HONOR Android 하드웨어와 Meta Quest 3 및 Meta Quest 3S 헤드셋을 포함합니다. 삼성 및 HONOR 기기는 GLES 호환성 경로를 검증하는 데에도 사용되었습니다. 장치 드라이버는 여전히 다양하므로, 나열된 API는 모든 GPU/OS 조합에 대한 보장이라기보다는 지원되는 목표(target)입니다. 하드웨어 보고서는 GitHub Issues를 통해 환영합니다.
WebGL 2 경로는 컴퓨트 또는 구조화 그래픽 버퍼를 생성하지 않습니다. 이 경로는 스플랫 데이터를 샘플링된 텍스처에 저장하고 그리기 순서(draw order)를 기록하며, 카운팅 정렬(counting sort)을 Unity의 메인 스레드에서 실행합니다. Web 빌드의 경우 Spark 압축과 적당한 스플랫 개수를 사용하세요: 브라우저 메모리 제한과 동기식 정렬은 대용량 비압축 에셋을 네이티브 플랫폼보다 훨씬 더 비용이 많이 들게 만듭니다. 글로벌 병합(Global merge) 및 컴퓨트 커팅아웃(compute cutouts)은 WebGL에서 사용할 수 없습니다.
정렬 제한 사항 (Sorting limitations)
GPU radix 경로는 웨이브/서브그룹 작업(wave/subgroup operations)과 호환되는 컴퓨트 워크그룹 제한을 요구합니다. CPU 폴백(fallback)은 인스턴스화된 GPU 그리기(instanced GPU drawing)를 유지하지만, 글로벌 멀티-렌더러 병합 및 컴퓨트 커팅아웃 기능은 비활성화합니다. 이 경로는 렌더러당 하나의 정렬 순서를 유지하며 게임 카메라를 우선시하므로, 상당히 다른 동시 카메라 시점들은 그 순서를 공유하게 됩니다.
크로스-렌더러 정렬(Cross-renderer sorting)은 기본적으로 활성화되어 있습니다. 이는 중첩되는 렌더러들로부터 스플랫을 글로벌 깊이 순서(depth-orders)로 지정하고, 모든 활성 렌더러가 완전히 업로드되고 Spark 패킹되며, 동일한 GameObject 레이어를 사용하고, 기본 렌더 순서를 유지하며, 패킹된 렌더러/인덱스 제한에 맞을 때 하나의 병합된 장면으로 그립니다. 이는 Project Settings > Gsplat에서 구성할 수 있습니다. 다른 설정들은 별도의 드로우 콜(draw calls)로 폴백합니다.
요구 사항 (Requirements)
- Unity 6000.0 이상. 포함된 개발 프로젝트는 Unity 6000.3.9f1을 사용합니다.
com.unity.mathematics1.3.2 이상.- SOG 이미지 디코딩을 위한
com.netpyoung.webp0.3.22. - 위 표에 있는 지원되는 그래픽 API 중 하나.
설치 (Installation)
Git URL을 통해 자동 Unity.WebP 해결 기능으로 설치하기
UnitySplats는 이미 패키지 종속성으로 Unity.WebP 0.3.22를 선언하고 있습니다. Unity가 이를 자동으로 해결하도록 하려면, 대상 프로젝트의 Packages/manifest.json에 com.netpyoung 스코프용 OpenUPM 레지스트리를 추가하고 UnitySplats Git URL을 추가해야 합니다:
{
"scopedRegistries": [
{
...
이 항목들을 기존 레지스트리 및 종속성과 병합하세요. 그러면 Unity가 UnitySplats를 해결할 때 Unity.WebP를 자동으로 설치합니다.
두 패키지를 Git URL에서 모두 설치하기
Unity Package Manager는 한 Git 패키지를 다른 Git 패키지의 전이적(transitive) 종속성으로 해결할 수 없습니다. 먼저 Unity.WebP를 설치하세요:
-
Window > Package Manager를 엽니다. -
+를 클릭하고Install package from git URL...을 선택합니다. -
Unity.WebP를 설치합니다:
https://github.com/netpyoung/unity.webp.git?path=unity_project/Assets/unity.webp#0.3.22 -
UnitySplats에 대해서도 이 과정을 반복합니다:
https://github.com/arloopa/UnitySplats.git
이것은 저장소의 현재 기본 브랜치를 설치합니다.
manifest.json에서 두 Git 종속성 모두 설치하기
두 직접적인 종속성을 대상 프로젝트의 Packages/manifest.json에 추가하세요:
{
"dependencies": {
"com.netpyoung.webp": "https://github.com/netpyoung/unity.webp.git?path=unity_project/Assets/unity.webp#0.3.22",
...
프로젝트의 다른 종속성들은 같은 객체 안에 유지하세요.
릴리스 아카이브에서 설치하기
UnitySplats 릴리스 ZIP을 다운로드하여 대상 프로젝트의 Assets 폴더 외부에 압축을 해제합니다. 위에서 OpenUPM 레지스트리를 구성하고, Unity.WebP를 Git URL로 설치하거나 별도로 다운로드한 Unity.WebP 패키지를 추가합니다. 그런 다음 Window > Package Manager를 열고, + > Install package from disk...를 선택한 후 UnitySplats의 package.json을 선택합니다.
UnitySplats 소스 아카이브에는 Unity.WebP가 번들링되지 않습니다. Unity는 소비하는 프로젝트의 Packages/manifest.json에서 Git 의존성 URL만 허용하므로, 패키지 간 자동 해결을 위해서는 OpenUPM과 같은 스코프된 레지스트리가 필요합니다.
렌더 파이프라인 설정
- Built-in Render Pipeline: 추가적인 렌더 기능은 필요하지 않습니다.
- URP: 활성화된 Universal Renderer Data 에셋을 열고
Gsplat URP Feature를 추가합니다. Unity 6 RenderGraph와 호환성 모드가 모두 지원됩니다. - HDRP: Custom Pass Volume과
Gsplat HDRP Pass를Before Transparent주입 지점에 추가합니다.
최대 성능을 위해 Android에서는 Vulkan, Windows에서는 Vulkan 또는 Direct3D 12를 사용하는 것이 좋습니다. Direct3D 11 및 OpenGL은 포터블 CPU 소터를 자동으로 선택합니다. 만약 Android가 OpenGL을 사용한다면, Player Settings에서 OpenGL ES 3.1을 요구해야 합니다.
스플랫 가져오기 및 렌더링
.ply,.sog,.spz또는 Gaussian-splat.glb파일을 프로젝트의Assets폴더로 복사하거나 드래그합니다.
GLB의 경우, 해당 파일을 선택하고Assets > UnitySplats > Choose GLB Importer... > UnitySplats (Gaussian Splat)을 선택합니다. 파일 인스펙터에서 Unity의 Importer 드롭다운 메뉴에서GsplatImporter를 선택할 수도 있습니다. UnitySplats는 선택적 GLB 임포터이므로, 일반적인 GLB 모델을 처리하는 glTFast 및 기타 패키지와 공존할 수 있습니다.
만약 다른 두 개의 설치된 패키지가 모두 자신들을 기본 GLB 임포터로 등록한다면, 하나가 비활성화되거나 오버라이드 임포터로 변경될 때까지 Unity는 해당 패키지들 간의 충돌을 계속 보고합니다. 하지만 이는 Gaussian GLB에 대해 UnitySplats를 명시적으로 선택하는 것을 방해하지 않습니다.- 가져온
GsplatAsset을 선택합니다. 메모리와 업로드 속도보다 정확한 프로젝트 내 값이 더 중요한 경우Uncompressed를 선택하고, 권장되는 패키지화된 표현은Spark입니다. - Project 창에서 가져온 에셋을 Hierarchy 또는 Scene 뷰로 드래그합니다. UnitySplats는 자동으로
GsplatRenderer가 포함된 GameObject를 생성하고, 해당 에셋을 할당하며, 로컬 Z 회전을 180도로 설정합니다.
GameObject를 수동으로 생성하고, Gsplat Renderer 컴포넌트를 추가한 다음, 가져온 에셋을 해당 Gsplat Asset 필드에 할당할 수도 있습니다.
Scene 뷰에서 splat의 변환된 에셋 경계 내부 아무 곳이나 클릭하여 GameObject를 선택하면 되며, 콜라이더는 필요하지 않습니다. Unity의 일반적인 Shift/Ctrl 선택 수정자는 계속 작동합니다. 여러 개의 GsplatRenderer GameObject를 선택하면 공유되는 인스펙터 속성에 대한 다중 객체 편집이 가능하며, 연결된 모든 BoxCollider 컴포넌트를 한 번에 처리할 수 있습니다.
두 개 이상의 Spark 렌더러가 겹칠 경우, Project Settings > Gsplat에서 Enable Cross-Renderer Sorting을 활성화 상태로 두십시오. 지원되는 Vulkan, Direct3D 12 및 Metal 장치에서는 이를 하나의 공유된 per-splat 깊이 순서로 생성하여 카메라가 움직일 때 전체 캡처가 서로 앞에서 전환되는 것을 방지합니다. OpenGL, WebGL, Direct3D 11 및 지원되지 않는 GPU 구성을 사용하는 포터블 CPU 소터는 별도의 드로우 콜을 유지하므로 진정한 병합된 순서를 제공할 수 없습니다.
대부분의 3DGS 콘텐츠는 감마 공간(gamma space)에서 학습됩니다. Gamma To Linear는 GsplatRenderer에서 기본적으로 활성화되어 있습니다. 소스 색상이 이미 프로젝트의 선형 워크플로우를 위해 작성된 경우 비활성화하십시오. 그렇지 않으면 알파 블렌딩 전에 변환하는 것이 시각적 정확도를 떨어뜨릴 수 있습니다.
Unpacked SOG
SOG의 meta.json을 선택한 다음, Assets > UnitySplats > Import unpacked SOG (Spark)를 선택하십시오. 참조된 모든 파일은 메타데이터 옆에 두십시오.
런타임 로딩
런타임 로더는 메모리 내의 GsplatAsset을 반환하며, 메인 스레드에서 Unity 객체를 생성/할당해야 합니다.
using Gsplat;
GsplatAsset asset = GsplatRuntimeLoader.LoadFile(
...
LoadFile은 파일 시스템 경로를 허용합니다. Android APK의 StreamingAssets, HTTP(S) 및 기타 URI 기반 소스는 UnityWebRequest로 읽은 다음, GsplatRuntimeLoader.Load(byte[], ...)에 전달해야 합니다. 다른 입력 형태에는 Load(Stream, ...) 또는 LoadUnpackedSog(...)를 사용하십시오.
패키지 관리자에는 바이트 배열 로딩 및 런타임 에셋 정리(cleanup)를 시연하는 선택적 런타임 PLY 로딩 샘플이 포함되어 있습니다.
활성 소스 범위 (Active source ranges)
GsplatRenderer.SetActiveRanges는 다른 에셋을 생성하지 않고 소스-스플랫 범위(source-splat ranges)의 정확한 합집합(union)을 선택합니다. 범위는 반개방([Offset, Offset + Count)) 의미를 사용하며, 겹치거나 접촉하는 경우 정규화됩니다.
renderer.SetActiveRanges(new[]
{
new GsplatActiveRange(offset: 1000, count: 500),
...
}
이러한 메서드들은 Unity GPU 버퍼를 업데이트하며 메인 스레드에서 실행되어야 합니다. 명시적 범위가 활성화되면 Compute cutouts는 우회됩니다.
형식 참고 사항 (Format notes)
- PLY 입력은 바이너리 리틀 엔디안(binary little-endian)이어야 합니다.
- SOG v1/v2는 Unity.WebP와 해당 플랫폼 libwebp 바이너리를 사용합니다.
SPZ_ADOBE_coordinate_system을 포함하는 SPZ 파일은 이 디스크립터를 자동으로 사용합니다.- GLB 프리미티브는
KHR_gaussian_splatting과 필요한 접근자(accessors)를 선언해야 합니다. UnitySplats는 또한splat-transform2.6.0 및 이전 버전에서 작성된 레거시 로그 스케일 인코딩도 인식합니다. 여러 노드 변환으로 스플랫 메쉬를 인스턴싱하는 장면 그래프(Scene graphs)는 하나의 에셋으로 평탄화되지 않습니다.
XR 지원 (XR support)
| XR 렌더 모드 | 내장 (Built-in) | URP | HDRP |
|---|---|---|---|
| 다중 패스 (Multi-pass) | 예 (Yes) | 예 (Yes) | 아니오 (No) |
| 단일 패스 인스턴싱 (Single Pass Instanced) | 아니오 (No) | 예 (Yes) | 아니오 (No) |
문서화 (Documentation)
라이선스 (License)
AI 자동 생성 콘텐츠
본 콘텐츠는 개발 자료 GitHub · 53f6f5ad의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기