평면 지도는 도시를 위에서 내려다본 기록입니다. 그런데 도시는 높이로도 지어집니다. 월드의 모든 건물과 지형을 실제 3D 그대로 브라우저에서 탐색하게 만드는 것, 그것이 이 파이프라인이 푸는 문제입니다. 이 보고서는 그 산출물을 구조부터 배포까지 직접 검증한 기록입니다.
무엇을 만들었는가
LiDAR 5는 저장된 월드 파일을 오프라인에서 읽어 스트리밍 3D 타일로 변환하는 도구입니다. 서버에 접속하지 않고 리전 파일을 직접 해석합니다. 산출물은 표준 3D Tiles 1.1 형식이라, 이 형식을 아는 렌더러라면 진입점 URL 하나로 월드 전체를 열 수 있습니다. 현재 지도 서비스의 3D 화면이 실제로 이 타일을 읽습니다.
월드 파일(.mca) → LiDAR 5 변환 → 타일 계층(tileset.json) → 정적 서빙 → 지도 3D 화면
원거리에서는 가볍게 요약된 조각을, 가까이 갈수록 더 선명한 조각을 받아 같은 장면이 점점 또렷해지는 방식입니다. 화면에 보이는 영역의 타일만 내려받으므로, 월드가 아무리 커도 브라우저가 감당하는 양은 시점 주변으로 한정됩니다.
타일 계층
전체 구조는 넓은 것에서 좁은 것으로 내려가는 트리입니다. 루트 아래에 8192블록 셀이, 그 아래에 2048블록 셀이, 다시 그 아래에 512블록 리전이 붙습니다. 리전부터는 파일이 분리되어, 리전마다 자기만의 작은 tileset을 갖습니다. 큰 월드에서도 필요한 리전의 색인만 점진적으로 불러오게 하는 분할입니다.
루트(오차 256) → 8192블록 셀(128) → 2048블록 셀(32) → 리전 참조(16) → 리전 내부 쿼드트리(8 → 4 → 2 → 0)
괄호의 숫자는 각 단계의 기하 오차입니다. 뷰어는 이 값을 화면에서 몇 픽셀의 오차로 보이는지로 환산해, 허용치를 넘는 타일만 다음 단계로 정제합니다. 정제 방식은 전 타일이 교체(REPLACE)라서, 자식 타일이 로드되면 부모의 거친 표현은 화면에서 사라집니다. 리전 내부는 4단 쿼드트리로, 타일 하나가 넷으로 갈라지며 512블록에서 64블록까지 내려갑니다.
모든 타일의 경계 상자는 실제 메시의 높이 범위로 조여져 있습니다. 예를 들어 한 리전의 상자는 바닥 기준이 아니라 그 구역에 실제로 지어진 높이까지만 감쌉니다. 상자가 헐거우면 화면 밖 판정과 오차 환산이 함께 부정확해지기 때문입니다.
세 가지 표현
모든 단계가 같은 방식으로 만들어지지는 않습니다. 거리에 따라 성격이 다른 세 가지 표현을 씁니다. 셋 모두 같은 원본(풀해상 볼륨)에서 파생되어, 줌 단계가 바뀔 때 색과 질감이 튀지 않습니다.
| 표현 | 타일 크기 | 타일 수 | 만드는 방법 | 의도된 손실 |
|---|---|---|---|---|
| compact 높이장 | 8192 / 2048블록 | 258 | 32블록 셀마다 대표 높이(P75)와 대표색 하나로 요약한 단일 메시 | 건물 측면, 투명한 수면, 세부 재질 |
| 드레이프 셸 | 512 / 256 / 128블록 | 42,418 | 지형과 건물을 하나의 매끈한 껍질로 단순화하고, 상공과 4방향 측면에서 미리 구운 사진 질감을 입힘 | 가려진 안뜰 벽은 앞 건물의 파사드를 차용 |
| 텍스처 복셀 | 64블록 (리프) | 129,262 | 실제 블록 지오메트리를 병합 메시로 만들고 블록 원본 텍스처를 입힘 | 없음 — 근접 표현의 기준 |
멀리서는 지붕과 지형의 실루엣만 있으면 되고, 중간 거리에서는 사진처럼 읽히면 되고, 가까이서는 블록 하나하나가 선명해야 합니다. 표현을 거리마다 바꾸는 대신 하나로 통일했다면, 원거리 화면이 수백만 개의 블록 메시를 감당하거나 근접 화면이 뭉개진 사진을 보여 주거나 둘 중 하나였을 것입니다.
압축과 공유
상세 타일(드레이프와 리프)은 정점 좌표를 정수로 양자화하고 메시 전용 코덱으로 한 번 더 압축합니다. 질감은 두 표현이 반대 전략을 씁니다. 드레이프는 구운 사진을 타일 안에 내장해 파일 하나로 자기완결이고, 리프는 반대로 블록 텍스처를 밖으로 빼서 공유합니다. 리프 12.9만 개가 저마다 돌과 흙 텍스처를 품으면 같은 그림이 수만 번 중복되기 때문입니다. 실측으로 리프 타일 하나는 공유 텍스처 801장 중 필요한 것만 상대 경로로 참조합니다.
| 항목 | 값 | 확인 방법 |
|---|---|---|
| 리전 | 2,020 | metadata == 디렉터리 수 |
| 상세 타일 | 171,680 | metadata == GLB 파일 수 (리프 129,262 + 드레이프 42,418) |
| 상세 삼각형 | 약 19.3억 | metadata (1,931,615,214) |
| compact 높이장 | 258개 / 32.6 MiB | metadata == 파일 수·바이트 합 |
| 공유 텍스처 | 801 PNG / 약 1.8 MiB | 디스크 실측(파일 크기 합, 매핑표 materials.tsv 별도) |
| 전체 용량 | 약 19 GiB | 디스크 실측 |
| 좌표 범위 | 51,200 × 58,880블록 | metadata bounds |
이 압축은 공짜가 아닙니다. 타일을 읽는 쪽이 메시 코덱 디코더와 압축 텍스처 디코더를 연결해야 지오메트리와 질감이 열립니다. 지도 서비스의 3D 화면은 두 디코더를 연결한 상태로 이 tileset을 순회합니다. 이 보고서의 검증은 타일의 컨테이너와 압축 선언(GLB 헤더, 확장 목록, 텍스처 참조)을 직접 파싱해 확인한 것이며, 디코더로 지오메트리를 복원해 본 것은 아닙니다.
증분 배포와 무결성
월드는 계속 지어집니다. 그때마다 19 GiB를 다시 만들 수는 없으므로, 갱신은 바뀐 리전만 다시 계산합니다. 월드 변경 기록에서 최근에 바뀐 리전을 산출하고, 그 리전과 주변 이웃만 다시 변환한 뒤, 원거리 요약과 루트 색인을 마지막에 함께 갱신합니다. 원본이 같은 리전은 해시로 판별해 기존 타일을 그대로 재사용합니다.
| 세대 | 리전 | 상세 타일 | 확인 방법 |
|---|---|---|---|
| 7월 13일 스냅샷 | 1,185 | 100,725 | 배포 전 보존 스냅샷의 metadata |
| 7월 16일 이전 스냅샷 | 1,861 | 158,185 | 배포 전 보존 스냅샷의 metadata |
| 7월 16일 라이브 (11:19 UTC) | 2,020 | 171,680 | 운영본 metadata == 디스크 |
보존 스냅샷은 다음 안정 배포까지만 유지되므로, 지난 세대의 행은 관측 당시의 기록입니다. 실제로 이 보고서를 검증하는 동안에도 한 세대가 지나갔습니다. 오전에 관측한 라이브는 리전 1,978개였는데 두 시간 뒤 2,020개가 되어 있었습니다. 수치를 문서에 옮겨 적는 순간 낡기 시작한다는 뜻이라서, 이 보고서의 모든 수치에는 관측 시각을 붙였고 현재 값은 언제나 배포본의 metadata가 기준입니다.
배포는 라이브를 직접 덮어쓰지 않습니다. 준비 공간에서 전체 검증을 마친 뒤, 기존 라이브를 하드링크 스냅샷으로 보존하고, 콘텐츠를 먼저 병합한 다음 루트 색인을 마지막에 원자적으로 교체합니다. 문제가 생기면 스냅샷 이름을 되돌리는 것으로 롤백이 끝납니다. 이번 검증에서는 배포 문서의 무결성 불변식을 운영본에 그대로 적용해 전부 통과를 확인했습니다.
- metadata의 리전 수 == 리전 목록 길이 == 실제 디렉터리 수 (2,020)
- metadata의 타일 수 == 실제 GLB 파일 수 (171,680)
- compact 타일 수·바이트 == 실제 파일 수·크기 합 (258개, 34,138,612바이트)
- 공개 URL의 루트 색인과 metadata가 디스크 원본과 sha256 일치
- 표본 타일의 GLB 헤더(magic, 버전, 선언 길이) 정상, 존재하지 않는 리전은 404
- 캐시는 3단계 — 루트 색인(tileset.json, metadata.json)은 항상 재검증, 버전 쿼리가 없는 리전 색인과 콘텐츠는 7일(미존재 응답 포함), 배포 버전 쿼리가 붙은 요청은 1년 불변. 지도 화면은 모든 타일 URL에 배포 버전을 붙여 계층 전체를 원자적으로 갱신
검증과 한계
알고 사용해야 하는 한계는 다음과 같습니다.
- 좌표는 월드의 로컬 블록 좌표입니다. 위도와 경도가 없으므로 실측 지도 위에 바로 얹을 수 없고, 지구 좌표 배치가 필요하면 원점 좌표를 지정한 재변환이 필요합니다.
- 드레이프의 측면 질감은 근사입니다. 가려진 안뜰 벽은 앞 건물의 파사드를 차용하며, 가까이 가면 실제 복셀이 이를 대체합니다.
- compact 높이장은 실루엣 전용 요약이라 수면 투명도와 건물 측면을 보존하지 않습니다.
- 타일 수와 삼각형 수는 상세 타일만 집계합니다. compact 요약은 별도 항목으로 세며, 두 계열을 합산하면 안 됩니다.
- 입력은 월드 지형과 건축물뿐입니다. 사용자 활동, 이동, 식별자는 이 파이프라인에 들어오지 않습니다.
검증 과정에서 사양 문서의 수치 여럿이 이전 세대의 값으로 남아 있는 것을 확인해 정리 대상으로 기록했습니다. 하루에도 세대가 바뀌는 산출물에서는 문서에 수치를 복제하지 않고 배포본의 metadata를 단일 출처로 가리키는 것이 유일하게 안전한 서술 방식입니다. 이 보고서도 같은 원칙을 따랐습니다.