layershift 0.2.1 → 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 +1782 -653
- package/dist/npm/layershift.es.js +5212 -2583
- package/dist/types/components/layershift/layershift-element.d.ts +10 -8
- package/dist/types/components/layershift/layershift-element.d.ts.map +1 -1
- package/dist/types/components/layershift/lifecycle.d.ts +77 -0
- package/dist/types/components/layershift/lifecycle.d.ts.map +1 -0
- package/dist/types/components/layershift/portal-element.d.ts +10 -8
- 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 +64 -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 +38 -4
|
@@ -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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebGPU Render Pass Framework — pipeline and bind group management.
|
|
3
|
+
*
|
|
4
|
+
* Parallel to `render-pass.ts` (WebGL2) but with idiomatic WebGPU patterns:
|
|
5
|
+
* - Pipeline state objects bake blend/stencil/depth config at creation
|
|
6
|
+
* - Bind groups replace individual uniform calls
|
|
7
|
+
* - No mutable state machine
|
|
8
|
+
*
|
|
9
|
+
* @see render-pass.ts for the WebGL2 counterpart.
|
|
10
|
+
*/
|
|
11
|
+
/** A single WebGPU render pass with its pipeline and bind group layout. */
|
|
12
|
+
export interface WebGPURenderPass {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly pipeline: GPURenderPipeline;
|
|
15
|
+
readonly bindGroupLayout: GPUBindGroupLayout;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
}
|
|
18
|
+
/** A WebGPU render pass that outputs to an offscreen texture. */
|
|
19
|
+
export interface WebGPUFBOPass extends WebGPURenderPass {
|
|
20
|
+
outputTexture: GPUTexture;
|
|
21
|
+
outputView: GPUTextureView;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
resize(device: GPUDevice, w: number, h: number, format?: GPUTextureFormat): void;
|
|
25
|
+
}
|
|
26
|
+
/** Configuration for creating a WebGPU render pass. */
|
|
27
|
+
export interface WebGPURenderPassConfig {
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly vertexShader: string;
|
|
30
|
+
readonly fragmentShader: string;
|
|
31
|
+
readonly vertexBufferLayouts: GPUVertexBufferLayout[];
|
|
32
|
+
readonly colorTargets: GPUColorTargetState[];
|
|
33
|
+
readonly depthStencil?: GPUDepthStencilState;
|
|
34
|
+
readonly primitive?: GPUPrimitiveState;
|
|
35
|
+
/** Explicit bind group layout entries. If omitted, uses auto layout. */
|
|
36
|
+
readonly bindGroupLayoutEntries?: GPUBindGroupLayoutEntry[];
|
|
37
|
+
}
|
|
38
|
+
/** Configuration for creating a WebGPU FBO pass. */
|
|
39
|
+
export interface WebGPUFBOPassConfig extends WebGPURenderPassConfig {
|
|
40
|
+
readonly outputWidth: number;
|
|
41
|
+
readonly outputHeight: number;
|
|
42
|
+
readonly outputFormat?: GPUTextureFormat;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a WebGPU render pass with explicit bind group layout.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createWebGPUPass(device: GPUDevice, config: WebGPURenderPassConfig): WebGPURenderPass;
|
|
48
|
+
/**
|
|
49
|
+
* Create a WebGPU FBO pass that renders to an offscreen texture.
|
|
50
|
+
*/
|
|
51
|
+
export declare function createWebGPUFBOPass(device: GPUDevice, config: WebGPUFBOPassConfig): WebGPUFBOPass;
|
|
52
|
+
/**
|
|
53
|
+
* Shared texture registry for WebGPU — manages texture unit allocation.
|
|
54
|
+
*
|
|
55
|
+
* Unlike WebGL2, WebGPU doesn't have numbered texture units. Instead,
|
|
56
|
+
* textures are referenced by bind group entries. This registry provides
|
|
57
|
+
* a consistent naming scheme across passes.
|
|
58
|
+
*/
|
|
59
|
+
export declare class WebGPUTextureRegistry {
|
|
60
|
+
private readonly textures;
|
|
61
|
+
register(name: string, texture: GPUTexture): GPUTextureView;
|
|
62
|
+
get(name: string): {
|
|
63
|
+
texture: GPUTexture;
|
|
64
|
+
view: GPUTextureView;
|
|
65
|
+
} | undefined;
|
|
66
|
+
dispose(): void;
|
|
67
|
+
}
|
|
68
|
+
/** Fullscreen quad vertex buffer layout: position (vec2). */
|
|
69
|
+
export declare const FULLSCREEN_QUAD_LAYOUT: GPUVertexBufferLayout;
|
|
70
|
+
/** Mesh vertex buffer layout: position (vec2) only. */
|
|
71
|
+
export declare const MESH_POSITION_LAYOUT: GPUVertexBufferLayout;
|
|
72
|
+
/** Boundary vertex buffer layout: position (vec2) + normal (vec2). */
|
|
73
|
+
export declare const BOUNDARY_VERTEX_LAYOUT: GPUVertexBufferLayout;
|
|
74
|
+
/** Chamfer vertex buffer layout: position (vec2) + normal3 (vec3) + lerpT (float). */
|
|
75
|
+
export declare const CHAMFER_VERTEX_LAYOUT: GPUVertexBufferLayout;
|
|
76
|
+
//# sourceMappingURL=render-pass-webgpu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-pass-webgpu.d.ts","sourceRoot":"","sources":["../../src/render-pass-webgpu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,kBAAkB,CAAC;IAC7C,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,iEAAiE;AACjE,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,aAAa,EAAE,UAAU,CAAC;IAC1B,UAAU,EAAE,cAAc,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAClF;AAED,uDAAuD;AACvD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,CAAC;IACtD,QAAQ,CAAC,YAAY,EAAE,mBAAmB,EAAE,CAAC;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,oBAAoB,CAAC;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC;IACvC,wEAAwE;IACxE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,uBAAuB,EAAE,CAAC;CAC7D;AAED,oDAAoD;AACpD,MAAM,WAAW,mBAAoB,SAAQ,sBAAsB;IACjE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;CAC1C;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,sBAAsB,GAC7B,gBAAgB,CAqClB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,mBAAmB,GAC1B,aAAa,CA4Bf;AAMD;;;;;;GAMG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoE;IAE7F,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,cAAc;IAM3D,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,cAAc,CAAA;KAAE,GAAG,SAAS;IAI5E,OAAO,IAAI,IAAI;CAMhB;AAuBD,6DAA6D;AAC7D,eAAO,MAAM,sBAAsB,EAAE,qBAKpC,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,oBAAoB,EAAE,qBAKlC,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,sBAAsB,EAAE,qBAMpC,CAAC;AAEF,sFAAsF;AACtF,eAAO,MAAM,qBAAqB,EAAE,qBAOnC,CAAC"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared render pass framework for compositing and effect stacking.
|
|
3
|
+
*
|
|
4
|
+
* Provides standardized interfaces (`RenderPass`, `FBOPass`) and a
|
|
5
|
+
* `TextureRegistry` for unit allocation. Both the parallax and portal
|
|
6
|
+
* renderers adopt this framework to structure their multi-pass GPU
|
|
7
|
+
* pipelines consistently.
|
|
8
|
+
*
|
|
9
|
+
* ## Design principles
|
|
10
|
+
*
|
|
11
|
+
* - **Geometry-agnostic** — passes may use fullscreen quads, indexed
|
|
12
|
+
* meshes, or any other geometry. The framework doesn't assume.
|
|
13
|
+
* - **No common execute()** — passes have wildly different execute
|
|
14
|
+
* signatures (bilateral needs raw depth data; JFA flood is iterative;
|
|
15
|
+
* parallax just draws). Each renderer calls passes type-safely.
|
|
16
|
+
* - **Zero per-frame overhead** — TextureRegistry allocates at init
|
|
17
|
+
* time. Hot-path code reads slot references directly.
|
|
18
|
+
* - **Pragmatic** — ~250 lines, not a game engine.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* A self-contained render pass: owns its shader program, uniform cache,
|
|
22
|
+
* and knows how to clean itself up.
|
|
23
|
+
*
|
|
24
|
+
* `program` and `uniforms` are exposed directly so the render loop can
|
|
25
|
+
* set per-frame uniforms (e.g., `uOffset`) without method-call overhead.
|
|
26
|
+
*/
|
|
27
|
+
export interface RenderPass {
|
|
28
|
+
/** Display name for debugging (e.g., "bilateral-filter", "jfa-flood"). */
|
|
29
|
+
readonly name: string;
|
|
30
|
+
/** The compiled + linked shader program. */
|
|
31
|
+
readonly program: WebGLProgram;
|
|
32
|
+
/** Cached uniform locations. */
|
|
33
|
+
readonly uniforms: Record<string, WebGLUniformLocation | null>;
|
|
34
|
+
/** Release GPU resources owned by this pass (program, FBOs). */
|
|
35
|
+
dispose(gl: WebGL2RenderingContext): void;
|
|
36
|
+
}
|
|
37
|
+
/** A single FBO color attachment descriptor. */
|
|
38
|
+
export interface FBOAttachment {
|
|
39
|
+
/** The texture backing this attachment. */
|
|
40
|
+
texture: WebGLTexture;
|
|
41
|
+
/** Assigned texture unit (e.g., `gl.TEXTURE2` maps to unit 2). */
|
|
42
|
+
unit: number;
|
|
43
|
+
/** GL color attachment point (e.g., `gl.COLOR_ATTACHMENT0`). */
|
|
44
|
+
attachment: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A render pass that writes to an FBO rather than the default framebuffer.
|
|
48
|
+
*
|
|
49
|
+
* Manages its own framebuffer and output texture(s). Supports both
|
|
50
|
+
* single-output passes (bilateral filter → R8) and MRT passes
|
|
51
|
+
* (portal interior → RGBA8 color + RGBA8 depth).
|
|
52
|
+
*/
|
|
53
|
+
export interface FBOPass extends RenderPass {
|
|
54
|
+
/** The framebuffer object. Null before first `resize()`. */
|
|
55
|
+
fbo: WebGLFramebuffer | null;
|
|
56
|
+
/** Output textures written by this pass. */
|
|
57
|
+
readonly outputs: readonly FBOAttachment[];
|
|
58
|
+
/** Width of the FBO in pixels. */
|
|
59
|
+
width: number;
|
|
60
|
+
/** Height of the FBO in pixels. */
|
|
61
|
+
height: number;
|
|
62
|
+
/**
|
|
63
|
+
* Resize or recreate the FBO and its attachment textures.
|
|
64
|
+
* Called on viewport resize, not per-frame.
|
|
65
|
+
*/
|
|
66
|
+
resize(gl: WebGL2RenderingContext, width: number, height: number): void;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Ordered list of render passes. Execute in array order.
|
|
70
|
+
*
|
|
71
|
+
* This is intentionally a thin type alias, not a class. The dual-loop
|
|
72
|
+
* architecture (RVFC + RAF) means passes are NOT all executed in one
|
|
73
|
+
* sequence, so orchestration stays in each renderer's render loop.
|
|
74
|
+
*/
|
|
75
|
+
export type RenderPipeline = readonly RenderPass[];
|
|
76
|
+
/** A named texture with its assigned unit. */
|
|
77
|
+
export interface TextureSlot {
|
|
78
|
+
/** Human-readable name (e.g., "video", "filteredDepth"). */
|
|
79
|
+
readonly name: string;
|
|
80
|
+
/** Assigned texture unit number (0, 1, 2, ...). */
|
|
81
|
+
readonly unit: number;
|
|
82
|
+
/** The WebGL texture handle. Null until allocated. */
|
|
83
|
+
texture: WebGLTexture | null;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Tracks texture unit assignments for a renderer.
|
|
87
|
+
*
|
|
88
|
+
* All allocation happens at init time via `register()`. The hot-path
|
|
89
|
+
* render loop accesses slots directly by cached reference — no map
|
|
90
|
+
* lookups per frame.
|
|
91
|
+
*
|
|
92
|
+
* Usage:
|
|
93
|
+
* ```ts
|
|
94
|
+
* const textures = new TextureRegistry();
|
|
95
|
+
* const videoSlot = textures.register('video'); // unit 0
|
|
96
|
+
* const depthSlot = textures.register('filteredDepth'); // unit 1
|
|
97
|
+
*
|
|
98
|
+
* // In render loop (hot path) — direct reference, zero lookup:
|
|
99
|
+
* gl.activeTexture(gl.TEXTURE0 + videoSlot.unit);
|
|
100
|
+
* gl.bindTexture(gl.TEXTURE_2D, videoSlot.texture);
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare class TextureRegistry {
|
|
104
|
+
private readonly slots;
|
|
105
|
+
private nextUnit;
|
|
106
|
+
/**
|
|
107
|
+
* Reserve a texture unit for a named texture.
|
|
108
|
+
*
|
|
109
|
+
* @returns The `TextureSlot` — hold a reference for hot-path access.
|
|
110
|
+
* @throws If the name is already registered.
|
|
111
|
+
*/
|
|
112
|
+
register(name: string): TextureSlot;
|
|
113
|
+
/**
|
|
114
|
+
* Get a previously registered slot by name.
|
|
115
|
+
*
|
|
116
|
+
* @throws If the name was not registered.
|
|
117
|
+
*/
|
|
118
|
+
get(name: string): TextureSlot;
|
|
119
|
+
/** Delete all textures and reset slots to null. */
|
|
120
|
+
disposeAll(gl: WebGL2RenderingContext): void;
|
|
121
|
+
/** Number of registered slots. */
|
|
122
|
+
get size(): number;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Create a `RenderPass` from vertex/fragment shader source.
|
|
126
|
+
*
|
|
127
|
+
* Compiles shaders, links program, caches uniform locations.
|
|
128
|
+
* The returned pass owns its program and cleans it up on `dispose()`.
|
|
129
|
+
*/
|
|
130
|
+
export declare function createPass(gl: WebGL2RenderingContext, name: string, vertexSource: string, fragmentSource: string, uniformNames: readonly string[]): RenderPass;
|
|
131
|
+
/** Options for creating a single-output FBO pass. */
|
|
132
|
+
export interface FBOPassOptions {
|
|
133
|
+
/** GL internal format (e.g., `gl.R8`, `gl.RGBA8`, `gl.RG16F`). */
|
|
134
|
+
internalFormat: number;
|
|
135
|
+
/** GL format for texImage2D (e.g., `gl.RED`, `gl.RGBA`, `gl.RG`). */
|
|
136
|
+
format: number;
|
|
137
|
+
/** GL type for texImage2D (e.g., `gl.UNSIGNED_BYTE`, `gl.FLOAT`). */
|
|
138
|
+
type: number;
|
|
139
|
+
/** Texture unit to assign to the output texture. */
|
|
140
|
+
textureUnit: number;
|
|
141
|
+
/** Initial FBO width. */
|
|
142
|
+
width: number;
|
|
143
|
+
/** Initial FBO height. */
|
|
144
|
+
height: number;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Create an `FBOPass` with a single color attachment.
|
|
148
|
+
*
|
|
149
|
+
* The FBO and its output texture are created immediately at the given
|
|
150
|
+
* dimensions. Call `resize()` to recreate at a different size.
|
|
151
|
+
*/
|
|
152
|
+
export declare function createFBOPass(gl: WebGL2RenderingContext, name: string, vertexSource: string, fragmentSource: string, uniformNames: readonly string[], options: FBOPassOptions): FBOPass;
|
|
153
|
+
/** Descriptor for one MRT color attachment. */
|
|
154
|
+
export interface MRTAttachment {
|
|
155
|
+
/** GL internal format (e.g., `gl.RGBA8`). */
|
|
156
|
+
internalFormat: number;
|
|
157
|
+
/** GL format (e.g., `gl.RGBA`). */
|
|
158
|
+
format: number;
|
|
159
|
+
/** GL type (e.g., `gl.UNSIGNED_BYTE`). */
|
|
160
|
+
type: number;
|
|
161
|
+
/** Texture unit to assign. */
|
|
162
|
+
textureUnit: number;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Create an `FBOPass` with multiple color attachments (MRT).
|
|
166
|
+
*
|
|
167
|
+
* Used by the portal interior pass which writes both color and depth
|
|
168
|
+
* to separate textures in a single draw call via `gl.drawBuffers()`.
|
|
169
|
+
*/
|
|
170
|
+
export declare function createMRTPass(gl: WebGL2RenderingContext, name: string, vertexSource: string, fragmentSource: string, uniformNames: readonly string[], attachments: readonly MRTAttachment[], width: number, height: number): FBOPass;
|
|
171
|
+
//# sourceMappingURL=render-pass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-pass.d.ts","sourceRoot":"","sources":["../../src/render-pass.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class for Layershift renderers.
|
|
3
|
+
*
|
|
4
|
+
* Extracts shared non-GPU logic common to both the parallax and portal
|
|
5
|
+
* renderers (and their future WebGPU counterparts):
|
|
6
|
+
*
|
|
7
|
+
* - Canvas creation + container attachment
|
|
8
|
+
* - Dual-loop animation management (RVFC + RAF)
|
|
9
|
+
* - Resize handling with debounce
|
|
10
|
+
* - Depth dimension clamping + CPU subsampling
|
|
11
|
+
* - Cover-fit UV computation
|
|
12
|
+
* - WebGL context loss handling
|
|
13
|
+
*
|
|
14
|
+
* Subclasses implement the GPU-specific abstract methods:
|
|
15
|
+
* `onRenderFrame()`, `onDepthUpdate()`, `recalculateViewportLayout()`,
|
|
16
|
+
* `disposeRenderer()`, and `onContextRestored()`.
|
|
17
|
+
*/
|
|
18
|
+
import type { ParallaxInput } from './input-handler';
|
|
19
|
+
import type { QualityParams } from './quality';
|
|
20
|
+
export declare abstract class RendererBase {
|
|
21
|
+
protected static readonly RESIZE_DEBOUNCE_MS = 100;
|
|
22
|
+
protected readonly canvas: HTMLCanvasElement;
|
|
23
|
+
protected readonly container: HTMLElement;
|
|
24
|
+
/** GPU texture dimensions (may be clamped by quality tier). */
|
|
25
|
+
protected depthWidth: number;
|
|
26
|
+
protected depthHeight: number;
|
|
27
|
+
/** Original source depth dimensions (from precomputed data). */
|
|
28
|
+
protected sourceDepthWidth: number;
|
|
29
|
+
protected sourceDepthHeight: number;
|
|
30
|
+
/** Reusable buffer for subsampling depth data when GPU dims < source dims. */
|
|
31
|
+
protected depthSubsampleBuffer: Uint8Array | null;
|
|
32
|
+
protected videoAspect: number;
|
|
33
|
+
protected uvOffset: number[];
|
|
34
|
+
protected uvScale: number[];
|
|
35
|
+
protected readDepth: ((timeSec: number) => Uint8Array) | null;
|
|
36
|
+
protected readInput: (() => ParallaxInput) | null;
|
|
37
|
+
protected playbackVideo: HTMLVideoElement | null;
|
|
38
|
+
/**
|
|
39
|
+
* Optional callback invoked on each new video frame (from RVFC).
|
|
40
|
+
* The Web Component uses this to dispatch frame events.
|
|
41
|
+
*/
|
|
42
|
+
protected onVideoFrame: ((currentTime: number, frameNumber: number) => void) | null;
|
|
43
|
+
protected animationFrameHandle: number;
|
|
44
|
+
/** requestVideoFrameCallback handle (0 = inactive). */
|
|
45
|
+
protected rvfcHandle: number;
|
|
46
|
+
/** Whether RVFC is supported on the current video element. */
|
|
47
|
+
protected rvfcSupported: boolean;
|
|
48
|
+
protected resizeObserver: ResizeObserver | null;
|
|
49
|
+
protected resizeTimer: number | null;
|
|
50
|
+
/** Adaptive quality parameters. Set by subclass constructor after GL init. */
|
|
51
|
+
protected qualityParams: QualityParams;
|
|
52
|
+
constructor(parent: HTMLElement);
|
|
53
|
+
/**
|
|
54
|
+
* Begin the render loop.
|
|
55
|
+
*
|
|
56
|
+
* When `requestVideoFrameCallback` is available, two loops run:
|
|
57
|
+
* 1. RVFC loop — fires once per new video frame, handles depth update.
|
|
58
|
+
* 2. RAF loop — fires at display refresh rate, handles input + render.
|
|
59
|
+
*
|
|
60
|
+
* When RVFC is not available, falls back to a single RAF loop.
|
|
61
|
+
*/
|
|
62
|
+
start(video: HTMLVideoElement, readDepth: (timeSec: number) => Uint8Array, readInput: () => ParallaxInput, onVideoFrame?: (currentTime: number, frameNumber: number) => void): void;
|
|
63
|
+
/** Stop both render loops and release callbacks. */
|
|
64
|
+
stop(): void;
|
|
65
|
+
/** Stop rendering and release all GPU resources. */
|
|
66
|
+
dispose(): void;
|
|
67
|
+
/** Check whether requestVideoFrameCallback is available. */
|
|
68
|
+
protected static isRVFCSupported(): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* RAF loop — fires at display refresh rate.
|
|
71
|
+
* Delegates to subclass `onRenderFrame()` for the actual render work.
|
|
72
|
+
*/
|
|
73
|
+
private readonly _rafLoop;
|
|
74
|
+
/**
|
|
75
|
+
* RVFC callback — fires only when the browser presents a new video frame.
|
|
76
|
+
* Delegates to subclass `onDepthUpdate()` for depth texture upload.
|
|
77
|
+
*/
|
|
78
|
+
private readonly _videoFrameLoop;
|
|
79
|
+
private readonly _handleContextLost;
|
|
80
|
+
private readonly _handleContextRestored;
|
|
81
|
+
/**
|
|
82
|
+
* Set up a ResizeObserver on the container element and a fallback
|
|
83
|
+
* window resize listener. Called by subclass after GPU init.
|
|
84
|
+
*/
|
|
85
|
+
protected setupResizeHandling(): void;
|
|
86
|
+
/** Debounce resize events to avoid expensive layout recalculations. */
|
|
87
|
+
protected readonly scheduleResizeRecalculate: () => void;
|
|
88
|
+
/** Read the container's pixel dimensions, with a minimum of 1x1. */
|
|
89
|
+
protected getViewportSize(): {
|
|
90
|
+
width: number;
|
|
91
|
+
height: number;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Clamp depth dimensions to the quality tier's maximum and allocate
|
|
95
|
+
* the subsample buffer if needed. Called during `initialize()`.
|
|
96
|
+
*/
|
|
97
|
+
protected clampDepthDimensions(sourceWidth: number, sourceHeight: number, maxDim: number): void;
|
|
98
|
+
/**
|
|
99
|
+
* CPU nearest-neighbor depth subsampling.
|
|
100
|
+
*
|
|
101
|
+
* Returns the original data if no subsampling is needed, otherwise
|
|
102
|
+
* fills and returns the pre-allocated subsample buffer.
|
|
103
|
+
*/
|
|
104
|
+
protected subsampleDepth(depthData: Uint8Array): Uint8Array;
|
|
105
|
+
/**
|
|
106
|
+
* Compute cover-fit + overscan UV transform.
|
|
107
|
+
*
|
|
108
|
+
* The video fills the viewport (cover-fit), and overscan adds extra
|
|
109
|
+
* visible area so parallax displacement doesn't reveal edges.
|
|
110
|
+
* Updates `this.uvOffset` and `this.uvScale`.
|
|
111
|
+
*/
|
|
112
|
+
protected computeCoverFitUV(parallaxStrength: number, overscanPadding: number): void;
|
|
113
|
+
/** Main render frame logic (called from RAF loop at display refresh rate). */
|
|
114
|
+
protected abstract onRenderFrame(): void;
|
|
115
|
+
/** Depth texture upload + filter (called from RVFC loop at video frame rate). */
|
|
116
|
+
protected abstract onDepthUpdate(timeSec: number): void;
|
|
117
|
+
/** Recalculate canvas size, FBOs, UV transform on resize. */
|
|
118
|
+
protected abstract recalculateViewportLayout(): void;
|
|
119
|
+
/** Release all GPU resources (called from dispose()). */
|
|
120
|
+
protected abstract disposeRenderer(): void;
|
|
121
|
+
/** Rebuild GPU state after context restoration. */
|
|
122
|
+
protected abstract onContextRestored(): void;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=renderer-base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer-base.d.ts","sourceRoot":"","sources":["../../src/renderer-base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared WebGL 2 utilities — compile, link, uniform caching, fullscreen quad.
|
|
3
|
+
*
|
|
4
|
+
* Used by both the parallax renderer and the portal renderer to avoid
|
|
5
|
+
* duplicating boilerplate GL setup code.
|
|
6
|
+
*/
|
|
7
|
+
/** Compile a GLSL shader, throwing on error. */
|
|
8
|
+
export declare function compileShader(gl: WebGL2RenderingContext, type: number, source: string): WebGLShader;
|
|
9
|
+
/** Link a shader program, throwing on error. */
|
|
10
|
+
export declare function linkProgram(gl: WebGL2RenderingContext, vertShader: WebGLShader, fragShader: WebGLShader): WebGLProgram;
|
|
11
|
+
/**
|
|
12
|
+
* Cache uniform locations for a set of uniform names.
|
|
13
|
+
*
|
|
14
|
+
* Returns a record mapping each name to its `WebGLUniformLocation | null`.
|
|
15
|
+
* Avoids repeated `getUniformLocation` calls per frame.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getUniformLocations(gl: WebGL2RenderingContext, program: WebGLProgram, names: readonly string[]): Record<string, WebGLUniformLocation | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Create a VAO for the standard fullscreen quad.
|
|
20
|
+
*
|
|
21
|
+
* The VAO binds a VBO with 4 clip-space vertices to the `aPosition`
|
|
22
|
+
* attribute (looked up from the given program). Draw with
|
|
23
|
+
* `gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)`.
|
|
24
|
+
*
|
|
25
|
+
* @param gl - WebGL 2 context
|
|
26
|
+
* @param program - Shader program to look up `aPosition` attribute location
|
|
27
|
+
*/
|
|
28
|
+
export declare function createFullscreenQuadVao(gl: WebGL2RenderingContext, program: WebGLProgram): WebGLVertexArrayObject;
|
|
29
|
+
//# sourceMappingURL=webgl-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgl-utils.d.ts","sourceRoot":"","sources":["../../src/webgl-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,gDAAgD;AAChD,wBAAgB,aAAa,CAC3B,EAAE,EAAE,sBAAsB,EAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,WAAW,CAWb;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CACzB,EAAE,EAAE,sBAAsB,EAC1B,UAAU,EAAE,WAAW,EACvB,UAAU,EAAE,WAAW,GACtB,YAAY,CAiBd;AAMD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,sBAAsB,EAC1B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC,CAM7C;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,sBAAsB,EAC1B,OAAO,EAAE,YAAY,GACpB,sBAAsB,CAiBxB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebGPU Utilities — shared helpers for WebGPU renderers.
|
|
3
|
+
*
|
|
4
|
+
* Parallel to `webgl-utils.ts` but for the WebGPU backend.
|
|
5
|
+
* Provides buffer creation, sampler factories, and fullscreen quad geometry.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Create a GPU buffer containing a fullscreen quad (triangle strip, 4 vertices).
|
|
9
|
+
*/
|
|
10
|
+
export declare function createFullscreenQuadBuffer(device: GPUDevice): GPUBuffer;
|
|
11
|
+
/**
|
|
12
|
+
* Create a GPU vertex buffer from Float32Array data.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createVertexBuffer(device: GPUDevice, data: Float32Array): GPUBuffer;
|
|
15
|
+
/**
|
|
16
|
+
* Create a GPU index buffer from Uint16Array data.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createIndexBuffer(device: GPUDevice, data: Uint16Array): GPUBuffer;
|
|
19
|
+
/**
|
|
20
|
+
* Create a GPU uniform buffer of the given byte size.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createUniformBuffer(device: GPUDevice, byteSize: number): GPUBuffer;
|
|
23
|
+
/**
|
|
24
|
+
* Create a 2D texture with common defaults for render targets.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createRenderTexture(device: GPUDevice, width: number, height: number, format?: GPUTextureFormat): GPUTexture;
|
|
27
|
+
/**
|
|
28
|
+
* Create a 2D texture for sampling (e.g., video frame, depth data).
|
|
29
|
+
*/
|
|
30
|
+
export declare function createSampleTexture(device: GPUDevice, width: number, height: number, format?: GPUTextureFormat): GPUTexture;
|
|
31
|
+
/** Create a linear-filtering, clamp-to-edge sampler. */
|
|
32
|
+
export declare function createLinearSampler(device: GPUDevice): GPUSampler;
|
|
33
|
+
/** Create a nearest-filtering, clamp-to-edge sampler. */
|
|
34
|
+
export declare function createNearestSampler(device: GPUDevice): GPUSampler;
|
|
35
|
+
/**
|
|
36
|
+
* Import a video frame into a WebGPU texture using `copyExternalImageToTexture`.
|
|
37
|
+
*
|
|
38
|
+
* This is the WebGPU equivalent of `gl.texImage2D(gl.TEXTURE_2D, ..., video)`.
|
|
39
|
+
* On supported browsers, this is a zero-copy operation.
|
|
40
|
+
*/
|
|
41
|
+
export declare function importVideoFrame(device: GPUDevice, texture: GPUTexture, video: HTMLVideoElement, flipY?: boolean): void;
|
|
42
|
+
//# sourceMappingURL=webgpu-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgpu-utils.d.ts","sourceRoot":"","sources":["../../src/webgpu-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CASvE;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,SAAS,CASnF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,CASjF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAOlF;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,gBAA+B,GACtC,UAAU,CAMZ;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,gBAA+B,GACtC,UAAU,CASZ;AAMD,wDAAwD;AACxD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAOjE;AAED,yDAAyD;AACzD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAOlE;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,gBAAgB,EACvB,KAAK,UAAO,GACX,IAAI,CAMN"}
|