img2obj: 참조 이미지를 애니메이션 가능한 Three.js 절차적 코드로 재구성하는 Codex 플러그인

img2obj 소개

웹에 3D 오브젝트를 하나 올리려면 보통 모델 파일을 구해 옵니다. 에셋 스토어에서 내려받거나, 사진 여러 장으로 포토그래메트리(Photogrammetry)를 돌려 메시를 뽑거나, 3D 도구에서 직접 모델링합니다. 세 방법 모두 결과물이 바이너리 메시라서 저장소에 수십 메가바이트가 들어오고, 회전축이나 여닫히는 부품을 나중에 붙이려면 원본 파일을 다시 열어야 하며, 부품 하나의 비율을 고치는 일이 코드 리뷰로 확인되지 않습니다. 웹 앱을 코드로 관리하는 팀에게 3D 자산만 다른 규칙으로 남는 셈입니다.

img2obj는 그 자산을 코드로 되돌리는 쪽을 택한 Codex 플러그인입니다. 참조 이미지 한 장을 넣으면 픽셀을 메시로 변환하는 것이 아니라, 이미지를 판독해 부품 계층과 지오메트리와 재질을 담은 ObjectSculptSpec 을 먼저 작성하고, 그 명세에서 Three.js 지오메트리를 절차적으로 생성하는 TypeScript 팩토리 함수를 만듭니다. 결과물이 코드이므로 회전축(Pivot)과 부착점(Socket)과 부모 자식 관계를 처음부터 명세에 넣을 수 있고, 값 하나를 바꾸는 수정이 diff로 남습니다.

절차 안에 검수 단계가 들어 있다는 점이 이 플러그인의 다른 축입니다. img2obj는 블록아웃에서 형태, 룩데브, 인터랙션으로 단계를 올리면서 각 단계마다 브라우저 렌더 결과를 원본 이미지와 나란히 놓고 차이가 큰 곳부터 고치도록 만들고, 다음 단계로 넘어가기 전에 사용자 승인을 요구합니다. 저자는 이 흐름을 *"It guides Codex through a controlled reconstruction workflow"*라고 설명하면서, 픽셀을 완성된 메시로 바꿔 주는 도구가 아니라는 점을 함께 밝히고 있습니다. 저장소는 원래 Three.js-Object-Sculptor-Codex-Plugin 이라는 이름이었고 지금은 img2obj 로 바뀌어 예전 주소가 새 주소로 넘어옵니다.

img2obj가 만드는 것과 만들지 못하는 것

프로젝트가 첫 화면에서 적용 범위를 표로 정리해 둔 것이 도입 판단에 가장 먼저 쓰입니다:

항목 내용
입력 첨부한 오브젝트 이미지, 스크린샷, 또는 로컬 이미지 경로
출력 ObjectSculptSpec 과 코드만으로 이루어진 절차적 Three.js 팩토리
목표 보이는 실루엣, 구조, 재질, 그리고 움직임을 붙일 수 있는 계층의 재현
적합 스타일라이즈드 소품, 기계 장치, 식물, 장면 자산, 인터랙티브 모델
부적합 포토그래메트리, 정확한 메시 추출, 이미지 한 장에서 프로덕션급 지오메트리 보장

부적합 열이 특히 중요합니다. 프로젝트가 밝힌 한계는 이미지 한 장으로는 가려진 면과 정확한 치수를 알 수 없다는 것, 결과가 스캔이나 추출이 아닌 절차적 근사라는 것, 투명한 유리와 연기와 액체와 털과 얇은 천과 정확한 인물 닮음에는 참조가 더 필요하거나 목표 정밀도를 낮춰야 한다는 것입니다. 생성된 팩토리 함수는 완성된 프로덕션 자산 파이프라인의 대체물이 아니라 출발점이라고 명시해 두었습니다.

img2obj의 재구성 워크플로우

저자가 정리한 절차는 네 단계입니다. 첫 단계에서 참조 이미지의 품질과 오브젝트 가시성과 복잡도를 점검하고 더 깨끗한 원본이 필요한지 판정합니다. 두 번째 단계에서 부품 계층, 지오메트리, 재질, 회전축, 부착점, 시각적 우선순위를 ObjectSculptSpec 으로 서술합니다. 세 번째 단계에서 블록아웃, 형태, 룩데브, 인터랙션 순서로 진행하면서 뒤 단계의 디테일을 앞 단계에 끌어오지 않습니다. 마지막 단계에서 브라우저 렌더를 현재 원본과 비교해 영향이 큰 차이부터 고치고, 다음 단계로 올라가기 전에 승인을 받습니다.

품질 판정은 두 층으로 나뉩니다. 전체 정체성은 실루엣, 비율, 카메라, 재질, 조명을 봅니다. 핵심 특징은 그 오브젝트를 알아보게 만드는 소수의 부품, 예를 들어 지붕 윤곽이나 가지가 갈라지는 지점이나 바퀴 뭉치나 손이 물체에 닿는 부분을 봅니다. 전체 점수가 높아도 핵심 특징 하나가 실패하면 통과하지 못합니다. 활성 단계에서는 시각적 증거와 사용자의 명시적 승인이 함께 있어야 다음으로 넘어갑니다.

이 워크플로우가 실제로 무엇을 만들어 내는지는 저장소가 공개한 두 개의 사례에서 확인할 수 있습니다.

첫 번째 사례인 누선(Tower Ship) 데모는 왼쪽 아래에 참조 이미지를 함께 띄워 두고, 절차적 지오메트리와 관절이 있는 부품과 재질 작업과 브라우저 조작을 함께 보여 줍니다. 화면 아래의 버튼으로 회전대, 강풍, 노 젓기, 등불, 번개를 켜고 끌 수 있는데, 이 움직임들이 명세 단계에서 미리 계획한 회전축과 부착점 위에서 동작합니다.

두 번째 사례인 오래된 가을 나무(Ancient Autumn Tree) 데모는 성격이 다른 문제를 다룹니다. 절차적 곡선, 결정론적 가지 분기, 겹쳐 쌓은 껍질, 빽빽한 잎, 그리고 움직임을 붙일 수 있는 계층이 이 사례의 초점입니다. 가지가 결정론적으로 갈라진다는 것은 같은 명세에서 같은 나무가 다시 나온다는 뜻이라, 코드로 관리하는 자산에서 중요한 성질입니다.

img2obj 설치와 사용

저장소를 받아 로컬 Codex 플러그인으로 불러오는 방식입니다. Codex의 로컬 플러그인 지원과 Python 3.10 이상, 그리고 생성된 팩토리를 띄울 Three.js 브라우저 프로젝트가 필요하고, 원본 정리와 계획 시점의 뷰 생성과 시각 검수에는 이미지와 비전 접근이 필요합니다:

git clone https://github.com/vinhhien112/img2obj.git
cd img2obj
python3 scripts/sculpt.py --help

플러그인을 불러온 뒤에는 오브젝트 이미지를 첨부하고 자연어로 요청합니다:

Use img2obj to turn the object in this image into a procedural Three.js model built entirely with code.

움직임이 필요하면 그 요구만 따로 덧붙입니다. 프로젝트가 든 예시는 *"Make the visible hatch open on its hinge. Do not add physics or destruction"*처럼 원하는 동작과 원하지 않는 범위를 함께 적는 형태입니다.

명령줄에서 직접 단계를 밟을 수도 있습니다. 저장소의 scripts/sculpt.py가 통합 진입점이고, 명세 생성부터 검증과 코드 생성까지 하위 명령으로 이어집니다:

python3 scripts/sculpt.py init "Ancient Autumn Oak" \
  --image ./reference/oak-tree.png \
  --reference-separation clear \
  --complexity complex \
  --out object-sculpt-spec.json

python3 scripts/sculpt.py context object-sculpt-spec.json

python3 scripts/sculpt.py validate object-sculpt-spec.json \
  --for-pass blockout \
  --strict-quality

python3 scripts/sculpt.py generate object-sculpt-spec.json \
  --out src/AncientOak.generated.ts \
  --wrapper-out src/AncientOak.ts

init 이 참조 이미지와 분리도와 복잡도를 받아 명세 JSON을 만들고, validate 가 지정한 단계 기준으로 명세를 검사하며, generate 가 생성 파일과 그것을 감싸는 래퍼(Wrapper) 파일을 따로 떨궈 줍니다. 생성물과 손으로 고칠 파일을 분리해 두는 구성이라 재생성이 사용자 수정을 덮지 않습니다. 비교, 검수, 보정, 능력 팩, 프로브, PBR(Physically Based Rendering) 맵 관련 명령은 --help 로 확인할 수 있고, 워크플로우 계약과 스크립트를 고친 뒤에는 회귀 테스트를 실행합니다:

python3 -m unittest discover -s tests

핵심 워크플로우 정의는 저장소의 skills/object-to-threejs-procedural/에 들어 있어, 플러그인을 쓰지 않고 명세만 읽어 보는 것도 가능합니다.

이미지에서 3D를 만드는 다른 접근과 비교

같은 입력에서 출발하는 프로젝트들이 서로 다른 출력을 고릅니다. img2threejs (:pytorch::kr: img2threejs: 이미지 한 장을 코드로 재구성하는 Three.js 3D 모델 생성 도구)도 이미지 한 장을 Three.js 코드로 재구성하고, 3DCellForge (:pytorch::kr: 3DCellForge: 참조 이미지를 인터랙티브 3D 모델로 만드는 웹 스튜디오)는 참조 이미지를 인터랙티브 3D 모델로 만드는 웹 스튜디오를 제공하며, image-blaster (:pytorch::kr: image-blaster: 이미지 한 장에서 3D 환경과 효과음을 만들어내는 Claude 스킬셋)는 이미지에서 3D 환경과 효과음까지 함께 만들어 냅니다. 자연어에서 출발하는 CADAM (:pytorch::kr: CADAM: 자연어로 3D CAD 모델을 만드는 오픈소스 text-to-CAD 웹 애플리케이션)처럼 입력 자체가 다른 계열도 있습니다.

img2obj가 이 중에서 다른 점은 완성도를 게이트로 만들어 사람의 승인 없이는 단계가 올라가지 않게 한 것입니다. 저장소는 지원하지 않는 지오메트리와 검증되지 않은 보정을 조용히 추측한 결과로 대체하지 않고 거부한다고 적어 두었고, 시각적 수용 판정에는 비전 검수가 필요하며 로컬 스크립트는 증거를 정리할 뿐 유사도를 스스로 판정하지 않는다고 범위를 그어 두었습니다. 빠르게 결과를 얻는 것보다 어디까지 닮았는지를 확인하며 올라가는 쪽에 무게를 둔 설계입니다.

img2obj는 누구에게 맞는가

Three.js로 웹 씬을 직접 만들고 있고, 소품이나 배경 자산을 바이너리 메시가 아닌 코드로 두고 싶다면 잘 맞습니다. 특히 부품이 여닫히거나 회전하는 인터랙티브 오브젝트가 필요할 때, 계층과 회전축을 처음부터 명세에 넣는 방식이 나중에 리깅을 얹는 것보다 손이 덜 갑니다. 이미 Codex를 쓰고 있다면 로컬 플러그인으로 불러오는 비용도 저장소를 받아 두는 것으로 끝납니다.

반대로 실측 치수가 맞아야 하는 자산이나 실사 수준의 닮음이 필요한 팀에게는 img2obj가 적절한 선택지가 아닙니다. 저자가 직접 포토그래메트리와 정확한 메시 추출을 부적합 항목으로 적어 두었고, 이미지 한 장에서는 가려진 면과 치수를 복원할 수 없다는 한계도 함께 밝혀 두었습니다. 사람이 매 단계 승인해야 진행되는 구조이므로, 자산 수백 개를 무인으로 찍어 내는 용도와도 맞지 않습니다.

img2obj의 라이선스

img2obj는 MIT 라이선스로 공개되어 있어 개인 및 상업적 목적으로 자유롭게 사용할 수 있습니다.

:framed_picture: img2obj로 만든 누선(Tower Ship) 라이브 데모

:framed_picture: img2obj로 만든 오래된 가을 나무 라이브 데모

:github: img2obj 프로젝트 GitHub 저장소

더 읽어보기




이 글은 GPT 모델로 정리한 초안을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 댓글로 알려주시기를 부탁드립니다. :hugs:

이 도구를 직접 설치해 사용해보셨다면, :pytorch:파이토치 한국 사용자 모임:south_korea: 회원들을 위해 경험이나 팁을 댓글로 남겨주세요! :folded_hands: