Files
behind_glass/docs/qa-ai-depth-base-2026-10-06/report.md
T
horoli 71c8d3b7ff Implement patterned glass and maximum-depth distance controls
Add gobang surface refraction and shared photo/depth distance adjustment. Compare V2 Small and Base at input 770 with maximum-depth masks and pixel diagnostics. Record browser QA and update runtime dependencies and model notices.
2026-10-06 14:33:47 +09:00

75 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# V2 Base 770 / 최대 깊이 표면 기준 거리 검증
2026-10-06. 요청: Base로 depth=1 영역이 앞쪽 부위를 명확하게 추정하는지 확인하고, 그 최대 깊이 표면을 유리와 피사체 거리 기준으로 사용한다.
## 구현
- `개발 비교 → AI 깊이 모델`에서 Small/Base 선택 후 기존 `AI 깊이 생성` 버튼으로 추론한다. 두 모델 모두 입력 770, 종횡비/14 배수 정렬, 스냅샷 긴 변 상한 1024를 공유한다. 기본값 Small, Base는 비상업적 테스트 옵션이다. 새 의존성 없음.
- 단일 worker estimator를 유지하고 다른 모델을 선택해 추론할 때 이전 estimator를 dispose한다. 기존 WebGPU 우선/WASM fallback을 유지한다.
- 기존 8비트 텍스처와 128×128 Depth mesh를 유지한다. 양자화 이전 정규화 Float32 값은 진단용으로 함께 전달한다.
- `최대 깊이 영역 확인`은 원본 사진 위에 Float32 최대 1(분홍), 8비트 255/255(청록), Float32 ≥0.99(노랑)를 표시한다. 픽셀 수/비율/첫 최대 좌표와 선택 지점 값을 표시한다. 사진 클릭 또는 X/Y 숫자 입력으로 검사한다.
- 기존 `contentBaseZ`/`applyFraming`을 사용한다. 거리 도움말을 최대 depth 표면 기준으로 명시하고 진단에 최대 표면/선택 지점 간격을 추가했다. RGB/Depth 공통 변환, 굴절 기준 평면, 프레임 가림을 함께 갱신한다. 자동 확대/팬 변경 없음.
## 같은 사진의 실제 추론 결과
원본 `public/assets/qa/dog1.jpeg`는 400×500이다. 입력 770은 이전 전처리 검증에서 실제 텐서 `[1,3,770,616]`으로 확인했으며 이번에도 같은 전처리 설정을 사용한다. 반환 깊이는 스냅샷 400×500으로 보간된다. 좌표는 좌상단 원점, X 오른쪽/Y 아래쪽이다. 지점은 원본을 보고 수동으로 고른 비교 좌표이며 모델의 의미적 코/눈 검출 결과가 아니다.
| 항목 | Small 770 | Base 770 |
|---|---:|---:|
| 정규화 Float32 최대=1 | 1px | 1px |
| 8비트 depth=1 | 24px | 26px |
| 정규화 depth≥0.99 | 153px | 126px |
| 최대 좌표 | (210,235) | (209,236) |
| 코 중앙 부근 (207,239) | 0.992057 | 0.996319 |
| 코 위쪽 (210,235) | 1.000000 | 0.999133 |
| 이마 (210,175) | 0.942435 | 0.958692 |
| 왼눈 (181,210) | 0.845839 | 0.854450 |
| 오른눈 (236,218) | 0.834167 | 0.847300 |
| 주둥이 (190,240) | 0.958051 | 0.963951 |
| 혀 (204,267) | 0.909496 | 0.881356 |
| 몸 (270,320) | 0.579217 | 0.616040 |
| 앞발 (183,414) | 0.481518 | 0.506277 |
두 모델 모두 최대 좌표는 원본 사진의 코 주변에 위치한다. Base의 ≥0.99 영역은 더 작지만 8비트 최대 영역은 약간 더 크다. 이것만으로 Base가 실제 형상을 더 정확하게 복원했다고 판정할 수 없다. 코와 이마/눈 사이의 값 차이는 이미 Small에도 존재했고, 흑백 화면에서는 모두 밝아 읽기 어려웠다. Base Depth 화면도 부드러운 형태이며 얼굴 내부 굴곡이 크게 개선되었다고 단정하지 않는다.
각 사진/모델별 정규화 기준이 다르므로 표의 수치를 모델 간 실제 거리 차이처럼 해석하지 않는다. Float32 최대 1은 비상수 예측을 min/max 정규화하면 항상 만들어진다. 이번 코 위치 결과는 한 사진의 검증이며 다른 사진의 최대값이 항상 코라는 보장은 없다. 정규화는 전체 사진을 대상으로 하고 피사체 마스크나 이상값 제거는 하지 않는다.
수치 원본: [Small](small-values.json), [Base](base-values.json). 동일 뷰/설정의 화면: [Small](small-inspection.png), [Base](base-inspection.png). 최대 영역은 진단 색상만 적용하며 실제 깊이값을 강조/변경하지 않는다.
## 거리 기준
```
baseZ = glassZ - requestedGap - (maxDepth - depthBias) * depthScale
surfaceZ(pixel) = baseZ + (byteDepth(pixel) - depthBias) * depthScale
gap(pixel) = requestedGap + (maxDepth - byteDepth(pixel)) * depthScale
```
Base 최대 픽셀 (209,236)의 byteDepth는 1. depthScale=0.25에서 검사:
| UI 거리 | 최대 표면 간격 | 이마 간격 | 이마의 상대적 후퇴 |
|---|---:|---:|---:|
| 0% | 0.0400 | 0.0508 | 0.0108 |
| 50% | 0.3200 | 0.3308 (같은 식) | 0.0108 |
| 100% | 0.6000 | 0.6108 | 0.0108 |
최대 픽셀의 0/50/100%, 이마 100%는 실제 UI 진단에서 읽었다. 이마 0%는 동일 위치 Base 수치 JSON에 기록돼 있다. 이마 50%는 수식 계산값이다. 거리와 깊이 차이는 장면 단위이며 cm가 아니다. `≥0.99`는 영역 가시화용이고 배치 기준은 항상 최대값이므로 가까운 표면의 관통을 막는다.
진단 간격은 텍스처 픽셀의 계산값이다. 128×128 mesh의 버텍스 샘플/삼각형 보간이 최대 픽셀을 정확히 통과하지 않을 수 있으므로 실제 mesh 최소 간격은 요청값보다 클 수 있다. 선형 텍스처 보간과 mesh 보간이 원본 최대값보다 더 앞선 값을 생성하지는 않으므로 전체 표면 기준 안전 여유는 유지된다.
[거리 수치](distance-values.json). No Glass [근접](base-noglass-near.png), [드래그](base-noglass-near-drag.png), [먼 거리](base-noglass-far.png). No Glass에서 RGB와 깊이 형상 및 시점에 따른 변화가 렌더링되는 것을 확인한 뒤 [Final 50%](base-final-mid.png)를 확인했다. 픽셀별 GPU projected 좌표/실제 측정 3D 정답과의 오차는 이번 테스트에서 측정하지 않았다.
Base 재추론은 같은 최대 좌표/픽셀 수를 반환했고 거리 50%, 수동 zoom=1/pan=0/0을 유지했다. [재추론 후 설정](after-reinference.json).
## 실행 검증과 한계
- `npm.cmd run build -- --outDir test-results/base-depth-build`: TypeScript/Vite 빌드 통과. 기존 큰 chunk 경고만 있었다. 생성한 임시 빌드 결과는 정리했다.
- `node --experimental-strip-types scripts/test-depth-refraction.mjs`: 통과.
- `node --experimental-strip-types scripts/test-window-reveal-coverage.mjs`: 통과. 두 거리/세 깊이 스케일/두 종횡비/17 시점의 프레임 가림 검사 포함.
- Node 22.13에서 옵션 없이 테스트를 실행한 첫 시도는 `.ts` 확장자 로딩 오류였다. TypeScript strip 옵션으로 재실행해 통과했다.
- 실제 브라우저에서 Small/Base 모두 추론 완료. Base는 첫 다운로드 후 같은 estimator로 재추론도 확인했다. 콘솔 error 0건. 강제 WASM-only/실제 모바일 GPU 추론 시간/메모리는 측정하지 않았다.
- 모바일 390×844에서 문서 너비 375, 가로 넘침 없음. [모바일 진단](mobile-inspection.png). 임시 viewport는 원복했다.
- 기본 뷰포트의 미리보기는 Base 770, Depth, 거리 0%, 최대 지점 선택 상태로 남겼다. [최종 화면](base-result.png).
- 원본이 400×500이므로 770 입력이 원본에 없는 디테일을 보장하지 않는다. 더 나은 모델/더 높은 입력에서도 코의 실제 돌출 길이 복원을 보장할 수 없다.
후속 판단: 현재 최대 깊이 표면 기준 거리 방식은 사용자 의도와 일치한다. 이 사진에서는 Base와 Small 모두 코 주변이 최대이므로 Base 교체만으로 거리 기준 문제가 해결됐다고 설명하지 않는다. 향후 여러 사진에서 최대 위치가 피사체가 아닌 배경/노이즈로 이동하는지 확인한 뒤 피사체 범위 제한이나 이상값 처리를 별도로 판단한다.