# ๐Ÿฆ– ์šฐ๋ฆฌ ๋ฐ˜์— ๊ณต๋ฃก์ด ๋‚˜ํƒ€๋‚ฌ๋‹ค! (Dino AR Camera) ์ดˆ๋“ฑํ•™๊ต 1ํ•™๋…„ ํ†ตํ•ฉ๊ต๊ณผ **'์šฐ๋ฆฌ ๋ฐ˜์— ๊ณต๋ฃก์ด ๋‚˜ํƒ€๋‚œ๋‹ค๋ฉด'** ์ˆ˜์—…์„ ์œ„ํ•ด ๊ฐœ๋ฐœ๋œ ์›น ๊ธฐ๋ฐ˜ ๋ฌด๋ฃŒ 3D AR ๊ณต๋ฃก ์นด๋ฉ”๋ผ์ž…๋‹ˆ๋‹ค. ๋ณ„๋„์˜ ์•ฑ ์„ค์น˜, ํšŒ์›๊ฐ€์ž…, ๊ด‘๊ณ  ์—†์ด ์›น ๋ธŒ๋ผ์šฐ์ €๋งŒ์œผ๋กœ ๊ต์‹ค ์นด๋ฉ”๋ผ ํ™”๋ฉด ์œ„์— ์›€์ง์ด๋Š” 3D ๊ณต๋ฃก์„ ์†Œํ™˜ํ•˜๊ณ  ์นœ๊ตฌ๋“ค๊ณผ ํ•จ๊ป˜ ์‚ฌ์ง„์„ ์ฐ์–ด ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- ## 1. ์ฃผ์š” ๊ตฌํ˜„ ๊ธฐ๋Šฅ (1์ฐจ ๋ฒ„์ „) ### ๐Ÿ“ท ์นด๋ฉ”๋ผ ๋ฐ ๊ต์‹ค ์—ฐ์Šต ๋ฐฐ๊ฒฝ - **์ž๋™ ์นด๋ฉ”๋ผ ์—ฐ๊ฒฐ**: ๋ธŒ๋ผ์šฐ์ €์—์„œ `MediaDevices.getUserMedia()`๋ฅผ ํ†ตํ•ด ์นด๋ฉ”๋ผ ๊ถŒํ•œ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. - ํƒœ๋ธ”๋ฆฟ/์Šค๋งˆํŠธํฐ: **ํ›„๋ฉด ์นด๋ฉ”๋ผ(`environment`)** ์šฐ์„  ์‚ฌ์šฉ - PC / ๋…ธํŠธ๋ถ: **์›น์บ ** ์ž๋™ ์—ฐ๊ฒฐ - **์ „ยทํ›„๋ฉด ์นด๋ฉ”๋ผ ์ „ํ™˜**: ์ƒ๋‹จ `๐Ÿ”„ ์นด๋ฉ”๋ผ` ๋ฒ„ํŠผ์œผ๋กœ ์ „๋ฉด(์…€์นด, ์ž๋™ ์ขŒ์šฐ ๋ฏธ๋Ÿฌ๋ง)๊ณผ ํ›„๋ฉด ์นด๋ฉ”๋ผ๋ฅผ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - **๊ต์‹ค ๋ฐฐ๊ฒฝ ํด๋ฐฑ ๋ชจ๋“œ**: ์นด๋ฉ”๋ผ๊ฐ€ ์—†๋Š” ๋ฐ์Šคํฌํ†ฑ PC์ด๊ฑฐ๋‚˜ ์นด๋ฉ”๋ผ ๊ถŒํ•œ์ด ๊ฑฐ๋ถ€๋œ ๊ฒฝ์šฐ์—๋„ ์ˆ˜์—…์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก **1ํ•™๋…„ ๊ต์‹ค ์ผ๋Ÿฌ์ŠคํŠธ ๋ฐฐ๊ฒฝ ๋ชจ๋“œ(`๐Ÿซ ๊ต์‹ค๋ฐฐ๊ฒฝ`)**๋ฅผ ๊ธฐ๋ณธ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ### ๐Ÿฆ– 3D ๊ณต๋ฃก ๋ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ยท์šธ์Œ์†Œ๋ฆฌ - **๊ธฐ๋ณธ ๊ณต๋ฃก**: **ํ‹ฐ๋ผ๋…ธ์‚ฌ์šฐ๋ฃจ์Šค(T-Rex)**๊ฐ€ ์ฒซ ํ™”๋ฉด์— ๋“ฑ์žฅํ•ฉ๋‹ˆ๋‹ค. - **์ถ”๊ฐ€ ๊ณต๋ฃก ํฌํ•จ (์ด 5์ข…)**: 1. ๐Ÿฆ– **ํ‹ฐ๋ผ๋…ธ์‚ฌ์šฐ๋ฃจ์Šค** (`public/models/trex.glb`) 2. ๐Ÿฆ• **ํŠธ๋ฆฌ์ผ€๋ผํ†ฑ์Šค** (`public/models/triceratops.glb`) 3. ๐Ÿฆ• **๋ธŒ๋ผํ‚ค์˜ค์‚ฌ์šฐ๋ฃจ์Šค** (`public/models/brachiosaurus.glb`) 4. ๐Ÿ‰ **์Šคํ…Œ๊ณ ์‚ฌ์šฐ๋ฃจ์Šค** (`public/models/stegosaurus.glb`) 5. ๐Ÿฆ– **๋ฒจ๋กœ์‹œ๋žฉํ„ฐ** (`public/models/velociraptor.glb`) - **์ž์—ฐ์Šค๋Ÿฌ์šด ์กฐ๋ช…๊ณผ ๋ฐ”๋‹ฅ ๊ทธ๋ฆผ์ž**: `HemisphereLight`, `DirectionalLight`(Soft Shadow Map), ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ ๊ต์‹ค ๋ฐ”๋‹ฅ ์˜์ƒ ์œ„์— ๊ทธ๋ฆผ์ž๋งŒ ํˆฌ๋ช…ํ•˜๊ฒŒ ๋“œ๋ฆฌ์šฐ๋Š” `ShadowMaterial` ๋ฐ”๋‹ฅ ํ‰๋ฉด(Shadow Catcher)์„ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. - **์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ**: ๋‚ด์žฅ ํ‚คํ”„๋ ˆ์ž„ ์• ๋‹ˆ๋ฉ”์ด์…˜(`Idle` ์ˆจ์‰ฌ๊ธฐ, `Walk` ๊ฑท๊ธฐ, `Roar` ์ž… ๋ฒŒ๋ ค ํฌํšจํ•˜๊ธฐ) ๋ฐ ๋ณด์กฐ ๊ด€์ ˆ ๋ชจ์…˜์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. - **์šธ์Œ์†Œ๋ฆฌ ๋ฐ ์Œ์†Œ๊ฑฐ**: ๊ณต๋ฃก๋ณ„ ๊ณ ์œ  ์šธ์Œ์†Œ๋ฆฌ(`public/sounds/*.wav` + Web Audio API ํ•ฉ์„ฑ ํด๋ฐฑ) ์žฌ์ƒ ๋ฐ ์ƒ๋‹จ `๐Ÿ”Š ์†Œ๋ฆฌ ์ผœ์ง / ๐Ÿ”‡ ์†Œ๋ฆฌ ๊บผ์ง` ํ† ๊ธ€์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ### ๐Ÿ‘† ์ดˆ๋“ฑํ•™๊ต 1ํ•™๋…„ ๋งž์ถคํ˜• ์กฐ์ž‘ (PC & ํƒœ๋ธ”๋ฆฟ) - **PC ์กฐ์ž‘**: - **๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋“œ๋ž˜๊ทธ**: ๊ณต๋ฃก ์œ„์น˜ ์ด๋™ - **๋งˆ์šฐ์Šค ํœ **: ๊ณต๋ฃก ํฌ๊ธฐ ํ™•๋Œ€ยท์ถ•์†Œ (`0.35๋ฐฐ ~ 2.8๋ฐฐ` ์•ˆ์ „ ๋ฒ”์œ„ ์ž๋™ ์ œํ•œ) - **ํšŒ์ „ ๋ฒ„ํŠผ (`โ†ฉ๏ธ ์™ผ์ชฝ ๋Œ๋ฆฌ๊ธฐ` / `โ†ช๏ธ ์˜ค๋ฅธ์ชฝ ๋Œ๋ฆฌ๊ธฐ`)** ๋˜๋Š” **์šฐํด๋ฆญ/Shift ๋“œ๋ž˜๊ทธ**: ๊ณต๋ฃก ๋ฐฉํ–ฅ ํšŒ์ „ - **ํƒœ๋ธ”๋ฆฟ / ๋ชจ๋ฐ”์ผ ์กฐ์ž‘**: - **ํ•œ ์†๊ฐ€๋ฝ ๋“œ๋ž˜๊ทธ**: ๊ณต๋ฃก ์œ„์น˜ ์ด๋™ - **๋‘ ์†๊ฐ€๋ฝ ํ•€์น˜ ์คŒ(๋ฒŒ๋ฆฌ๊ธฐ/์˜ค๋ฏ€๋ฆฌ๊ธฐ)**: ๊ณต๋ฃก ํฌ๊ธฐ ํ™•๋Œ€ยท์ถ•์†Œ - **๋‘ ์†๊ฐ€๋ฝ ํšŒ์ „ ๋˜๋Š” ํšŒ์ „ ๋ฒ„ํŠผ**: ๊ณต๋ฃก ๋ฐฉํ–ฅ ํšŒ์ „ - **์›๋ž˜๋Œ€๋กœ ๋ฒ„ํŠผ (`๐ŸŽฏ ์›๋ž˜๋Œ€๋กœ`)**: ๊ณต๋ฃก์ด ๋„ˆ๋ฌด ์ž‘์•„์ง€๊ฑฐ๋‚˜ ๊ตฌ์„์œผ๋กœ ์ด๋™ํ–ˆ์„ ๋•Œ ํ•œ ๋ฒˆ์˜ ํ„ฐ์น˜๋กœ ์ฒ˜์Œ ์œ„์น˜ยทํฌ๊ธฐยท๋ฐฉํ–ฅ์œผ๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค. ### ๐Ÿ“ธ ์‚ฌ์ง„ ์ดฌ์˜ ๋ฐ ๊ธฐ๊ธฐ ์ €์žฅ (์„œ๋ฒ„ ์—…๋กœ๋“œ ์—†์Œ) - ํ™”๋ฉด ํ•˜๋‹จ ์ค‘์•™์˜ ํฐ **`๐Ÿ“ธ ์ฐฐ์นต!`** ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์นด๋ฉ”๋ผ ์˜์ƒ(๋˜๋Š” ๊ต์‹ค ๋ฐฐ๊ฒฝ)๊ณผ 3D ๊ณต๋ฃก(+๋ฐ”๋‹ฅ ๊ทธ๋ฆผ์ž)์„ ๊ณ ํ•ด์ƒ๋„ ์บ”๋ฒ„์Šค์— ํ•ฉ์„ฑํ•ฉ๋‹ˆ๋‹ค. - **UI ๋ฒ„ํŠผ ๋ฐ ์ดˆ๋ก์ƒ‰ ๋ฐ”๋‹ฅ ๋ฐฐ์น˜ ๊ฐ€์ด๋“œ ๋ง์€ ์‚ฌ์ง„์— ์ ˆ๋Œ€ ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** - `object-fit: cover` ๋น„์œจ ๊ณ„์‚ฐ(`computeCoverCrop`)๊ณผ ์ „๋ฉด ์นด๋ฉ”๋ผ ์ขŒ์šฐ ๋ฐ˜์ „ ๋ณด์ •์„ ํ†ตํ•ด ํ™”๋ฉด์—์„œ ๋ณด๋˜ ๋น„์œจยท์œ„์น˜ ๊ทธ๋Œ€๋กœ ์™œ๊ณก ์—†์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. - ์ดฌ์˜ ์งํ›„ **์‚ฌ์ง„ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ฐฝ**์—์„œ **`๐Ÿ’พ ์‚ฌ์ง„ ์ €์žฅํ•˜๊ธฐ`**(PNG ๋‹ค์šด๋กœ๋“œ), ๋ชจ๋ฐ”์ผ **`๐Ÿ“ค ๊ณต์œ ํ•˜๊ธฐ`**(Web Share API ์ง€์› ๊ธฐ๊ธฐ), **`๐Ÿ”„ ๋‹ค์‹œ ์ฐ๊ธฐ`**๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ๋ชจ๋“  ์˜์ƒ๊ณผ ์‚ฌ์ง„ ๋ฐ์ดํ„ฐ๋Š” **์‚ฌ์šฉ์ž ๊ธฐ๊ธฐ(๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ)์—์„œ๋งŒ ์ฒ˜๋ฆฌ**๋˜๋ฉฐ ์™ธ๋ถ€ ์„œ๋ฒ„๋กœ ์ „์†ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. --- ## 2. ๊ฐœ๋ฐœ ๋ฐ ์‹คํ–‰ ๋ฐฉ๋ฒ• ### ์‚ฌ์ „ ์ค€๋น„ - Node.js 18 ์ด์ƒ (๊ถŒ์žฅ: Node.js 20+) ### ํŒจํ‚ค์ง€ ์„ค์น˜ ๋ฐ ์‹คํ–‰ ```bash # 1. ์˜์กด์„ฑ ํŒจํ‚ค์ง€ ์„ค์น˜ npm install # 2. (์„ ํƒ) ์ž์ฒด ์ œ์ž‘ CC0 ๊ณต๋ฃก GLB 5์ข… ๋ฐ WAV ์šธ์Œ์†Œ๋ฆฌ 5์ข… ์žฌ์ƒ์„ฑ npm run generate:assets # 3. ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰ (๋กœ์ปฌ ๋ฐ ๋™์ผ ๋„คํŠธ์›Œํฌ ์ ‘์† ํ—ˆ์šฉ) npm run dev ``` - ์‹คํ–‰ ํ›„ ๋ธŒ๋ผ์šฐ์ €์—์„œ `http://localhost:5188` ์œผ๋กœ ์ ‘์†ํ•ฉ๋‹ˆ๋‹ค. ### ๋นŒ๋“œ ๋ฐ ํ…Œ์ŠคํŠธ ๋ช…๋ น์–ด ```bash # TypeScript ํƒ€์ž… ๊ฒ€์‚ฌ npm run typecheck # ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์‹คํ–‰ (Vitest) npm test # ํ”„๋กœ๋•์…˜ ์ •์  ์›น์‚ฌ์ดํŠธ ๋นŒ๋“œ (dist/ ํด๋” ์ƒ์„ฑ) npm run build # ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ ๋กœ์ปฌ ๋ฏธ๋ฆฌ๋ณด๊ธฐ npm run preview ``` --- ## 3. ๊ณต๋ฃก GLB ๋ชจ๋ธ ๋ฐ ์‚ฌ์šด๋“œ ๊ต์ฒด ๋ฐฉ๋ฒ• ์ด ํ”„๋กœ์ ํŠธ๋Š” ์™ธ๋ถ€ ๋””์ž์ด๋„ˆ๊ฐ€ ์ œ์ž‘ํ–ˆ๊ฑฐ๋‚˜ ๋ฌด๋ฃŒ ์—์…‹ ์‚ฌ์ดํŠธ์—์„œ ๋‹ค์šด๋กœ๋“œํ•œ `.glb` ํŒŒ์ผ๋กœ ์ฆ‰์‹œ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ### ๋ฐฉ๋ฒ• A: `public/models/` ํŒŒ์ผ ๊ต์ฒด (์˜๊ตฌ ์ ์šฉ) 1. ์ƒˆ๋กœ์šด 3D ๊ณต๋ฃก ๋ชจ๋ธ ํŒŒ์ผ(`.glb`)์„ `public/models/trex.glb` (๋˜๋Š” `triceratops.glb` ๋“ฑ) ๊ฒฝ๋กœ์— ๋ฎ์–ด์”๋‹ˆ๋‹ค. 2. `DinoManager`๊ฐ€ ๋ชจ๋ธ์„ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ **์ž๋™์œผ๋กœ ๋ฐ”์šด๋”ฉ ๋ฐ•์Šค๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ํฌ๊ธฐ๋ฅผ ์ •๊ทœํ™”ํ•˜๊ณ  ๋ฐœ๋ฐ”๋‹ฅ์„ ๋ฐ”๋‹ฅ ๊ทธ๋ฆผ์ž(`y = 0`)์— ๋งž์ถ”๋ฏ€๋กœ**, ๋ชจ๋ธ ์›์ ์ด๋‚˜ ์Šค์ผ€์ผ์ด ๋‹ฌ๋ผ๋„ ๋ณ„๋„ ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด ๋ฐ”๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. 3. ๋ชจ๋ธ ๋‚ด๋ถ€์— `Idle`, `Walk`, `Roar` ๋“ฑ์˜ glTF ์• ๋‹ˆ๋ฉ”์ด์…˜ ํด๋ฆฝ์ด ์žˆ์œผ๋ฉด ์ž๋™์œผ๋กœ ๋งค์นญํ•˜์—ฌ ์žฌ์ƒํ•˜๋ฉฐ, ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์—†๋Š” ์ •์  ๋ชจ๋ธ์ด๋ผ๋„ ๊ธฐ๋ณธ ํ˜ธํกยท๊ฑธ์Œ ๋ชจ์…˜์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. 4. ์ƒˆ๋กœ์šด ๊ณต๋ฃก ์ข…๋ฅ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด `src/config/dinosaurs.ts`์˜ `DINOSAUR_CATALOG` ๋ฐฐ์—ด์— ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ### ๋ฐฉ๋ฒ• B: ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์—์„œ ์ฆ‰์‹œ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ (ํ…Œ์ŠคํŠธ์šฉ) 1. ์•ฑ ์ƒ๋‹จ ์™ผ์ชฝ์˜ **`๐Ÿฆ– ํ‹ฐ๋ผ๋…ธ์‚ฌ์šฐ๋ฃจ์Šค โ–พ`** ๋ฒ„ํŠผ์„ ๋ˆ„๋ฆ…๋‹ˆ๋‹ค. 2. ํŒ์—… ํ•˜๋‹จ์˜ **`๐Ÿ“‚ ๋‚ด ๊ณต๋ฃก 3D ํŒŒ์ผ(.glb) ๋ถˆ๋Ÿฌ์˜ค๊ธฐ`** ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋‚ด ๊ธฐ๊ธฐ์— ์žˆ๋Š” `.glb` ๋˜๋Š” `.gltf` ํŒŒ์ผ์„ ์„ ํƒํ•˜๋ฉด ์ฆ‰์‹œ ํ™”๋ฉด์˜ ๊ณต๋ฃก์ด ๊ต์ฒด๋ฉ๋‹ˆ๋‹ค. ### ๋ชจ๋ธ ๋ฐ ์‚ฌ์šด๋“œ ๋ผ์ด์„ ์Šค / ์ถœ์ฒ˜ - **ํ‹ฐ๋ผ๋…ธ์‚ฌ์šฐ๋ฃจ์Šค (`public/models/trex.glb`)**: - ์ž‘ํ’ˆ/์ €์ž‘์ž: **"T. rex" by Bake3D** () - ๋ผ์ด์„ ์Šค: **CC BY 4.0** () โ€” ๋ฉ”์‹œยทํ…์Šค์ฒ˜ ์ตœ์ ํ™” ๋ฐ ํฌํšจ ๋ชจ์…˜ ์ ์šฉ - **ํŠธ๋ฆฌ์ผ€๋ผํ†ฑ์Šค, ๋ธŒ๋ผํ‚ค์˜ค์‚ฌ์šฐ๋ฃจ์Šค, ์Šคํ…Œ๊ณ ์‚ฌ์šฐ๋ฃจ์Šค, ๋ฒจ๋กœ์‹œ๋žฉํ„ฐ (`public/models/*.glb`)**: - ์›๋ณธ: **Quaternius, "Animated Dinosaur Pack"** () - ๋ผ์ด์„ ์Šค: **CC0 1.0 (ํผ๋ธ”๋ฆญ ๋„๋ฉ”์ธ)** โ€” ๊ณก๋ฉด ์„ธ๋ถ„ํ™”(Subdivision) ๋ฐ ํŒŒ์ถฉ๋ฅ˜ ๋น„๋Š˜ ์…ฐ์ด๋” ์ ์šฉ - **๊ณต๋ฃก ์šธ์Œ์†Œ๋ฆฌ (`public/sounds/trex.wav`, `*.mp3`)**: - `trex.wav`: **CC0 Deep Monster Roar by trazzz123** (OpenGameArt, **CC0 1.0**) - `*.mp3`: Freesound **CC0 1.0** ๋™๋ฌผ/๊ณต๋ฃก ํšจ๊ณผ์Œ ๊ฐ€๊ณต๋ณธ (`JarredGibb`, `D.jones`, `Breviceps`) --- ## 4. ๊ธฐ๊ธฐ๋ณ„ ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ• ### ๐Ÿ’ป PC ์›น์บ  ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ• 1. `npm run dev` ์‹คํ–‰ ํ›„ Chrome ๋˜๋Š” Edge์—์„œ `http://localhost:5173`์— ์ ‘์†ํ•ฉ๋‹ˆ๋‹ค. 2. ๋ธŒ๋ผ์šฐ์ € ์ƒ๋‹จ ์นด๋ฉ”๋ผ ๊ถŒํ•œ ํŒ์—…์—์„œ **[ํ—ˆ์šฉ]**์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. 3. ์›น์บ ์ด ์—†๋Š” ๋ฐ์Šคํฌํ†ฑ PC๋ผ๋ฉด ์ž๋™์œผ๋กœ **๊ต์‹ค ๋ฐฐ๊ฒฝ ๋ชจ๋“œ**๊ฐ€ ์ผœ์ง€๋ฉฐ, ์–ธ์ œ๋“  ์ƒ๋‹จ `๐Ÿซ ๊ต์‹ค๋ฐฐ๊ฒฝ / ๐Ÿ“ท ์นด๋ฉ”๋ผ์ผœ๊ธฐ` ๋ฒ„ํŠผ์œผ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 4. ๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ(์ด๋™), ๋งˆ์šฐ์Šค ํœ (ํฌ๊ธฐ ์กฐ์ ˆ), ํ•˜๋‹จ ๋ฒ„ํŠผ(ํšŒ์ „ยท์šธ์Œ์†Œ๋ฆฌยท๊ฑท๊ธฐยท์ฐฐ์นต)์„ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. ### ๐Ÿ“ฑ Android ํƒœ๋ธ”๋ฆฟ ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ• (Chrome ๊ถŒ์žฅ) - Android Chrome์—์„œ ์นด๋ฉ”๋ผ(`getUserMedia`)๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ **`localhost`** ๋˜๋Š” **`HTTPS` ๋ณด์•ˆ ์—ฐ๊ฒฐ**๋กœ ์ ‘์†ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. - ์•„๋ž˜ **5๋ฒˆ(HTTPS๋ฅผ ์ด์šฉํ•œ ๋ชจ๋ฐ”์ผ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ตฌ์„ฑ)** ๋ฐฉ๋ฒ•์œผ๋กœ ์ ‘์†ํ•œ ๋’ค: 1. ํ›„๋ฉด ์นด๋ฉ”๋ผ๋กœ ๊ต์‹ค ๋ฐ”๋‹ฅ์ด๋‚˜ ์ฑ…์ƒ์„ ๋น„์ถฅ๋‹ˆ๋‹ค. 2. ํ•œ ์†๊ฐ€๋ฝ์œผ๋กœ ๊ณต๋ฃก์„ ๋Œ์–ด์„œ ์›ํ•˜๋Š” ์œ„์น˜์— ๋†“๊ณ , ๋‘ ์†๊ฐ€๋ฝ์„ ๋ฒŒ๋ ค ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•ฉ๋‹ˆ๋‹ค. 3. `๐Ÿ“ธ ์ฐฐ์นต!` ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์‚ฌ์ง„์„ ์ฐ๊ณ  `๐Ÿ’พ ์‚ฌ์ง„ ์ €์žฅํ•˜๊ธฐ` ๋˜๋Š” `๐Ÿ“ค ๊ณต์œ ํ•˜๊ธฐ`๋กœ ๊ฐค๋Ÿฌ๋ฆฌ์— ์ €์žฅ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ### ๐ŸŽ iPad Safari ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ• (iPadOS 15+ ๊ถŒ์žฅ) 1. iPad Safari์—์„œ HTTPS ์ฃผ์†Œ๋กœ ์ ‘์†ํ•œ ๋’ค ์นด๋ฉ”๋ผ ๊ถŒํ•œ ์š”์ฒญ ์‹œ **[ํ—ˆ์šฉ]**์„ ํƒญํ•ฉ๋‹ˆ๋‹ค. 2. ๋น„๋””์˜ค๊ฐ€ ์ „์ฒด ํ™”๋ฉด์— ์ž๋™ ์žฌ์ƒ(`playsinline`, `muted`)๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. 3. ์‚ฌ์ง„์„ ์ฐ์€ ํ›„ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ฐฝ์—์„œ **`๐Ÿ“ค ๊ณต์œ ํ•˜๊ธฐ` -> `์ด๋ฏธ์ง€ ์ €์žฅ`**(์‚ฌ์ง„ ์•ฑ์— ๋ฐ”๋กœ ์ €์žฅ) ๋˜๋Š” **`๐Ÿ’พ ์‚ฌ์ง„ ์ €์žฅํ•˜๊ธฐ`**(ํŒŒ์ผ ์•ฑ ๋‹ค์šด๋กœ๋“œ)๊ฐ€ ์ •์ƒ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ### ๐Ÿ’ป Chromebook ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ• 1. Chromebook ๋‚ด์žฅ Chrome ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฐฐํฌ๋œ HTTPS ์ฃผ์†Œ(๋˜๋Š” ๋กœ์ปฌ ์‹คํ–‰ ์‹œ `http://localhost:5173`)๋กœ ์ ‘์†ํ•ฉ๋‹ˆ๋‹ค. 2. ํ„ฐ์น˜์Šคํฌ๋ฆฐ์ด ์žˆ๋Š” ํฌ๋กฌ๋ถ์€ ํƒœ๋ธ”๋ฆฟ๊ณผ ๋™์ผํ•˜๊ฒŒ ์†๊ฐ€๋ฝ ํ•€์น˜ ์คŒยท๋“œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํŠธ๋ž™ํŒจ๋“œ/๋งˆ์šฐ์Šค๋กœ๋„ ๋™์ผํ•˜๊ฒŒ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 3. ํ‚ค๋ณด๋“œ ๋ฐฉํ–ฅํ‚ค/์ „ํ™˜ ์‹œ ํ™”๋ฉด ๋น„์œจ์ด ๋ฐ”๋€” ๋•Œ ๊ณต๋ฃก๊ณผ ์นด๋ฉ”๋ผ ํ™”๋ฉด์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฆฌ์‚ฌ์ด์ฆˆ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. --- ## 5. HTTPS๋ฅผ ์ด์šฉํ•œ ๋ชจ๋ฐ”์ผ(ํƒœ๋ธ”๋ฆฟ) ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ตฌ์„ฑ ๊ต์‹ค์˜ Android ํƒœ๋ธ”๋ฆฟ์ด๋‚˜ iPad์—์„œ ๊ฐœ๋ฐœ PC์˜ ์„œ๋ฒ„์— ์ ‘์†ํ•ด ์นด๋ฉ”๋ผ๋ฅผ ์ผœ๋ ค๋ฉด **HTTPS ๋ณด์•ˆ ์ปจํ…์ŠคํŠธ**๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค (`http://192.168.x.x:5173` ํ˜•ํƒœ๋Š” ๋ธŒ๋ผ์šฐ์ € ๋ณด์•ˆ ์ •์ฑ…์ƒ ์นด๋ฉ”๋ผ๊ฐ€ ์ฐจ๋‹จ๋จ). ### ๋ฐฉ๋ฒ• 1: Cloudflare Tunnel ๋˜๋Š” ngrok ์‚ฌ์šฉ (๊ฐ€์žฅ ๊ฐ„ํŽธ, ์ธ์ฆ์„œ ๊ฒฝ๊ณ  ์—†์Œ) ```bash # ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰ (ํฌํŠธ 5173) npm run dev # ์ƒˆ ํ„ฐ๋ฏธ๋„์—์„œ Cloudflare ๋ฌด๋ฃŒ ์ž„์‹œ HTTPS ํ„ฐ๋„ ์‹คํ–‰ npx cloudflared tunnel --url http://localhost:5173 ``` - ์ถœ๋ ฅ๋˜๋Š” `https://xxxx.trycloudflare.com` ์ฃผ์†Œ๋ฅผ ํƒœ๋ธ”๋ฆฟ ๋ธŒ๋ผ์šฐ์ €๋‚˜ QR ์ฝ”๋“œ๋กœ ์—ด๋ฉด ์ฆ‰์‹œ ํ›„๋ฉด ์นด๋ฉ”๋ผ๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ### ๋ฐฉ๋ฒ• 2: ์ •์  ํ˜ธ์ŠคํŒ… ๋ฌด๋ฃŒ ๋ฐฐํฌ (์ˆ˜์—… ํ˜„์žฅ์—์„œ ๊ฐ€์žฅ ์ถ”์ฒœ) ๋ฐฑ์—”๋“œ๊ฐ€ ์—†๋Š” ์ˆœ์ˆ˜ ์ •์  ์›น์‚ฌ์ดํŠธ์ด๋ฏ€๋กœ `npm run build` ํ›„ ์ƒ์„ฑ๋œ `dist/` ํด๋”๋ฅผ ์•„๋ž˜ ๋ฌด๋ฃŒ HTTPS ํ˜ธ์ŠคํŒ…์— ์˜ฌ๋ฆฌ๋ฉด ๊ต์‹ค ๋ชจ๋“  ํƒœ๋ธ”๋ฆฟ์—์„œ ๋ฐ”๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: - **GitHub Pages**, **Cloudflare Pages**, **Vercel**, **Netlify** ### ๋ฐฉ๋ฒ• 3: USB ์ผ€์ด๋ธ” ํฌํŠธ ํฌ์›Œ๋”ฉ (Android ํƒœ๋ธ”๋ฆฟ ์ „์šฉ) - Android ํƒœ๋ธ”๋ฆฟ์„ PC์— USB๋กœ ์—ฐ๊ฒฐํ•˜๊ณ  Chrome ์ฃผ์†Œ์ฐฝ์— `chrome://inspect/#devices`๋ฅผ ์—ด์–ด **`Port forwarding` (`5173 -> localhost:5173`)**์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด, ํƒœ๋ธ”๋ฆฟ์—์„œ๋„ `http://localhost:5173`์œผ๋กœ ์นด๋ฉ”๋ผ ๊ถŒํ•œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- ## 6. ํ˜„์žฌ ๊ตฌํ˜„๋œ ๊ธฐ๋Šฅ๊ณผ ์•Œ๋ ค์ง„ ์ œ์•ฝ ### ๊ตฌํ˜„ ์™„๋ฃŒ ํ•ญ๋ชฉ - [x] Vite + TypeScript + Three.js ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„ - [x] PC ์›น์บ  ๋ฐ ํƒœ๋ธ”๋ฆฟ ํ›„๋ฉด ์นด๋ฉ”๋ผ ์šฐ์„  ์—ฐ๊ฒฐ + ์ „/ํ›„๋ฉด ์นด๋ฉ”๋ผ ์ „ํ™˜ - [x] ์นด๋ฉ”๋ผ ๋ฏธ์—ฐ๊ฒฐ/๊ถŒํ•œ ๊ฑฐ๋ถ€ ์‹œ ํ•œ๊ตญ์–ด ์•ˆ๋‚ด ๋ฐ **1ํ•™๋…„ ๊ต์‹ค ์ผ๋Ÿฌ์ŠคํŠธ ๋ฐฐ๊ฒฝ ๋ชจ๋“œ** ์ œ๊ณต - [x] ํ‹ฐ๋ผ๋…ธ์‚ฌ์šฐ๋ฃจ์Šค(๊ธฐ๋ณธ) ํฌํ•จ 5์ข…์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋‚ด์žฅ GLB ๋ชจ๋ธ ๋ฐ ๋กœ์ปฌ `.glb` ํŒŒ์ผ ์ฆ‰์‹œ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๊ธฐ๋Šฅ - [x] ์ž์—ฐ์Šค๋Ÿฌ์šด ์กฐ๋ช…๊ณผ ๋ฐ”๋‹ฅ ๊ทธ๋ฆผ์ž(Shadow Catcher) - [x] ๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ/ํœ  ๋ฐ ํ„ฐ์น˜ ํ•œ ์†๊ฐ€๋ฝ ์ด๋™/๋‘ ์†๊ฐ€๋ฝ ํ•€์น˜ ์คŒยทํšŒ์ „ ์กฐ์ž‘ - [x] ๊ณต๋ฃก ์šธ์Œ์†Œ๋ฆฌ ์žฌ์ƒ ๋ฐ ์Œ์†Œ๊ฑฐ ํ† ๊ธ€ - [x] UI๋ฅผ ์ œ์™ธํ•œ ๊ณ ํ•ด์ƒ๋„ ์นด๋ฉ”๋ผ+3D ๊ณต๋ฃก ์‚ฌ์ง„ ํ•ฉ์„ฑ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ, ๋‹ค์‹œ ์ฐ๊ธฐ, PNG ์ €์žฅ ๋ฐ ๋ชจ๋ฐ”์ผ ๊ณต์œ  ### ์•Œ๋ ค์ง„ ์ œ์•ฝ - 1์ฐจ ๋ฒ„์ „์€ ๋ชจ๋“  ๊ธฐ๊ธฐ(PC, iPad, Chromebook, ๋ณด๊ธ‰ํ˜• Android ํƒœ๋ธ”๋ฆฟ)์—์„œ 100% ์ž‘๋™ํ•˜๋Š” **์นด๋ฉ”๋ผ ํ™”๋ฉด + 3D ๋ ˆ์ด์–ด ์‹ค์‹œ๊ฐ„ ํ•ฉ์„ฑ ๋ฐฉ์‹**์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํƒœ๋ธ”๋ฆฟ์„ ๋“ค๊ณ  ๊ฑธ์–ด ๋‹ค๋‹ ๋•Œ ์‹ค์ œ ๋ฌผ๋ฆฌ์  ๋ฐ”๋‹ฅ ์ขŒํ‘œ์— ๊ณต๋ฃก์ด ๊ณ ์ •(World-Tracking)๋˜์ง€๋Š” ์•Š์œผ๋ฉฐ, ํ™”๋ฉด ๋“œ๋ž˜๊ทธ์™€ ํ•€์น˜ ์คŒ์œผ๋กœ ๋ฐ”๋‹ฅ ์œ„์น˜์— ๋งž์ถฐ ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. - ๋ชจ๋ฐ”์ผ ๋ธŒ๋ผ์šฐ์ €์—์„œ `http://`(๋น„๋ณด์•ˆ ์—ฐ๊ฒฐ)๋กœ ๋กœ์ปฌ IP์— ์ ‘์†ํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ € ์ •์ฑ…์— ์˜ํ•ด ์นด๋ฉ”๋ผ ์ ‘๊ทผ์ด ์ฐจ๋‹จ๋˜๋ฏ€๋กœ, ์ด๋•Œ๋Š” ์ž๋™์œผ๋กœ ์•ˆ๋‚ด ๋ฐฐ๋„ˆ์™€ ํ•จ๊ป˜ **๊ต์‹ค ๋ฐฐ๊ฒฝ ๋ชจ๋“œ**๊ฐ€ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. --- ## 7. ํ–ฅํ›„ WebXR ๊ณต๊ฐ„ ์ธ์‹ AR ๊ฐœ๋ฐœ ๊ณ„ํš (2์ฐจ ํ™•์žฅ ๋กœ๋“œ๋งต) ํ”„๋กœ์ ํŠธ ๋‚ด `src/ar/WebXRManager.ts`์— WebXR ์ง€์› ๊ฐ์ง€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฉฐ, ํ–ฅํ›„ ๋‹ค์Œ ์ˆœ์„œ๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: 1. **WebXR `immersive-ar` + `hit-test` ์—ฐ๋™**: - Android Chrome(ARCore ์ง€์› ๊ธฐ๊ธฐ)์—์„œ `navigator.xr.requestSession('immersive-ar', { requiredFeatures: ['hit-test'] })` ์„ธ์…˜์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. - ๊ต์‹ค ์‹ค์ œ ๋ฐ”๋‹ฅ ํ‰๋ฉด์„ ์ธ์‹ํ•ด ๋ ˆํ‹ฐํด(๋ฐ”๋‹ฅ ์กฐ์ค€์ )์„ ํ‘œ์‹œํ•˜๊ณ , ํ™”๋ฉด์„ ํƒญํ•˜๋ฉด ํ•ด๋‹น 3D ์›”๋“œ ์ขŒํ‘œ์— ๊ณต๋ฃก์„ ๊ณ ์ • ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. 2. **๊ธฐ๊ธฐ๋ณ„ ์ž๋™ ํด๋ฐฑ ์•„ํ‚คํ…์ฒ˜ ์œ ์ง€**: - iPad Safari๋‚˜ Chromebook, PC์ฒ˜๋Ÿผ WebXR `immersive-ar`๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ธฐ๊ธฐ์—์„œ๋Š” ํ˜„์žฌ ๊ตฌํ˜„๋œ **๊ธฐ๋ณธ ์นด๋ฉ”๋ผ ํ•ฉ์„ฑ ๋ชจ๋“œ**๋กœ ์ž๋™ ์ž‘๋™ํ•˜๋„๋ก ์ด์›ํ™” ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. 3. **๋‹ค์ค‘ ๊ณต๋ฃก ๋ฐฐ์น˜ ๋ฐ PWA ์˜คํ”„๋ผ์ธ ์บ์‹ฑ**: - ํ•œ ํ™”๋ฉด์— ์นœ๊ตฌ๋“ค๊ณผ ์—ฌ๋Ÿฌ ๋งˆ๋ฆฌ์˜ ๊ณต๋ฃก์„ ๋™์‹œ์— ๋ฐฐ์น˜ํ•˜๋Š” ๊ธฐ๋Šฅ ๋ฐ Service Worker๋ฅผ ํ†ตํ•œ ์˜คํ”„๋ผ์ธ ์ˆ˜์—… ์ง€์›์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.