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:
2026-10-06 14:33:47 +09:00
parent 619d980098
commit 71c8d3b7ff
82 changed files with 1602 additions and 1103 deletions
+10 -6
View File
@@ -1,10 +1,11 @@
import * as THREE from 'three';
import { DepthProcessor } from './DepthProcessor';
import type { DepthProvider } from '../types/depth';
import type { AiDepthModel } from '../constants/depth';
type WorkerReply =
| { type: 'status'; id: number; message: string }
| { type: 'result'; id: number; width: number; height: number; values: ArrayBuffer }
| { type: 'result'; id: number; width: number; height: number; values: ArrayBuffer; normalizedValues: ArrayBuffer }
| { type: 'error'; id: number; message: string };
type PendingRequest = {
@@ -20,12 +21,12 @@ export class AiDepthProvider implements DepthProvider {
constructor(private readonly onStatus: (message: string) => void) {}
async getDepthMap(image: HTMLImageElement): Promise<THREE.Texture> {
async getDepthMap(image: HTMLImageElement, model: AiDepthModel = 'small'): Promise<THREE.Texture> {
if (this.pending) throw new Error('AI depth 추론이 이미 진행 중입니다.');
const id = ++this.requestId;
return new Promise<THREE.Texture>((resolve, reject) => {
this.pending = { id, resolve, reject };
void this.captureAndSend(image, id).catch((error: unknown) => {
void this.captureAndSend(image, id, model).catch((error: unknown) => {
this.fail(id, error instanceof Error ? error : new Error('AI depth 생성에 실패했습니다.'));
});
});
@@ -40,7 +41,7 @@ export class AiDepthProvider implements DepthProvider {
pending?.reject(new Error('AI depth 요청이 취소되었습니다.'));
}
private async captureAndSend(image: HTMLImageElement, id: number): Promise<void> {
private async captureAndSend(image: HTMLImageElement, id: number, model: AiDepthModel): Promise<void> {
const width = image.naturalWidth || image.width;
const height = image.naturalHeight || image.height;
if (!width || !height) throw new Error('사진 크기를 확인할 수 없습니다.');
@@ -56,7 +57,7 @@ export class AiDepthProvider implements DepthProvider {
}
const worker = this.ensureWorker();
try {
worker.postMessage({ type: 'infer', id, image: bitmap }, [bitmap]);
worker.postMessage({ type: 'infer', id, image: bitmap, model }, [bitmap]);
} catch (error) {
bitmap.close();
throw error;
@@ -75,7 +76,10 @@ export class AiDepthProvider implements DepthProvider {
const pending = this.pending;
this.pending = null;
try {
pending.resolve(DepthProcessor.fromNormalizedDepth(new Uint8Array(message.values), message.width, message.height));
const texture = DepthProcessor.fromNormalizedDepth(new Uint8Array(message.values), message.width, message.height);
// Keep unquantized normalized values for inspection; geometry still uses the existing byte texture.
texture.userData.normalizedDepth = new Float32Array(message.normalizedValues);
pending.resolve(texture);
} catch (error) {
pending.reject(error instanceof Error ? error : new Error('AI depth 결과를 읽지 못했습니다.'));
}