Pet Behind Glass
사진과 Depth Map으로 얕은 2.5D 장면을 만들고 그 렌더 결과를 유리 셰이더로 굴절시키는 브라우저 로컬 MVP입니다. Vite, TypeScript, Three.js, GLSL을 사용하며 별도 백엔드는 없습니다. 선택 사항인 AI depth 추론도 브라우저 안에서 실행합니다.
npm install
npm run dev
npm run build
샘플 반려동물 불러오기를 누르면 사용자가 제공한 사진과 수작업 Depth Map이 얼굴 확대 구도의 Final로 표시됩니다. 사진 확대·가로 위치·세로 위치를 조절하거나 사진 구도 초기화로 원래 전체 구도로 돌아갈 수 있습니다. 일반 사진/영상 업로드는 전체 구도로 시작합니다. Mosaic 스타일에서 조각 유리(유리 가로 10칸, 강도 0.90)와 촘촘 유리(28칸, 강도 0.85)를 비교하세요. 셀마다 이미지 위치·확대율이 달라지며 검은 격자선과 원형 물결은 제거했습니다. Grid Size는 6~96으로 조절할 수 있습니다. No Glass는 깊이 시차를 확인하는 모드입니다. 직접 사용할 때는 사진 또는 영상 다음에 같은 종횡비의 Depth 이미지를 선택합니다. 새 RGB 미디어는 flat depth로 시작합니다.
사진을 불러온 뒤 AI 깊이 생성을 누르면 Depth Anything V2 Small이 로컬에서 상대 깊이를 계산합니다. 처음 실행할 때 모델 파일을 Hugging Face에서 내려받습니다. 사진 데이터는 추론을 위해 브라우저 밖으로 전송하지 않습니다. 결과는 AI 추정으로 표시되고 No Glass 모드로 전환됩니다. 영상에서는 이 버튼을 사용할 수 없습니다. 자세한 출처와 Playwright smoke 실행법은 AI depth 안내를 참조하세요.
Mosaic의 셀 굴곡으로 얕은 곡면을 조절하고, 광택 강도, 조명 가로, 조명 세로로 유리 표면의 반사를 조절할 수 있습니다. 하나의 공통 광원과 셀별 표면 방향으로 반사를 계산하며, 카메라 이동에도 반응합니다. 광택 0은 표면 반사만 끄고 곡면 굴절을 유지하며 Distortion 0에서는 광택도 꺼집니다. 사진 리라이팅은 MVP 범위에서 제외합니다. 조명 깊이는 고정이며 직사각형 광원을 향하는 반사 시선으로 창 모양을 근사합니다. 실제 환경맵이나 유리 내부 다중 반사는 없습니다.
변경된 구조
QA 개선으로 Reeded/Frosted도 활성 효과의 출력을 유리판 안으로 제한합니다. 파일 선택은 Tab과 Enter로 접근할 수 있으며, 샘플의 수작업 Depth 안내는 로딩 이후에도 유지됩니다. 굴곡 +0.65 초과 구간은 높이 증가폭을 완만하게 압축해 강한 볼록의 과도한 이동을 소폭 줄였습니다. 기본값과 음수 구간은 유지합니다.
셀 굴곡은 −1 오목 / 0 평탄 / +1 볼록으로 조절합니다. 양수는 관찰자 쪽으로 솟고 음수는 사진 쪽으로 들어가는 방향이며 기본값은 +0.65입니다. 0에서도 셀별 기울기와 조각별 확대·이동은 유지됩니다. 실제 유리 메시를 변형하는 대신 부호가 있는 높이함수의 법선으로 굴절과 반사를 함께 근사합니다.
PetDepthMesh: 128×128 세그먼트, 정점 Z를(depth-bias)*scale로 이동. 규칙은 0=뒤, 1=앞, 기본 scale 0.25, 상한 0.4입니다.- 실제 PerspectiveCamera가 보간 이동하여 코·눈·몸 사이의 시차를 만듭니다. Camera Offset 상한 0.6, camera z=3입니다.
- Final은
content scene → WebGLRenderTarget → fullscreen glass scene의 2-pass 구조입니다. DPR 상한은 1.5이며 RT는 선형 색상, 화면 출력에서 색공간을 변환합니다. - Mosaic는 월드 유리판 기준 셀별 위치·축별 배율·미세 회전과 5개 주변 샘플을 사용합니다. 중앙이 비교적 평탄한 사각 곡면에 셀별 고정 비대칭을 주고, 같은 법선으로 굴절과 창 모양 반사를 계산합니다. 주 기준은 레퍼런스 2번입니다. 조각 유리는 변화가 작은 셀과 확대·압축 셀을 섞어 특징점과 넓은 색면이 공존하도록 하고, 촘촘 유리는 기존 설정을 유지합니다. 입력은
uSceneTexture이며 기존 Depth/RT 파이프라인과 Reeded/Frosted는 유지합니다. 활성 Mosaic에서 유리판 밖은 배경색으로 가려 외곽을 일정하게 유지합니다. Distortion 0 및 No Glass는 진단용 전체 장면을 표시하므로 확대된 사진이 유리판 밖까지 보일 수 있습니다. - View Mode는 Final, RGB(평면 원본), Depth(평면 지도), No Glass(깊이 메시), Glass Only(배경 위 유리 진단)입니다. Depth Scale, Grid Size, Distortion, Camera Offset, View Sensitivity를 조절할 수 있습니다.
주요 파일
- 수정:
src/main.ts,src/input/CameraController.ts, 기존 Glass fragment 3개,index.html,src/style.css,AGENTS.md. - 신규:
src/objects/PetDepthMesh.ts,src/depth/DepthMapLoader.ts,DepthProcessor.ts,StaticDepthProvider.ts,DepthDebug.ts,src/types/depth.ts. - 신규 셰이더:
src/shaders/petDepth.vert,petDepth.frag,glassScreen.vert. - 자산:
public/assets/sample-pet.png,sample-pet-depth.png,sample-pet-depth.json. 재생성은scripts/create-sample-depth.ps1. - 명세와 검증:
docs/depth-task-brief.txt,depth-implementation-plan.md,depth-validation.md. 기존 효과는docs/baseline-shaders/에 비교용으로 보존했습니다.
확인 결과와 한계
TypeScript 검사와 production build를 통과했습니다. 사용자 사진으로 Glass OFF 시차를 먼저 검증한 뒤 Glass를 연결했습니다. 브라우저에서 세 효과, RGB/Depth 업로드, 비율 오류, 강도 0 Final/No Glass 정렬·색상, 390px viewport의 가로 넘침을 확인했습니다. 상세 진단은 검증 기록을 참조하세요.
테스트 Depth는 수작업 가상 깊이이며 AI 추정·실측 결과가 아닙니다. 보이지 않는 측면을 복원하지 않으므로 큰 이동에서는 사진이 늘어질 수 있습니다. 진단 좌표는 깊이 데이터와 카메라의 투영값으로, GPU 삼각형 보간과 작은 차이가 있을 수 있으며 화면 특징점 추적값은 아닙니다.
기존 VideoTexture와 flat/static depth 경로는 유지했습니다. 실제 영상 파일의 재생·loop, 실기기 gyro 및 60fps 성능 측정은 이번 브라우저 검증에서 수행하지 않았습니다. 요청 경쟁·미디어 수명·센서 경로는 코드 검토했습니다.
AI 추정은 AiDepthProvider와 별도 module worker로 연결했습니다. Depth Anything V2 Small의 상대 깊이는 실제 측정값이 아니며, 보이지 않는 측면이나 가려진 영역을 복원하지 않습니다. 실시간 영상 depth 추정과 완전한 3D 복원은 현재 범위가 아닙니다.