layershift 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +14 -0
  2. package/dist/components/layershift.js +1783 -654
  3. package/dist/npm/layershift.es.js +5154 -2569
  4. package/dist/types/components/layershift/layershift-element.d.ts +2 -1
  5. package/dist/types/components/layershift/layershift-element.d.ts.map +1 -1
  6. package/dist/types/components/layershift/portal-element.d.ts +2 -1
  7. package/dist/types/components/layershift/portal-element.d.ts.map +1 -1
  8. package/dist/types/components/layershift/types.d.ts +8 -0
  9. package/dist/types/components/layershift/types.d.ts.map +1 -1
  10. package/dist/types/gpu-backend.d.ts +37 -0
  11. package/dist/types/gpu-backend.d.ts.map +1 -0
  12. package/dist/types/jfa-distance-field.d.ts +78 -0
  13. package/dist/types/jfa-distance-field.d.ts.map +1 -0
  14. package/dist/types/parallax-renderer-webgpu.d.ts +103 -0
  15. package/dist/types/parallax-renderer-webgpu.d.ts.map +1 -0
  16. package/dist/types/parallax-renderer.d.ts +54 -91
  17. package/dist/types/parallax-renderer.d.ts.map +1 -1
  18. package/dist/types/portal-renderer-webgpu.d.ts +199 -0
  19. package/dist/types/portal-renderer-webgpu.d.ts.map +1 -0
  20. package/dist/types/portal-renderer.d.ts +63 -65
  21. package/dist/types/portal-renderer.d.ts.map +1 -1
  22. package/dist/types/precomputed-depth.d.ts +9 -51
  23. package/dist/types/precomputed-depth.d.ts.map +1 -1
  24. package/dist/types/quality.d.ts +95 -0
  25. package/dist/types/quality.d.ts.map +1 -0
  26. package/dist/types/render-pass-webgpu.d.ts +76 -0
  27. package/dist/types/render-pass-webgpu.d.ts.map +1 -0
  28. package/dist/types/render-pass.d.ts +171 -0
  29. package/dist/types/render-pass.d.ts.map +1 -0
  30. package/dist/types/renderer-base.d.ts +124 -0
  31. package/dist/types/renderer-base.d.ts.map +1 -0
  32. package/dist/types/webgl-utils.d.ts +29 -0
  33. package/dist/types/webgl-utils.d.ts.map +1 -0
  34. package/dist/types/webgpu-utils.d.ts +42 -0
  35. package/dist/types/webgpu-utils.d.ts.map +1 -0
  36. package/package.json +24 -4
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Portal Renderer (WebGPU) — GPU-accelerated multi-pass portal compositing.
3
+ *
4
+ * WebGPU counterpart to `portal-renderer.ts` (WebGL2). Shares the same
5
+ * `RendererBase` abstract base class and `PortalRendererConfig` interface.
6
+ *
7
+ * ## Pipeline (per frame, 6 draw calls)
8
+ *
9
+ * 1. **Interior pass** — POM ray-march + lens depth + DOF + fog + color grade.
10
+ * MRT output: color (rgba8unorm) + depth (r8unorm) to offscreen textures.
11
+ *
12
+ * 2a. **Stencil mark** — triangulated SVG mesh into depth-stencil attachment.
13
+ * Color writes disabled, stencil ref=1 written.
14
+ *
15
+ * 2b. **Composite** — emissive interior passthrough with edge occlusion ramp,
16
+ * stencil-tested (only where stencil == 1).
17
+ *
18
+ * 2c. **Chamfer geometry** — Blinn-Phong lit ring with frosted-glass blur.
19
+ *
20
+ * 3. **Boundary effects** — rim lighting, refraction, chromatic fringe,
21
+ * volumetric edge wall. Alpha blended onto backbuffer.
22
+ *
23
+ * ## JFA Distance Field (cached, recomputed on resize)
24
+ *
25
+ * mask render -> seed extraction -> flood iterations -> distance conversion.
26
+ * Uses rg16float ping-pong textures. Runs at reduced resolution (quality tier).
27
+ *
28
+ * ## Key WebGPU differences from WebGL2 version
29
+ *
30
+ * - Stencil via explicit `depth24plus-stencil8` texture attachment.
31
+ * - MRT via multiple color attachments in a single render pass.
32
+ * - Float render targets (rg16float) natively supported — no extension needed.
33
+ * - Pipeline state objects bake blend/stencil/depth config at creation time.
34
+ * - Bind groups replace individual uniform calls.
35
+ * - Override constants for POM loop bound.
36
+ * - `writeTexture` with manual Y-flip (no UNPACK_FLIP_Y_WEBGL equivalent).
37
+ * - `copyExternalImageToTexture` for zero-copy video frame import.
38
+ */
39
+ import { RendererBase } from './renderer-base';
40
+ import type { PortalRendererConfig } from './portal-renderer';
41
+ import type { ShapeMesh } from './shape-generator';
42
+ export declare class PortalRendererWebGPU extends RendererBase {
43
+ private device;
44
+ private context;
45
+ private canvasFormat;
46
+ private readonly config;
47
+ private quadBuffer;
48
+ private linearSampler;
49
+ private nearestSampler;
50
+ private interiorPipeline;
51
+ private interiorBindGroupLayout;
52
+ private stencilMarkPipeline;
53
+ private stencilMarkBindGroupLayout;
54
+ private compositePipeline;
55
+ private compositeBindGroupLayout;
56
+ private chamferPipeline;
57
+ private chamferBindGroupLayout;
58
+ private boundaryPipeline;
59
+ private boundaryBindGroupLayout;
60
+ private maskPipeline;
61
+ private maskBindGroupLayout;
62
+ private jfaSeedPipeline;
63
+ private jfaSeedBindGroupLayout;
64
+ private jfaFloodPipeline;
65
+ private jfaFloodBindGroupLayout;
66
+ private jfaDistPipeline;
67
+ private jfaDistBindGroupLayout;
68
+ private meshScaleUniformBuffer;
69
+ private interiorVertexUniformBuffer;
70
+ private interiorFragmentUniformBuffer;
71
+ private compositeUniformBuffer;
72
+ private boundaryUniformBuffer;
73
+ private chamferUniformBuffer;
74
+ private jfaSeedUniformBuffer;
75
+ private jfaFloodUniformBuffer;
76
+ private jfaDistUniformBuffer;
77
+ private interiorBindGroup;
78
+ private stencilMarkBindGroup;
79
+ private compositeBindGroup;
80
+ private chamferBindGroup;
81
+ private boundaryBindGroup;
82
+ private maskBindGroup;
83
+ private jfaSeedBindGroup;
84
+ private jfaDistBindGroup;
85
+ private videoTexture;
86
+ private videoTextureView;
87
+ private depthTexture;
88
+ private depthTextureView;
89
+ private interiorColorTexture;
90
+ private interiorColorView;
91
+ private interiorDepthTexture;
92
+ private interiorDepthView;
93
+ private fboWidth;
94
+ private fboHeight;
95
+ private depthStencilTexture;
96
+ private depthStencilView;
97
+ private dsWidth;
98
+ private dsHeight;
99
+ private jfaMaskTexture;
100
+ private jfaMaskView;
101
+ private jfaPingTexture;
102
+ private jfaPingView;
103
+ private jfaPongTexture;
104
+ private jfaPongView;
105
+ private jfaDistTexture;
106
+ private jfaDistView;
107
+ private jfaWidth;
108
+ private jfaHeight;
109
+ private jfaDirty;
110
+ private stencilVertexBuffer;
111
+ private stencilIndexBuffer;
112
+ private stencilIndexCount;
113
+ private boundaryVertexBuffer;
114
+ private boundaryVertexCount;
115
+ private chamferVertexBuffer;
116
+ private chamferVertexCount;
117
+ private meshAspect;
118
+ private meshScaleX;
119
+ private meshScaleY;
120
+ private lightDirX;
121
+ private lightDirY;
122
+ private lightDir3;
123
+ private depthFlipBuffer;
124
+ private readonly offsetData;
125
+ constructor(parent: HTMLElement, config: PortalRendererConfig, device: GPUDevice, adapterInfo: GPUAdapterInfo);
126
+ initialize(video: HTMLVideoElement, depthWidth: number, depthHeight: number, mesh: ShapeMesh): void;
127
+ private createInteriorPipeline;
128
+ private createStencilMarkPipeline;
129
+ private createCompositePipeline;
130
+ private createChamferPipeline;
131
+ private createBoundaryPipeline;
132
+ private createMaskPipeline;
133
+ private createJFASeedPipeline;
134
+ private createJFAFloodPipeline;
135
+ private createJFADistPipeline;
136
+ private uploadStencilMesh;
137
+ private uploadBoundaryMesh;
138
+ private uploadChamferMesh;
139
+ private writeStaticInteriorUniforms;
140
+ private writeStaticCompositeUniforms;
141
+ private writeStaticChamferUniforms;
142
+ private writeStaticBoundaryUniforms;
143
+ private rebuildInteriorBindGroup;
144
+ private rebuildStencilMarkBindGroup;
145
+ private rebuildCompositeBindGroup;
146
+ private rebuildChamferBindGroup;
147
+ private rebuildBoundaryBindGroup;
148
+ private rebuildMaskBindGroup;
149
+ private rebuildJFASeedBindGroup;
150
+ private rebuildJFADistBindGroup;
151
+ /** Rebuild all bind groups that reference textures (after resize or init). */
152
+ private rebuildBindGroups;
153
+ private createInteriorFBO;
154
+ private createDepthStencilTexture;
155
+ private createJFAResources;
156
+ private computeDistanceField;
157
+ /**
158
+ * Flip depth data vertically.
159
+ *
160
+ * WebGPU writeTexture has no UNPACK_FLIP_Y_WEBGL equivalent. Video frames
161
+ * are imported with flipY:true via copyExternalImageToTexture, so depth
162
+ * data must also be flipped to maintain spatial alignment.
163
+ */
164
+ private flipDepthY;
165
+ private fallbackTexture;
166
+ private createFallbackTextureView;
167
+ /**
168
+ * Main render loop -- 6 draw calls per frame.
169
+ *
170
+ * Pass 1: Interior -> MRT offscreen textures.
171
+ * Pass 2a: Stencil mark -> depth-stencil attachment.
172
+ * Pass 2b: Composite -> canvas (stencil-tested).
173
+ * Pass 2c: Chamfer geometry -> canvas.
174
+ * Pass 3: Boundary effects -> canvas (alpha blended).
175
+ * JFA: runs inside command encoder when dirty (cached on resize).
176
+ */
177
+ protected onRenderFrame(): void;
178
+ /**
179
+ * Upload depth data to the GPU texture.
180
+ * Called from the RVFC loop at video frame rate, or from RAF fallback.
181
+ */
182
+ protected onDepthUpdate(timeSec: number): void;
183
+ protected recalculateViewportLayout(): void;
184
+ /**
185
+ * WebGPU device loss recovery.
186
+ *
187
+ * Device loss is handled via the `device.lost` promise (set in constructor).
188
+ * Full recovery requires re-requesting adapter + device, which is managed
189
+ * at the Web Component level by re-creating the renderer.
190
+ */
191
+ protected onContextRestored(): void;
192
+ protected disposeRenderer(): void;
193
+ private disposeTextures;
194
+ private disposeInteriorFBO;
195
+ private disposeDepthStencilTexture;
196
+ private disposeJFAResources;
197
+ private disposeGeometryBuffers;
198
+ }
199
+ //# sourceMappingURL=portal-renderer-webgpu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portal-renderer-webgpu.d.ts","sourceRoot":"","sources":["../../src/portal-renderer-webgpu.ts"],"names":[],"mappings":"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"}
@@ -29,13 +29,22 @@
29
29
  * refraction, chromatic fringe, occlusion — all driven by distance field
30
30
  * and interior depth texture.
31
31
  */
32
- import type { ParallaxInput } from './input-handler';
33
32
  import type { ShapeMesh } from './shape-generator';
33
+ import type { QualityTier } from './quality';
34
+ import { RendererBase } from './renderer-base';
34
35
  export interface PortalRendererConfig {
35
36
  parallaxStrength: number;
36
37
  overscanPadding: number;
37
38
  /** POM step count for interior (default: 16). */
38
39
  pomSteps: number;
40
+ /**
41
+ * Adaptive quality tier. Controls render resolution, JFA resolution,
42
+ * depth resolution, and sample counts.
43
+ * - 'auto' — probe device capabilities and classify automatically.
44
+ * - 'high' / 'medium' / 'low' — use the specified tier directly.
45
+ * - undefined — defaults to 'auto'.
46
+ */
47
+ quality?: 'auto' | QualityTier;
39
48
  rimLightIntensity: number;
40
49
  rimLightColor: [number, number, number];
41
50
  rimLightWidth: number;
@@ -66,7 +75,7 @@ export interface PortalRendererConfig {
66
75
  chamferWidth: number;
67
76
  /** Chamfer angle in degrees (0 = face-forward, 90 = wall). Default: 45 */
68
77
  chamferAngle: number;
69
- /** Chamfer base color [r, g, b] in 01 range. Default: [0.15, 0.15, 0.18] */
78
+ /** Chamfer base color [r, g, b] in 0-1 range. Default: [0.15, 0.15, 0.18] */
70
79
  chamferColor: [number, number, number];
71
80
  /** Chamfer ambient light level. Default: 0.12 */
72
81
  chamferAmbient: number;
@@ -81,29 +90,36 @@ export interface PortalRendererConfig {
81
90
  /** 3D light direction [x, y, z] for chamfer lighting (will be normalized). */
82
91
  lightDirection: [number, number, number];
83
92
  }
84
- export declare class PortalRenderer {
85
- private static readonly RESIZE_DEBOUNCE_MS;
86
- private readonly canvas;
93
+ export declare function buildEdgeMesh(edgeVertices: Float32Array): {
94
+ vertices: Float32Array;
95
+ count: number;
96
+ };
97
+ /**
98
+ * Build geometric chamfer ring around each contour with smooth per-vertex
99
+ * normals and inner/outer lerp parameter for progressive blur.
100
+ *
101
+ * Normals are averaged between adjacent segments at shared vertices so the
102
+ * chamfer surface appears smooth rather than faceted. The `lerpT` value is
103
+ * 0 at the inner (silhouette) edge and 1 at the outer edge, driving blur
104
+ * intensity in the fragment shader.
105
+ *
106
+ * Vertex format: [x, y, nx3, ny3, nz3, lerpT] — 6 floats per vertex.
107
+ */
108
+ export declare function buildChamferMesh(edgeVertices: Float32Array, contourOffsets: number[], contourIsHole: boolean[], chamferWidth: number, chamferAngle: number): {
109
+ vertices: Float32Array;
110
+ count: number;
111
+ };
112
+ export declare class PortalRenderer extends RendererBase {
87
113
  private gl;
88
- private readonly container;
89
- private stencilProgram;
90
- private maskProgram;
91
- private jfaSeedProgram;
92
- private jfaFloodProgram;
93
- private jfaDistProgram;
94
- private interiorProgram;
95
- private compositeProgram;
96
- private boundaryProgram;
97
- private chamferProgram;
98
- private stencilUniforms;
99
- private maskUniforms;
100
- private jfaSeedUniforms;
101
- private jfaFloodUniforms;
102
- private jfaDistUniforms;
103
- private interiorUniforms;
104
- private compositeUniforms;
105
- private boundaryUniforms;
106
- private chamferUniforms;
114
+ private stencilPass;
115
+ private maskPass;
116
+ private jfaSeedPass;
117
+ private jfaFloodPass;
118
+ private jfaDistPass;
119
+ private interiorPass;
120
+ private compositePass;
121
+ private boundaryPass;
122
+ private chamferPass;
107
123
  private quadVao;
108
124
  private stencilVao;
109
125
  private stencilIndexCount;
@@ -112,42 +128,19 @@ export declare class PortalRenderer {
112
128
  private boundaryVertexCount;
113
129
  private chamferVao;
114
130
  private chamferVertexCount;
115
- private videoTexture;
116
- private depthTexture;
131
+ private readonly textures;
132
+ private readonly videoSlot;
133
+ private readonly depthSlot;
117
134
  private interiorFbo;
118
135
  private interiorColorTex;
119
136
  private interiorDepthTex;
120
137
  private fboWidth;
121
138
  private fboHeight;
122
- private maskFbo;
123
- private maskTex;
124
- private jfaPingFbo;
125
- private jfaPingTex;
126
- private jfaPongFbo;
127
- private jfaPongTex;
128
- private distFbo;
129
- private distTex;
130
- private jfaWidth;
131
- private jfaHeight;
132
- private distFieldDirty;
139
+ private jfa;
133
140
  private hasColorBufferFloat;
134
- private depthWidth;
135
- private depthHeight;
136
- private videoAspect;
137
141
  private meshAspect;
138
142
  private meshScaleX;
139
143
  private meshScaleY;
140
- private readDepth;
141
- private readInput;
142
- private playbackVideo;
143
- private onVideoFrame;
144
- private animationFrameHandle;
145
- private rvfcHandle;
146
- private rvfcSupported;
147
- private resizeObserver;
148
- private resizeTimer;
149
- private uvOffset;
150
- private uvScale;
151
144
  private lightDirX;
152
145
  private lightDirY;
153
146
  private lightDir3;
@@ -162,25 +155,30 @@ export declare class PortalRenderer {
162
155
  private createFBO;
163
156
  private createJFAResources;
164
157
  private computeDistanceField;
165
- start(video: HTMLVideoElement, readDepth: (timeSec: number) => Uint8Array, readInput: () => ParallaxInput, onVideoFrame?: (currentTime: number, frameNumber: number) => void): void;
166
- stop(): void;
167
- dispose(): void;
168
158
  private initGPUResources;
169
- private getUniforms;
170
- private readonly videoFrameLoop;
171
- private readonly renderLoop;
172
- private updateDepthTexture;
173
- private setupResizeHandling;
174
- private readonly scheduleResizeRecalculate;
175
- private recalculateViewportLayout;
176
- private getViewportSize;
177
- private readonly handleContextLost;
178
- private readonly handleContextRestored;
159
+ /**
160
+ * Main render loop — called every animation frame at display refresh rate.
161
+ *
162
+ * Handles interior FBO rendering, stencil marking, emissive composite,
163
+ * chamfer geometry, and boundary effects in a multi-pass pipeline.
164
+ */
165
+ protected onRenderFrame(): void;
166
+ /**
167
+ * Upload depth data to the GPU texture.
168
+ * Called from the RVFC loop at video frame rate, or from RAF fallback.
169
+ */
170
+ protected onDepthUpdate(timeSec: number): void;
171
+ protected recalculateViewportLayout(): void;
172
+ /** Rebuild GPU state after context restoration. */
173
+ protected onContextRestored(): void;
174
+ /** Dispose source textures via the registry (video, depth). */
179
175
  private disposeTextures;
180
176
  private disposeFBO;
181
- private disposeJFA;
182
177
  private disposeStencilGeometry;
183
178
  private disposeBoundaryGeometry;
179
+ /** Dispose all GPU resources — called by base class dispose(). */
180
+ protected disposeRenderer(): void;
181
+ /** Dispose all render passes and shared VAO. */
184
182
  private disposeGPUResources;
185
183
  }
186
184
  //# sourceMappingURL=portal-renderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"portal-renderer.d.ts","sourceRoot":"","sources":["../../src/portal-renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"portal-renderer.d.ts","sourceRoot":"","sources":["../../src/portal-renderer.ts"],"names":[],"mappings":"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"}
@@ -15,66 +15,24 @@ export interface BinaryDownloadProgress {
15
15
  fraction: number;
16
16
  }
17
17
  /**
18
- * Worker-backed depth frame interpolator.
18
+ * Depth frame interpolator — synchronous keyframe blending.
19
19
  *
20
- * Offloads the bilateral filter, interpolation, and resize to a Web Worker
21
- * so the main thread stays free for smooth rendering. Uses double-buffering:
22
- * the main thread always has a ready-to-use depth frame while the worker
23
- * computes the next one in parallel.
20
+ * Interpolates between precomputed depth keyframes at ~5fps and returns
21
+ * raw Uint8 depth data for GPU upload. The bilateral filter runs on the
22
+ * GPU as a dedicated shader pass (see parallax-renderer.ts), so this
23
+ * class only handles temporal interpolation.
24
24
  *
25
- * ## Double-buffer strategy
26
- *
27
- * - `currentBuffer` the latest completed depth frame, always available
28
- * for synchronous reads via `sample()`.
29
- * - When the render loop calls `sample(timeSec)`, it returns `currentBuffer`
30
- * immediately (zero main-thread work) and posts a request to the worker
31
- * for the new time if it differs from the last requested time.
32
- * - When the worker responds, `currentBuffer` is swapped to the new result.
33
- * - During the 1-2 frames of latency, the previous depth frame is shown —
34
- * this is imperceptible since depth only changes at ~5fps.
25
+ * Frame-change caching avoids redundant computation: depth only changes
26
+ * at ~5fps (keyframe transitions), but the render loop calls sample()
27
+ * at 60fps. Caching skips recomputation for ~12 identical frames.
35
28
  */
36
- export declare class WorkerDepthInterpolator {
37
- private worker;
38
- private currentBuffer;
39
- private pendingTimeSec;
40
- private workerBusy;
41
- private disposed;
42
- private constructor();
43
- /**
44
- * Create a WorkerDepthInterpolator, initializing the worker with frame data.
45
- *
46
- * The frame ArrayBuffers are transferred (zero-copy) to the worker.
47
- * After this call, the original depthData.frames arrays are neutered
48
- * and should not be accessed.
49
- */
50
- static create(depthData: PrecomputedDepthData, targetWidth: number, targetHeight: number): Promise<WorkerDepthInterpolator>;
51
- /**
52
- * Get the current depth frame — always synchronous, zero main-thread work.
53
- *
54
- * Returns the latest completed depth frame from the worker. If the worker
55
- * hasn't finished processing the current time yet, returns the previous
56
- * frame (1-2 frame latency is imperceptible at ~5fps depth changes).
57
- *
58
- * Automatically requests the worker to process the new time in the background.
59
- */
60
- sample(timeSec: number): Uint8Array;
61
- /** Send a sample request to the worker if it's not busy. */
62
- private requestSample;
63
- /** Terminate the worker and release resources. */
64
- dispose(): void;
65
- }
66
29
  export declare class DepthFrameInterpolator {
67
30
  private readonly depthData;
68
- private readonly targetWidth;
69
- private readonly targetHeight;
70
- private readonly interpolatedDepth;
71
- private readonly resizedDepth;
72
- private readonly bilateralOutput;
73
31
  private readonly uint8Output;
74
32
  private lastFrameIndex;
75
33
  private lastNextFrameIndex;
76
34
  private lastLerpFactor;
77
- constructor(depthData: PrecomputedDepthData, targetWidth: number, targetHeight: number);
35
+ constructor(depthData: PrecomputedDepthData);
78
36
  sample(timeSec: number): Uint8Array;
79
37
  }
80
38
  export declare function loadPrecomputedDepth(depthDataUrl: string, depthMetaUrl: string, onProgress?: (progress: BinaryDownloadProgress) => void): Promise<PrecomputedDepthData>;
@@ -1 +1 @@
1
- {"version":3,"file":"precomputed-depth.d.ts","sourceRoot":"","sources":["../../src/precomputed-depth.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO;IAQP;;;;;;OAMG;WACU,MAAM,CACjB,SAAS,EAAE,oBAAoB,EAC/B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,uBAAuB,CAAC;IAqEnC;;;;;;;;OAQG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;IAKnC,4DAA4D;IAC5D,OAAO,CAAC,aAAa;IAarB,kDAAkD;IAClD,OAAO,IAAI,IAAI;CAIhB;AAED,qBAAa,sBAAsB;IAe/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAhB/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAe;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IAMzC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,cAAc,CAAM;gBAGT,SAAS,EAAE,oBAAoB,EAC/B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM;IAUvC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;CA8DpC;AAED,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,GACtD,OAAO,CAAC,oBAAoB,CAAC,CAO/B"}
1
+ {"version":3,"file":"precomputed-depth.d.ts","sourceRoot":"","sources":["../../src/precomputed-depth.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,sBAAsB;IAS/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAR5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IAGzC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,cAAc,CAAM;gBAGT,SAAS,EAAE,oBAAoB;IAMlD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;CA4BpC;AAED,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,GACtD,OAAO,CAAC,oBAAoB,CAAC,CAO/B"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Adaptive Quality Scaling — device capability probing and tier classification.
3
+ *
4
+ * Probes WebGL context + navigator APIs once at init time, classifies the
5
+ * device into a quality tier (high / medium / low), and resolves concrete
6
+ * parameters that both renderers and Web Components consume to adjust:
7
+ *
8
+ * - **Render resolution** — DPR cap (2.0 / 1.5 / 1.0)
9
+ * - **Depth resolution** — depth texture max dimension (512 / 512 / 256)
10
+ * - **Sample count** — POM steps (16 / 16 / 8), bilateral kernel (5×5 / 5×5 / 3×3)
11
+ * - **JFA resolution** — distance field divisor (2 / 2 / 4) for portal effect
12
+ *
13
+ * Override precedence (unchanged): explicit config > quality-derived > calibrated defaults.
14
+ *
15
+ * @see ADR-012 for the architectural decision and rationale.
16
+ */
17
+ /** Device quality classification. */
18
+ export type QualityTier = 'high' | 'medium' | 'low';
19
+ /** Concrete rendering parameters resolved from a quality tier. */
20
+ export interface QualityParams {
21
+ readonly tier: QualityTier;
22
+ /** Maximum device pixel ratio (2.0 / 1.5 / 1.0). */
23
+ readonly dprCap: number;
24
+ /** Maximum depth texture dimension — depth maps larger than this are downscaled (512 / 512 / 256). */
25
+ readonly depthMaxDim: number;
26
+ /** POM ray-march step count (16 / 16 / 8). */
27
+ readonly pomSteps: number;
28
+ /** Bilateral filter kernel radius in texels — kernel is (2r+1)×(2r+1) (2 / 2 / 1). */
29
+ readonly bilateralRadius: number;
30
+ /** JFA distance field resolution divisor (2 = half-res, 4 = quarter-res). */
31
+ readonly jfaDivisor: number;
32
+ }
33
+ /** Raw device capability probe results. */
34
+ export interface DeviceCapabilities {
35
+ /** GPU renderer string from WEBGL_debug_renderer_info, or 'unknown'. */
36
+ readonly gpuRenderer: string;
37
+ /** GL_MAX_TEXTURE_SIZE. */
38
+ readonly maxTextureSize: number;
39
+ /** navigator.hardwareConcurrency (logical cores), or 0 if unavailable. */
40
+ readonly hardwareConcurrency: number;
41
+ /** navigator.deviceMemory in GB, or 0 if unavailable. */
42
+ readonly deviceMemory: number;
43
+ /** window.devicePixelRatio. */
44
+ readonly devicePixelRatio: number;
45
+ /** Total screen pixels (width × height). */
46
+ readonly screenPixels: number;
47
+ /** Whether the device appears to be mobile (touch + small screen). */
48
+ readonly isMobile: boolean;
49
+ }
50
+ /**
51
+ * Probe device capabilities from the WebGL context and navigator APIs.
52
+ *
53
+ * This is intentionally lightweight — it reads values that are already
54
+ * available (no async, no benchmarks). Called once at init time.
55
+ */
56
+ export declare function probeCapabilities(gl: WebGL2RenderingContext): DeviceCapabilities;
57
+ /**
58
+ * Classify device capabilities into a quality tier using a score-based heuristic.
59
+ *
60
+ * Weighted signals are summed to produce a score:
61
+ * - Score >= 0 → high
62
+ * - Score -25 to -1 → medium
63
+ * - Score < -25 → low
64
+ */
65
+ export declare function classifyDevice(caps: DeviceCapabilities): QualityTier;
66
+ /**
67
+ * Resolve quality parameters for a renderer.
68
+ *
69
+ * - If `quality` is a specific tier ('high' | 'medium' | 'low'), return
70
+ * that tier's parameters directly (no probing).
71
+ * - If `quality` is 'auto' or undefined, probe device capabilities and
72
+ * classify automatically.
73
+ *
74
+ * Called once per renderer at construction time. The returned params are
75
+ * stored as `private readonly qualityParams` and read during init and resize.
76
+ *
77
+ * @param gl - WebGL 2 rendering context (used for GPU probing).
78
+ * @param quality - Explicit tier, 'auto', or undefined (defaults to 'auto').
79
+ */
80
+ export declare function resolveQuality(gl: WebGL2RenderingContext, quality?: 'auto' | QualityTier): QualityParams;
81
+ /**
82
+ * Probe device capabilities from a WebGPU adapter.
83
+ *
84
+ * Extracts the same `DeviceCapabilities` shape as the WebGL2 probe,
85
+ * allowing the shared `classifyDevice()` scoring logic to work for both backends.
86
+ */
87
+ export declare function probeCapabilitiesWebGPU(adapterInfo: GPUAdapterInfo): DeviceCapabilities;
88
+ /**
89
+ * Resolve quality parameters for a WebGPU renderer.
90
+ *
91
+ * Same logic as `resolveQuality()` but accepts a `GPUAdapterInfo` instead
92
+ * of a WebGL context.
93
+ */
94
+ export declare function resolveQualityWebGPU(adapterInfo: GPUAdapterInfo, quality?: 'auto' | QualityTier): QualityParams;
95
+ //# sourceMappingURL=quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../src/quality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,qCAAqC;AACrC,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEpD,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sGAAsG;IACtG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,sFAAsF;IACtF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,2CAA2C;AAC3C,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2BAA2B;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,yDAAyD;IACzD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,+BAA+B;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,4CAA4C;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAkCD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,sBAAsB,GAAG,kBAAkB,CA0ChF;AA2CD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,WAAW,CAmCpE;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,sBAAsB,EAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,GAC7B,aAAa,CAMf;AAMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,cAAc,GAAG,kBAAkB,CAkCvF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,cAAc,EAC3B,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,GAC7B,aAAa,CAMf"}