문제의식
게임은 조각상으로 가득한 방이고 그중 일부가 살아 있다. 그리고 웹 포털로 나간다 — 즉 조각상 하나하나가 플레이 전에 네트워크로 도착해야 한다. 여덟 종류를 손으로 모델링하는 건 이 규모에서 선택지가 아니었고, 대안인 생성은 웹에서 못 쓰는 파일을 뱉는다. 보물상자 하나가 변환 직후 13MB에 삼각형 3만 개다. 그래서 질문은 「3D를 만들 수 있는가」가 아니었다. 만들어진 것을 브라우저가 받을 크기까지 줄여도 형태가 버티는가였다.
$
케이스 13 · 3D 파이프라인
호러 게임에 조각상이 필요해서, 텍스트 프롬프트에서 브라우저가 실제로 받을 수 있는 메시까지 가는 선을 만들었다. 에셋 하나에 8분, 13.13MB를 421KB로. 그러고 나서 한계 항목에 두 가지를 「불가능」이라고 적었다 — 부분 수정과 폴리곤 예산. 둘 다 틀렸다. 하나는 기록을 원래 맥락에서 떼어 옮긴 탓이고, 하나는 존재하지 않는 이름으로 파라미터를 부른 탓이다. 파이프라인보다 이 틀린 방식이 더 옮겨쓸 만해서 둘 다 남긴다.
$
문제의식
게임은 조각상으로 가득한 방이고 그중 일부가 살아 있다. 그리고 웹 포털로 나간다 — 즉 조각상 하나하나가 플레이 전에 네트워크로 도착해야 한다. 여덟 종류를 손으로 모델링하는 건 이 규모에서 선택지가 아니었고, 대안인 생성은 웹에서 못 쓰는 파일을 뱉는다. 보물상자 하나가 변환 직후 13MB에 삼각형 3만 개다. 그래서 질문은 「3D를 만들 수 있는가」가 아니었다. 만들어진 것을 브라우저가 받을 크기까지 줄여도 형태가 버티는가였다.
만든 선
컨셉 — 일부러 격리해서
텍스트에서 평평한 배경 위의 단일 오브젝트로. 형태는 두껍게, 얇은 잔가지는 금지. 미감의 문제가 아니다 — 장면형 컨셉과 가느다란 디테일은 변환에서 깨진다. 이 세트의 죽은 나무를 「발톱 같은 가지, 얇은 트위그 없이」로 지정한 이유가 그것이다.
이미지에서 메시로, PBR까지
약 6분, 텍스처 맵 네 장이 함께 나온다 — 기본색·거칠기/금속·노멀·발광. 5천 삼각짜리 상자에서 나무결이 보이는 건 노멀맵 덕이다. 디테일이 형태가 아니라 텍스처에 있다.
줄이기 — 이 순서로
메시 감축 → 텍스처 WebP → 미사용 제거 → 정점 병합 → 지오메트리 압축. 순서가 중요한 건 무게의 대부분이 텍스처이기 때문이다. 상자 13.13MB 중 11MB가 2048×2048 맵 네 장이었다. 메시는 상대적으로 싸다.
엔진에 넣고 눈으로
수치는 얼굴이 무너졌는지 알려주지 않는다. 모든 에셋을 three.js에서 같은 조명으로 렌더해 원본과 대조한다 — 이 사이트에 올라간 자산들이 그 결과물이기도 하다.
상자 하나, 다섯 단계
위 에셋에서 실측. 최종 파일은 변환 직후의 1/32이다.
| 단계 | 삼각형 | 크기 |
|---|---|---|
| 변환 직후 | 30,367 | 13.13 MB |
| 메시 감축 | 14,110 | — |
| 텍스처 → WebP | 14,110 | 2.00 MB |
| 지오메트리 압축 | 14,110 | 1.60 MB |
| 모바일 프로파일 | 5,306 | 0.41 MB |
같은 물건, 32배 차이
같은 조명, 같은 각도. 자물쇠·리벳·나무결이 감축을 견딘다. 우물은 정면 이미지 한 장으로 만들었는데 뒷면이 존재한다 — 게임에 들어갈 물건이라면 그게 전부를 가르는 질문이다.

컨셉 이미지 — 텍스트에서, 15초
평평한 배경과 두꺼운 형태는 취향이 아니라 요건이다. 부서지기 쉬운 디테일은 변환을 못 넘긴다.

변환 직후 — 13.13MB · 30,367 삼각
정확하지만 웹에서는 못 쓴다.

최적화 후 — 0.41MB · 5,306 삼각
32배 작다. 이 크기에서 차이를 찾아보라 — 그게 요점이다.

뒷면 135° — 단일 이미지 입력
나무판과 금속 밴드가 뒤까지 이어진다. 이게 없으면 모델이 아니라 간판이다.
틀린 곳 1
부분 수정이 불가능하다고 적었다. 생성 메시는 재질이 하나이고 텍스처가 통짜로 구워지므로 「자물쇠만 은색으로」는 전체 재생성이라고. 근거로 삼은 건 이 게임의 예전 빌드에서 남긴 기록이었다. 그런데 그 기록은 three.js 런타임에서 재질을 틴트하려던 이야기였고, 거기서는 재질이 하나면 모델 전체가 물드는 게 맞다. 텍스처 파일을 편집하는 건 아예 다른 작업이다. GLB를 풀면 맵이 평범한 이미지 파일로 떨어진다. 황동색 픽셀만 색상값으로 골라 바꾸고 다시 묶었다. 텍스처의 0.63%가 바뀌었고, 자물쇠는 은색이 됐고, 나무와 밴드와 리벳은 그대로였다. 기록은 참이었다. 참이던 상황에서 내가 떼어 온 것이다.
자물쇠만, 자물쇠만
왼쪽부터: GLB에서 빠져나온 텍스처, 그리고 수정 전후. 여전히 불가능한 건 형태 변경이다 — 더 큰 자물쇠, 손잡이 추가. 색과 질감은 되고, 형태는 재생성이 필요하다.

baseColor 텍스처 2048² — 좌상단이 자물쇠
물건 전체가 한 장에 펼쳐져 있다. 모든 표면이 이 시트 어딘가에 있다.

수정 전 — 황동 자물쇠
원본 텍스처 그대로.

수정 후 — 0.63% 픽셀 치환
색상값으로 골라서 마스크도 UV 조회도 필요 없었다. 나머지는 바이트 단위로 동일하다.
틀린 곳 2
폴리곤 예산도 주문할 수 없다고 적었다. 변환기가 항상 3만 삼각 안팎을 뱉으니 5,000을 원하는 의뢰는 후처리로만 맞출 수 있다고. 근거는 「해당 파라미터를 지원하지 않는다」는 API 응답이었다. 지원되지 않은 이유는 내가 `polycount`라고 불렀기 때문이고, 그런 이름은 없다. 진짜 이름은 `target_polycount`이고 100부터 300,000까지 받는다. 6,000 쿼드를 요청하니 6,084가 나왔다 — 1.4% 오차. 그리고 `quad` 토폴로지 옵션이 있는데 이게 개수보다 중요하다. 쿼드 메시는 모델러가 열어서 이어 작업할 수 있는 형태라, 생성 에셋과 수작업 에셋 사이의 간격을 대부분 메운다. 거부된 호출 하나가 「기능이 없다」를 대신하고 있었다.
6,000 요청, 6,084 수령
같은 소스 이미지, 나머지도 동일. 정점이 3분의 1로 준다 — 렌더러가 실제로 값을 치르는 부분이 그쪽이다.
| 요청 | 결과 | 정점 | 크기 |
|---|---|---|---|
| 지정 없음 | 30,367 tris | 27,667 | 13.13 MB |
| target_polycount: 6000 · quad | 12,169 삼각 = 6,084 쿼드 | 8,637 | 0.38 MB |
방법론으로 남은 것
두 오류의 모양이 같다. 좁은 근거를 일반 명제로 올렸고, 확인할 테스트를 돌리지 않았다. 그래서 규칙 둘. 다른 프로젝트의 기록을 인용할 때는 전제 조건까지 같이 옮길 것 — 특정 조건에서의 실패는 도구의 성질이 아니다. 그리고 API가 무언가를 거부하면 기능이 없다고 결론내기 전에 이름을 의심할 것. 모델 카탈로그에 진짜 파라미터가 적혀 있고 읽는 데 몇 초 걸린다. 여기서 틀린 대가는 낭비한 시간이 아니었다. 두 한계를 서비스 설명에 적기 직전이었고, 그랬다면 실제로 가진 능력을 스스로 부정하며 팔 뻔했다.
이 선이 실제로 보장하는 것
POLY BUDGET
생성 단계에서 주문, 후처리에서 재확인
QUAD TOPOLOGY
모델링 도구에서 열어 이어 작업 가능
PBR · 4 MAPS
디테일이 형태가 아니라 텍스처에
TWO PROFILES
웹 1.4MB · 모바일 0.4MB
COLOUR EDITS
텍스처 단위, 재생성 없이
SHAPE = REGEN
남은 진짜 한계
$
근거 · 깃·위키 인용