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.
- package/README.md +14 -0
- package/dist/components/layershift.js +1783 -654
- package/dist/npm/layershift.es.js +5154 -2569
- package/dist/types/components/layershift/layershift-element.d.ts +2 -1
- package/dist/types/components/layershift/layershift-element.d.ts.map +1 -1
- package/dist/types/components/layershift/portal-element.d.ts +2 -1
- package/dist/types/components/layershift/portal-element.d.ts.map +1 -1
- package/dist/types/components/layershift/types.d.ts +8 -0
- package/dist/types/components/layershift/types.d.ts.map +1 -1
- package/dist/types/gpu-backend.d.ts +37 -0
- package/dist/types/gpu-backend.d.ts.map +1 -0
- package/dist/types/jfa-distance-field.d.ts +78 -0
- package/dist/types/jfa-distance-field.d.ts.map +1 -0
- package/dist/types/parallax-renderer-webgpu.d.ts +103 -0
- package/dist/types/parallax-renderer-webgpu.d.ts.map +1 -0
- package/dist/types/parallax-renderer.d.ts +54 -91
- package/dist/types/parallax-renderer.d.ts.map +1 -1
- package/dist/types/portal-renderer-webgpu.d.ts +199 -0
- package/dist/types/portal-renderer-webgpu.d.ts.map +1 -0
- package/dist/types/portal-renderer.d.ts +63 -65
- package/dist/types/portal-renderer.d.ts.map +1 -1
- package/dist/types/precomputed-depth.d.ts +9 -51
- package/dist/types/precomputed-depth.d.ts.map +1 -1
- package/dist/types/quality.d.ts +95 -0
- package/dist/types/quality.d.ts.map +1 -0
- package/dist/types/render-pass-webgpu.d.ts +76 -0
- package/dist/types/render-pass-webgpu.d.ts.map +1 -0
- package/dist/types/render-pass.d.ts +171 -0
- package/dist/types/render-pass.d.ts.map +1 -0
- package/dist/types/renderer-base.d.ts +124 -0
- package/dist/types/renderer-base.d.ts.map +1 -0
- package/dist/types/webgl-utils.d.ts +29 -0
- package/dist/types/webgl-utils.d.ts.map +1 -0
- package/dist/types/webgpu-utils.d.ts +42 -0
- package/dist/types/webgpu-utils.d.ts.map +1 -0
- 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 0
|
|
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
|
|
85
|
-
|
|
86
|
-
|
|
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
|
|
89
|
-
private
|
|
90
|
-
private
|
|
91
|
-
private
|
|
92
|
-
private
|
|
93
|
-
private
|
|
94
|
-
private
|
|
95
|
-
private
|
|
96
|
-
private
|
|
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
|
|
116
|
-
private
|
|
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
|
|
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
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,
|
|
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
|
-
*
|
|
18
|
+
* Depth frame interpolator — synchronous keyframe blending.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
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
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
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
|
|
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
|
|
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"}
|