2D Canvas 아이소메트릭 렌더링을 Three.js 로우폴리 3D로 전면 전환했습니다. 건물 진입 기능과 신도시 레이아웃도 함께 추가.
왜 바꿨나
기존 렌더링의 한계가 명확했습니다:
- 건물이 색칠한 박스
- 캐릭터가 종이인형 스프라이트
- 그림자도 조명도 없음
- 날씨가 화면에 선 긋는 수준
"짜치는 것들을 다 없애자"는 한 마디에서 시작해서, Three.js로 Crossy Road 스타일 로우폴리 3D를 만들었습니다.
신도시 레이아웃
건물 배치를 전면 리뉴얼했습니다.
- 중앙 대로 (x=25): 남북으로 관통하는 메인 도로
- 동서 교차로 (y=25): 광장이 되는 교차점
- 골목길 4개: 상업/주거/캠퍼스 연결
- 건물 11개를 대로 양쪽으로 정렬 (서쪽 상가, 동쪽 상가, KSA 캠퍼스, 남쪽 주거)
- 월드 크기 100x100 → 60x65로 축소 (빈 공간 제거)
건물 내부 진입
E키로 문 앞에서 건물 안으로 들어갈 수 있습니다.
- 11개 건물 전부 인테리어 보유
- 건물별 고유 가구/색상 (카페엔 테이블, 도서관엔 책장, 주택엔 침대)
- NPC도 시간대에 따라 건물 진출입 (출근, 퇴근, 귀가)
- 실내에서 날씨 파티클 자동 차단
Three.js 렌더러 아키텍처
기존 7100줄 main.js에서 렌더링을 완전히 분리:
src/playground/renderer/ (10개 모듈, ~2000줄)
renderer.js — WebGL 씬/루프 오케스트레이터
camera-rig.js — Ortho(아이소메트릭) + Perspective(실내) 듀얼 카메라
terrain.js — vertex color 지면 + 물결 애니메이션
lighting.js — 태양/달/주변광 밤낮 주기
buildings.js — 7종 지붕 (박공/평지붕/뾰족/페디먼트/맨사드/모던)
props.js — 나무/가로등/벤치/바위/분수 등 10종
entities.js — Crossy Road 박스 캐릭터 + 걷기 애니메이션
interior.js — 실내 렌더링
weather-fx.js — 비/눈/안개/흐림 파티클
speech-overlay.js — CSS 말풍선 (3D→화면 투영)
게임 로직은 한 줄도 건드리지 않았습니다. USE_3D = false로 바꾸면 기존 2D로 돌아갑니다.
핵심 설계
좌표 매핑: 게임 (x, y) → Three.js (x, 0, y). 렌더러만 변환하고 로직은 2D 그대로.
듀얼 캔버스: WebGL canvas 위에 투명한 2D canvas를 겹쳐서 미니맵/HUD를 유지.
MeshToonMaterial: 3단계 gradient map으로 cel-shading. Crossy Road의 깔끔한 느낌.
날씨: sizeAttenuation: false + 줌 비례 크기 조절. 맵 중앙 고정으로 파티클이 플레이어를 따라다니지 않음.
밤낮 조명
실시간 동기화된 게임 시간에 맞춰 태양/달/주변광이 자동 전환:
- 새벽: 오렌지 일출
- 낮: 풀 밝기 + 그림자
- 황혼: 붉은 노을
- 밤: 달빛 + 가로등 PointLight
최소 밝기 하한선으로 어떤 날씨+시간에서도 항상 캐릭터가 보입니다.
건물 시각 개선
3D 전환과 함께 건물 외형도 대폭 업그레이드:
- 7종 지붕: 주택(박공), KSA(평지붕+난간), 시장(뾰족 빨간색), 도서관(클래식 페디먼트), 카페/빵집/꽃집(맨사드), 사무실(모던)
- 창문 다양화: 기관(격자), 도서관(아치), 주택(덧문)
- 문에 손잡이, 유리 패널
- 간판에 그림자 효과
다음 목표
- 캐릭터 모션 확장 (앉기, 눕기, 기분별 모션)
- 실내 카메라 전환 애니메이션
- 바닥 아이템/핫스팟 3D 표시