발행물

Research Note 009 · 시스템

8,576만 블록을 브라우저 아카이브로 만드는 법

도시를 브라우저에 옮기는 일은 원본 월드를 그대로 싣는 일이 아닙니다. 내아거리의 85,765,828개 비공기 블록을 재현 가능한 정적 자산으로 바꾸고, 필요한 청크부터 점진적으로 여는 Depth 파이프라인을 검증했습니다.

2026.09.02 플레이시티 리서치 12분 읽기

Depth는 실행 중인 Minecraft 서버를 중계하는 화면이 아닙니다. 특정 시점의 오프라인 월드 백업을 읽어 블록, 조명, 재질과 카메라 표현을 자기완결형 정적 웹 아카이브로 발행합니다. 서버가 멈추거나 원본 월드가 바뀌어도 같은 자산과 같은 주소로 당시 도시를 다시 열 수 있습니다.

Depth WebGL 뷰어로 본 내아거리의 도로와 건축물
내아거리 Depth 공개 뷰어. 정적 스냅샷 안에 블록 형상, 재질, 하늘빛과 인공조명 표현을 함께 담습니다.

먼저 알아둘 결론

이번 사례의 원본은 2026년 7월 1일 03시 전체 월간 백업입니다. X 13,444~14,673, Z -7,414~-6,780의 범위를 잘라 3,198개 청크로 읽었고 누락은 없었습니다. 3,041개 block state와 3,001개 재질 연결을 하나의 palette와 atlas로 정리해 브라우저가 반복해서 해석할 일을 발행 단계로 옮겼습니다.

내아거리 공개 아카이브 기준값 · 2026-09-02 재검증
원본2026-07-01 03:00 KST 오프라인 전체 월간 백업
공간 범위1,230 × 635블록 · Y -64~320
청크3,198 / 3,198 · 누락 0
비공기 블록85,765,828
현재 정적 탑재량3,258파일 · 22,597,463바이트 · 21.551 MiB

월드에서 웹까지 무엇이 바뀌는가

핵심은 원본을 복사하는 것이 아니라 브라우저가 바로 그릴 수 있는 표현으로 바꾸는 일입니다. 먼저 전체 백업으로 시점을 고정하고 좌표 범위를 청크 경계로 확장합니다. 각 청크의 block state는 전역 palette의 정수로, 조명은 block light와 sky light로 저장합니다. 리소스 팩과 client JAR에서 찾은 텍스처와 모델 면은 atlas와 사전 계산된 quad가 됩니다.

표현 변환 파이프라인

운영 월드와 분리된 발행물을 만듭니다

무거운 파싱과 재질 해석은 오프라인에서 끝냅니다. 공개 서버는 완성된 파일을 전달하고, 브라우저는 그 파일을 풀어 화면에 그립니다.

  1. 01시점 고정실행 중인 서버 대신 완결된 월간 백업을 읽어 모든 청크의 기준 시점을 맞춥니다.
  2. 02영역 절단요청 좌표를 포함하는 78 × 41개 청크를 선택하고 누락 여부를 검사합니다.
  3. 03상태 정규화반복되는 block state를 전역 palette 번호로 치환하고 조명 배열을 보존합니다.
  4. 04재질 사전 계산texture atlas를 만들고 block model의 보이는 면을 브라우저용 quad로 준비합니다.
  5. 05정적 계약 발행DEPTHSNAP에 공간 데이터를, DEPTHSITE에 제목·시작 화면·투어를 기록합니다.
  6. 06브라우저 재생WebGL2가 필요한 청크를 메시로 만들고 카메라·조명·후처리를 적용합니다.
Source → Anvil backup → palette and light arrays → atlas and pre-baked model quads → DEPTHSNAP + DEPTHSITE → static WebGL viewer.
서로 역할이 다른 세 개의 발행 계약
계약담는 것변경 단위
DEPTHSNAP v1bounds, 청크 목록, palette, 블록·조명 데이터, atlas월드 스냅샷을 다시 만들 때
DEPTHROWPACK v1같은 Z행 청크를 묶은 전송용 gzip archive와 hash청크 전송 구조를 다시 만들 때
DEPTHSITE v1프로젝트 이름, 시작 모드·시각, 카메라 투어보여 주는 방식만 바꿀 때

3,198개 청크를 41개 행으로 전달합니다

Minecraft 청크 한 변은 16블록입니다. 좌표의 양 끝을 포함하도록 청크 번호를 구하면 X방향 78개, Z방향 41개가 되고 둘을 곱한 3,198개가 캡처 대상입니다. 이 계산 결과는 manifest의 청크 목록과 실제 파일 수가 모두 같아야 통과합니다.

chunks_x = floor(14,673 / 16) - floor(13,444 / 16) + 1 = 78
chunks_z = floor(-6,780 / 16) - floor(-7,414 / 16) + 1 = 41
total_chunks = 78 × 41 = 3,198

파일을 청크마다 요청하면 공간을 열기 위해 최대 3,198회의 개별 요청이 필요합니다. Depth는 같은 Z행의 78개 청크를 하나의 행 팩으로 묶습니다. 색인 1개와 행 팩 41개, 모두 42개 요청으로 같은 청크를 전달할 수 있어 요청 수가 98.7% 줄어듭니다. 행 팩이 없거나 해제에 실패하면 남겨 둔 개별 파일로 돌아갑니다.

전송 요청 비교

행 팩은 저장량보다 요청 수를 줄이는 장치입니다

막대는 개별 청크 방식 3,198회를 100으로 둔 상대값입니다. 실제 전송은 카메라와 투어 순서에 따라 점진적으로 일어납니다.

개별 청크 파일

요청3,198

행 팩 색인 + 41개 행

요청42
42 / 3,198 = 1.3%. 행 팩의 압축 데이터는 6,315,792바이트이며 manifest의 모든 청크를 정확히 한 번 포함합니다.
행 팩이 바꾸는 전송과 메모리 단위
항목해석
행 팩 압축 데이터6,315,792바이트41개 행 파일의 gzip 크기 합
전체 행 해제 크기271,684,790바이트모든 행을 동시에 유지하지 않음
최대 3행 원시 창25,136,002바이트 · 9.3%앞·현재·뒤 행만 원시 상태로 유지
초기 준비 청크최대 15개첫 화면 또는 투어 진행축 주변부터 메시 생성

큰 도시를 안정적으로 그리는 방법

월드 좌표를 그대로 GPU 정점에 반복해서 넣으면 원점에서 멀수록 부동소수점 정밀도 문제가 커집니다. Depth는 정점을 청크 안의 작은 좌표로 두고 청크 원점을 별도로 전달합니다. 카메라 계산은 월드 위치를 유지하면서 실제 정점 버퍼는 작은 수를 사용합니다.

position_world = position_chunk_local + origin_chunk
visible(mesh) = sphereVisible(camera_frustum, mesh.center, mesh.radius)
draw = visible opaque meshes → visible blended meshes

렌더링 문제와 선택한 대응
문제선택효과
큰 월드 좌표청크 로컬 정점 + 별도 origin정점 수치를 작게 유지해 화면 떨림 위험을 낮춤
화면 밖 청크청크 구체와 카메라 절두체 비교보이지 않는 mesh의 draw call을 생략
투명 재질opaque와 blended mesh 분리불투명 장면 뒤에 투명 장면을 별도로 합성
넓은 그림자 범위2,048² shadow map 3단계카메라 거리별로 그림자 해상도를 나눔
낮과 밤의 대비HDR RGBA16F, bloom, FXAA, ACES 근사하늘빛과 block light를 분리하고 최종 화면 범위로 변환

모바일에서는 백그라운드 메시 생성 중 해상도와 그림자·bloom을 잠시 줄이고, 각 작업 묶음 뒤 입력과 렌더링 기회를 돌려줍니다. 숨겨진 탭에서는 행 해제와 메시 생성을 멈춥니다. 이는 최종 화질을 고정하는 설정이 아니라, 첫 화면과 조작 응답을 먼저 확보하기 위한 진행 순서입니다.

자동 순회 대신 60초 도시 서사를 기록합니다

스냅샷이 같아도 어디서 시작해 무엇을 보여 줄지는 별개의 문제입니다. 초기 자동 경로는 184.1초 동안 남북 경계를 오가며 내아거리의 주 도로와 무관한 회전·상승을 포함했습니다. 현재 `site.json`에는 10개 경유점을 두어 서측 진입, 간선도로 저공 이동, 중심부 상승, 전체 전경의 순서로 60.2초 경로를 고정했습니다.

투어 길이와 구성

짧아진 시간보다 경로의 목적이 중요합니다

내아거리 편집 경로는 자동 경로의 약 32.7% 길이입니다. 비교의 목적은 속도가 아니라 건물 내부와 빈 월드를 피하며 거리의 구조를 순서대로 보여 주는 것입니다.

내아거리 일반 자동 경로

길이184.1초

황룡사 참고 경로

길이59.4초

내아거리 10개 경유점

길이60.2초
2026-08-30 운영 브라우저 측정 기록. 현재 공개 DEPTHSITE에도 같은 10개 경유점이 유지됩니다.

투어가 코드가 아니라 데이터인 덕분에 viewer와 스냅샷을 다시 만들지 않고도 경로만 검토할 수 있습니다. 발행 검사는 site id, 경유점 수, 카메라·주시점·FOV·시각의 유한값, 카메라 X/Z가 snapshot bounds 안에 있는지를 확인합니다.

재현 가능한 것과 아직 말할 수 없는 것

보고서 작성 시점에 운영 파일과 공개 응답을 다시 내려받아 `site.json`, manifest와 행 팩 색인의 SHA-256을 비교했습니다. 세 파일은 각각 일치했고 공개 프로젝트와 viewer는 HTTP 200을 반환했습니다. 운영 스냅샷은 3,198개 청크, 누락 0, 3,041개 palette, 85,765,828개 비공기 블록에 합의합니다.

공개 핵심 계약의 2026-09-02 SHA-256
파일SHA-256
site.json3ba7e768b96731d96e9546d54e7f20057a476d53f2abfd2fcec5df5417f60cc7
manifest.jsonca3c7ad08740e405ec228d8c445676acfd9e1975f42a93ae8ee0857824e361f2
행 팩 index.jsoncce35979c03e267673b15dde8c64f168dfb6187c77b08dc052dba43b4aea23ea

이 검증이 보장하지 않는 범위도 분명합니다.

  • 스냅샷은 2026년 7월 1일의 도시입니다. 이후 건축 변경이나 이용자 활동을 실시간으로 반영하지 않습니다.
  • 22.60 MB는 정적 탑재량입니다. 최초 화면의 네트워크 전송량이나 원본 월드 대비 압축률이 아닙니다.
  • block entity, biome와 애니메이션 등 원본 표현의 보존률은 이번 보고서에서 완전성을 검증하지 않았습니다.
  • WebGL 결과는 Minecraft 게임 렌더러의 픽셀 단위 복제가 아닙니다. atlas, 조명과 후처리로 다시 구성한 브라우저 표현입니다.
  • 실제 로딩 시간과 프레임률은 네트워크, 브라우저와 GPU에 따라 달라집니다. 소프트웨어 WebGL 측정값을 사용자 성능으로 일반화하지 않습니다.
  • hash는 이번 검증 시점의 근거입니다. 자산이 갱신되면 manifest 수치와 함께 다시 측정해야 합니다.
내아거리 프로젝트 보기 BLOCK · 새 창 Depth에서 직접 탐색하기 WebGL2 · 새 창