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.
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
# 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 교체만으로 거리 기준 문제가 해결됐다고 설명하지 않는다. 향후 여러 사진에서 최대 위치가 피사체가 아닌 배경/노이즈로 이동하는지 확인한 뒤 피사체 범위 제한이나 이상값 처리를 별도로 판단한다.
|
||||
Reference in New Issue
Block a user