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 표시