vireglass 2.2.0 → 2.3.1
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 +39 -0
- package/dist/{adapters-DugC6Qri.d.cts → adapters-BOPIRMnL.d.cts} +3 -1
- package/dist/{adapters-BfeAopGO.d.ts → adapters-B_amRBqc.d.ts} +3 -1
- package/dist/{chunk-2XJJO7SC.js → chunk-UDPJLNFW.js} +25 -5
- package/dist/chunk-UDPJLNFW.js.map +1 -0
- package/dist/{chunk-H5QTBF67.js → chunk-V47YU75P.js} +2 -2
- package/dist/{chunk-H5QTBF67.js.map → chunk-V47YU75P.js.map} +1 -1
- package/dist/dom.cjs.map +1 -1
- package/dist/dom.d.cts +1 -1
- package/dist/dom.d.ts +1 -1
- package/dist/dom.js +1 -1
- package/dist/dom.js.map +1 -1
- package/dist/index.cjs +22 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -4
- package/dist/index.d.ts +13 -4
- package/dist/index.js +2 -2
- package/dist/web/index.cjs +282 -152
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.d.cts +89 -3
- package/dist/web/index.d.ts +89 -3
- package/dist/web/index.js +255 -154
- package/dist/web/index.js.map +1 -1
- package/package.json +4 -2
- package/src/adapters.ts +3 -1
- package/src/dom/index.ts +6 -5
- package/src/targets/glsl.ts +31 -2
- package/src/web/gl.ts +57 -4
- package/src/web/gpu-timer.ts +111 -0
- package/src/web/index.ts +1 -0
- package/src/web/renderer.ts +305 -218
- package/dist/chunk-2XJJO7SC.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { V as VireGlassOptics } from './material-CnUmdKg1.cjs';
|
|
2
2
|
export { A as ADAPT_RADIUS, b as ALL_EFFECTS_ON, D as DEBUG_MODES, E as EFFECTS, L as LEGACY_NAMES, c as LEGACY_OPTICS, d as LegacyOpticsName, M as MATERIAL_PRESETS, e as MATERIAL_RANGES, f as MaterialPresetName, P as PRESET_NAMES, g as PRODUCT_DIM, h as VIREGLASS_CLEAR_MATERIAL, i as VIREGLASS_CONTROL_MATERIAL, j as VIREGLASS_LYRICS_MATERIAL, k as VIREGLASS_MATERIAL, l as VIREGLASS_MATERIAL_V4, m as VIREGLASS_MATERIAL_V5, n as VIREGLASS_SHEET_MATERIAL, o as VireGlassDebugMode, p as VireGlassEffect, a as VireGlassMaterial, q as VireGlassNumericKey, r as VireGlassTint, s as VireGlassToggles, t as activeMaterial, u as applyToggles, v as debugIndex, w as materialForInk, x as resolveMaterial, y as resolveOptics } from './material-CnUmdKg1.cjs';
|
|
3
3
|
export { M as MAX_BEVEL_FRACTION, a as MAX_STRETCH, R as RIM_FRACTION, V as VireGlassGeometry, b as bevelDp, c as bevelFraction, d as capsuleGeometry, e as circleGeometry, h as halfMinDp, l as lensPadDp, m as morphReachDp, r as rimDp, f as roundedRectGeometry, s as shadowOpacity, g as shadowOpacityFrom, i as shadowReachDp, j as sizeDp, k as sizeGain, n as surfacePadDp, t as thicknessDp } from './geometry-RhKd7CM5.cjs';
|
|
4
|
-
import { V as VireGlassAccent } from './adapters-
|
|
5
|
-
export { A as ACCENT_AMOUNT, D as DYNAMIC_UNIFORMS, I as ICON_UNIFORMS, O as OVERLAY_UNIFORMS, R as REST_LIGHT, S as SURFACE_LENGTH_UNIFORMS, a as SurfaceUniforms, b as VireGlassMorph, c as VireGlassTouch, l as lensMagnify, m as morphBetween, d as morphOutOf, t as toDeviceSurfaceUniforms, e as toLensProps, f as toSurfaceUniforms } from './adapters-
|
|
4
|
+
import { V as VireGlassAccent } from './adapters-BOPIRMnL.cjs';
|
|
5
|
+
export { A as ACCENT_AMOUNT, D as DYNAMIC_UNIFORMS, I as ICON_UNIFORMS, O as OVERLAY_UNIFORMS, R as REST_LIGHT, S as SURFACE_LENGTH_UNIFORMS, a as SurfaceUniforms, b as VireGlassMorph, c as VireGlassTouch, l as lensMagnify, m as morphBetween, d as morphOutOf, t as toDeviceSurfaceUniforms, e as toLensProps, f as toSurfaceUniforms } from './adapters-BOPIRMnL.cjs';
|
|
6
6
|
export { a as GRADIENT, b as GroupDecision, c as GroupMember, G as GroupPlane, d as GroupSink, e as GroupState, M as MorphShape, N as NO_ACCESSIBILITY, f as SCROLL_EDGE_ENGAGE_DP, g as SETTLE, h as SMOOTH, S as ScrollEdgeStyle, T as TouchWarp, i as VG_FALLOFF, j as VG_SDF, V as VireGlassAccessibility, k as aggregate, l as applyAccessibility, m as contrastRimLuma, n as createGroupState, o as elasticAllowed, p as neckToBridge, q as probeValuesAt, s as sceneDistance, r as sceneGradient, t as scrollEdgeReachDp, u as scrollEdgeStrength, v as scrollEdgeStyle, w as sdfRoundedRect, x as sdfRoundedRectGradient, y as smin, z as smoothPlane, A as touchWarp } from './group-model-DwtixGhG.cjs';
|
|
7
7
|
export { B as BackdropSample, C as CONFIRMATIONS, F as FADE_MS, a as FLIP_LUMA, I as INK_DARK, b as INK_LIGHT, R as RETURN_LUMA, c as ambientFrom, d as decisiveLuma, s as shouldInkBeLight } from './adaptation-BSbbdExK.cjs';
|
|
8
8
|
|
|
@@ -275,11 +275,16 @@ declare function convertShaderUniforms(src: string): string;
|
|
|
275
275
|
* parentheses inside.
|
|
276
276
|
*/
|
|
277
277
|
declare function convertEvalCalls(src: string): string;
|
|
278
|
+
/** Comments are prose, and the rewrites here are regexes over raw text: a comment mentioning
|
|
279
|
+
* "return" became one, and a brace in a comment ended the entry point early. Newlines inside
|
|
280
|
+
* block comments survive, so a compile error still points at the source line. */
|
|
281
|
+
declare function stripComments(src: string): string;
|
|
278
282
|
/**
|
|
279
283
|
* Early `return <expression>;` inside `main` → `fragColor = <expression>; return;`. Takes ONLY
|
|
280
284
|
* the body of main (see `convertEntryPoint`) — ordinary `return`s in helper functions live
|
|
281
285
|
* outside this text and are untouched. Expressions never contain a `;` of their own (shaders have
|
|
282
|
-
* none — the only `;` lives inside `for(...)`, which isn't a return), so `[^;]+` is safe
|
|
286
|
+
* none — the only `;` lives inside `for(...)`, which isn't a return), so `[^;]+` is safe once
|
|
287
|
+
* comments are gone (`stripComments`).
|
|
283
288
|
*/
|
|
284
289
|
declare function convertReturns(mainBody: string): string;
|
|
285
290
|
/**
|
|
@@ -288,6 +293,10 @@ declare function convertReturns(mainBody: string): string;
|
|
|
288
293
|
* origin, y up. The flip via `u_resolution.y - gl_FragCoord.y` restores the original convention
|
|
289
294
|
* (both coordinate systems center the pixel at `+0.5`, so no X shift or constant is needed).
|
|
290
295
|
* `out vec4 fragColor` and `uniform vec2 u_resolution` are declared in the prologue (`addPrologue`).
|
|
296
|
+
*
|
|
297
|
+
* `xy` and `.eval()` are flipped together — but only inside a shader THIS function translates. A
|
|
298
|
+
* `VireGlassBackdropPass` (`web/renderer.ts`) that reads its own previous frame from an FBO is raw
|
|
299
|
+
* `gl_FragCoord`, unflipped; reusing AGSL-style helpers there needs an explicit flip of its own.
|
|
291
300
|
*/
|
|
292
301
|
declare function convertEntryPoint(src: string): string;
|
|
293
302
|
/** `#version 300 es` + `precision highp float;` — no equivalent in AGSL, WebGL2 requires them as
|
|
@@ -300,4 +309,4 @@ declare function addPrologue(src: string): string;
|
|
|
300
309
|
* found. */
|
|
301
310
|
declare function toGLSL(shaderSource: string): string;
|
|
302
311
|
|
|
303
|
-
export { type DeformOptions, type DeformSample, FRESNEL_EXPONENT, GLASS_SCALE_DEFAULT, LENS_SHADER, SURFACE_SHADER, type ShapeParent, type ShapeSpec, VireGlassAccent, VireGlassOptics, absorption, accentAmount, accentTone, addPrologue, applyAppear, applyGlassScale, blur, bodyDensity, colorPickup, concentricFit, concentricInset, concentricRadius, convertEntryPoint, convertEvalCalls, convertHalfTypes, convertReturns, convertShaderUniforms, convertVecTypes, createDeform, diffraction, dispersion, edgeDensity, edgeLight, fresnelF0, fresnelStrength, gatherRadius, iorSpread, iridescence, mediumTint, raiseIntoGlass, refractionScale, refractionStrength, resolveShape, shadowTint, specularPower, specularStrength, toAGSL, toGLSL };
|
|
312
|
+
export { type DeformOptions, type DeformSample, FRESNEL_EXPONENT, GLASS_SCALE_DEFAULT, LENS_SHADER, SURFACE_SHADER, type ShapeParent, type ShapeSpec, VireGlassAccent, VireGlassOptics, absorption, accentAmount, accentTone, addPrologue, applyAppear, applyGlassScale, blur, bodyDensity, colorPickup, concentricFit, concentricInset, concentricRadius, convertEntryPoint, convertEvalCalls, convertHalfTypes, convertReturns, convertShaderUniforms, convertVecTypes, createDeform, diffraction, dispersion, edgeDensity, edgeLight, fresnelF0, fresnelStrength, gatherRadius, iorSpread, iridescence, mediumTint, raiseIntoGlass, refractionScale, refractionStrength, resolveShape, shadowTint, specularPower, specularStrength, stripComments, toAGSL, toGLSL };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { V as VireGlassOptics } from './material-CnUmdKg1.js';
|
|
2
2
|
export { A as ADAPT_RADIUS, b as ALL_EFFECTS_ON, D as DEBUG_MODES, E as EFFECTS, L as LEGACY_NAMES, c as LEGACY_OPTICS, d as LegacyOpticsName, M as MATERIAL_PRESETS, e as MATERIAL_RANGES, f as MaterialPresetName, P as PRESET_NAMES, g as PRODUCT_DIM, h as VIREGLASS_CLEAR_MATERIAL, i as VIREGLASS_CONTROL_MATERIAL, j as VIREGLASS_LYRICS_MATERIAL, k as VIREGLASS_MATERIAL, l as VIREGLASS_MATERIAL_V4, m as VIREGLASS_MATERIAL_V5, n as VIREGLASS_SHEET_MATERIAL, o as VireGlassDebugMode, p as VireGlassEffect, a as VireGlassMaterial, q as VireGlassNumericKey, r as VireGlassTint, s as VireGlassToggles, t as activeMaterial, u as applyToggles, v as debugIndex, w as materialForInk, x as resolveMaterial, y as resolveOptics } from './material-CnUmdKg1.js';
|
|
3
3
|
export { M as MAX_BEVEL_FRACTION, a as MAX_STRETCH, R as RIM_FRACTION, V as VireGlassGeometry, b as bevelDp, c as bevelFraction, d as capsuleGeometry, e as circleGeometry, h as halfMinDp, l as lensPadDp, m as morphReachDp, r as rimDp, f as roundedRectGeometry, s as shadowOpacity, g as shadowOpacityFrom, i as shadowReachDp, j as sizeDp, k as sizeGain, n as surfacePadDp, t as thicknessDp } from './geometry-GvXtt-_S.js';
|
|
4
|
-
import { V as VireGlassAccent } from './adapters-
|
|
5
|
-
export { A as ACCENT_AMOUNT, D as DYNAMIC_UNIFORMS, I as ICON_UNIFORMS, O as OVERLAY_UNIFORMS, R as REST_LIGHT, S as SURFACE_LENGTH_UNIFORMS, a as SurfaceUniforms, b as VireGlassMorph, c as VireGlassTouch, l as lensMagnify, m as morphBetween, d as morphOutOf, t as toDeviceSurfaceUniforms, e as toLensProps, f as toSurfaceUniforms } from './adapters-
|
|
4
|
+
import { V as VireGlassAccent } from './adapters-B_amRBqc.js';
|
|
5
|
+
export { A as ACCENT_AMOUNT, D as DYNAMIC_UNIFORMS, I as ICON_UNIFORMS, O as OVERLAY_UNIFORMS, R as REST_LIGHT, S as SURFACE_LENGTH_UNIFORMS, a as SurfaceUniforms, b as VireGlassMorph, c as VireGlassTouch, l as lensMagnify, m as morphBetween, d as morphOutOf, t as toDeviceSurfaceUniforms, e as toLensProps, f as toSurfaceUniforms } from './adapters-B_amRBqc.js';
|
|
6
6
|
export { a as GRADIENT, b as GroupDecision, c as GroupMember, G as GroupPlane, d as GroupSink, e as GroupState, M as MorphShape, N as NO_ACCESSIBILITY, f as SCROLL_EDGE_ENGAGE_DP, g as SETTLE, h as SMOOTH, S as ScrollEdgeStyle, T as TouchWarp, i as VG_FALLOFF, j as VG_SDF, V as VireGlassAccessibility, k as aggregate, l as applyAccessibility, m as contrastRimLuma, n as createGroupState, o as elasticAllowed, p as neckToBridge, q as probeValuesAt, s as sceneDistance, r as sceneGradient, t as scrollEdgeReachDp, u as scrollEdgeStrength, v as scrollEdgeStyle, w as sdfRoundedRect, x as sdfRoundedRectGradient, y as smin, z as smoothPlane, A as touchWarp } from './group-model-z4N27qsC.js';
|
|
7
7
|
export { B as BackdropSample, C as CONFIRMATIONS, F as FADE_MS, a as FLIP_LUMA, I as INK_DARK, b as INK_LIGHT, R as RETURN_LUMA, c as ambientFrom, d as decisiveLuma, s as shouldInkBeLight } from './adaptation-BSbbdExK.js';
|
|
8
8
|
|
|
@@ -275,11 +275,16 @@ declare function convertShaderUniforms(src: string): string;
|
|
|
275
275
|
* parentheses inside.
|
|
276
276
|
*/
|
|
277
277
|
declare function convertEvalCalls(src: string): string;
|
|
278
|
+
/** Comments are prose, and the rewrites here are regexes over raw text: a comment mentioning
|
|
279
|
+
* "return" became one, and a brace in a comment ended the entry point early. Newlines inside
|
|
280
|
+
* block comments survive, so a compile error still points at the source line. */
|
|
281
|
+
declare function stripComments(src: string): string;
|
|
278
282
|
/**
|
|
279
283
|
* Early `return <expression>;` inside `main` → `fragColor = <expression>; return;`. Takes ONLY
|
|
280
284
|
* the body of main (see `convertEntryPoint`) — ordinary `return`s in helper functions live
|
|
281
285
|
* outside this text and are untouched. Expressions never contain a `;` of their own (shaders have
|
|
282
|
-
* none — the only `;` lives inside `for(...)`, which isn't a return), so `[^;]+` is safe
|
|
286
|
+
* none — the only `;` lives inside `for(...)`, which isn't a return), so `[^;]+` is safe once
|
|
287
|
+
* comments are gone (`stripComments`).
|
|
283
288
|
*/
|
|
284
289
|
declare function convertReturns(mainBody: string): string;
|
|
285
290
|
/**
|
|
@@ -288,6 +293,10 @@ declare function convertReturns(mainBody: string): string;
|
|
|
288
293
|
* origin, y up. The flip via `u_resolution.y - gl_FragCoord.y` restores the original convention
|
|
289
294
|
* (both coordinate systems center the pixel at `+0.5`, so no X shift or constant is needed).
|
|
290
295
|
* `out vec4 fragColor` and `uniform vec2 u_resolution` are declared in the prologue (`addPrologue`).
|
|
296
|
+
*
|
|
297
|
+
* `xy` and `.eval()` are flipped together — but only inside a shader THIS function translates. A
|
|
298
|
+
* `VireGlassBackdropPass` (`web/renderer.ts`) that reads its own previous frame from an FBO is raw
|
|
299
|
+
* `gl_FragCoord`, unflipped; reusing AGSL-style helpers there needs an explicit flip of its own.
|
|
291
300
|
*/
|
|
292
301
|
declare function convertEntryPoint(src: string): string;
|
|
293
302
|
/** `#version 300 es` + `precision highp float;` — no equivalent in AGSL, WebGL2 requires them as
|
|
@@ -300,4 +309,4 @@ declare function addPrologue(src: string): string;
|
|
|
300
309
|
* found. */
|
|
301
310
|
declare function toGLSL(shaderSource: string): string;
|
|
302
311
|
|
|
303
|
-
export { type DeformOptions, type DeformSample, FRESNEL_EXPONENT, GLASS_SCALE_DEFAULT, LENS_SHADER, SURFACE_SHADER, type ShapeParent, type ShapeSpec, VireGlassAccent, VireGlassOptics, absorption, accentAmount, accentTone, addPrologue, applyAppear, applyGlassScale, blur, bodyDensity, colorPickup, concentricFit, concentricInset, concentricRadius, convertEntryPoint, convertEvalCalls, convertHalfTypes, convertReturns, convertShaderUniforms, convertVecTypes, createDeform, diffraction, dispersion, edgeDensity, edgeLight, fresnelF0, fresnelStrength, gatherRadius, iorSpread, iridescence, mediumTint, raiseIntoGlass, refractionScale, refractionStrength, resolveShape, shadowTint, specularPower, specularStrength, toAGSL, toGLSL };
|
|
312
|
+
export { type DeformOptions, type DeformSample, FRESNEL_EXPONENT, GLASS_SCALE_DEFAULT, LENS_SHADER, SURFACE_SHADER, type ShapeParent, type ShapeSpec, VireGlassAccent, VireGlassOptics, absorption, accentAmount, accentTone, addPrologue, applyAppear, applyGlassScale, blur, bodyDensity, colorPickup, concentricFit, concentricInset, concentricRadius, convertEntryPoint, convertEvalCalls, convertHalfTypes, convertReturns, convertShaderUniforms, convertVecTypes, createDeform, diffraction, dispersion, edgeDensity, edgeLight, fresnelF0, fresnelStrength, gatherRadius, iorSpread, iridescence, mediumTint, raiseIntoGlass, refractionScale, refractionStrength, resolveShape, shadowTint, specularPower, specularStrength, stripComments, toAGSL, toGLSL };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { SURFACE_SHADER, addPrologue, convertEntryPoint, convertEvalCalls, convertHalfTypes, convertReturns, convertShaderUniforms, convertVecTypes, toGLSL } from './chunk-
|
|
1
|
+
export { SURFACE_SHADER, addPrologue, convertEntryPoint, convertEvalCalls, convertHalfTypes, convertReturns, convertShaderUniforms, convertVecTypes, stripComments, toGLSL } from './chunk-UDPJLNFW.js';
|
|
2
2
|
export { GLASS_SCALE_DEFAULT, GRADIENT, NO_ACCESSIBILITY, SCROLL_EDGE_ENGAGE_DP, SETTLE, SMOOTH, accentAmount, accentTone, aggregate, applyAccessibility, applyAppear, applyGlassScale, concentricFit, concentricInset, concentricRadius, contrastRimLuma, createDeform, createGroupState, elasticAllowed, probeValuesAt, raiseIntoGlass, resolveShape, scrollEdgeReachDp, scrollEdgeStrength, scrollEdgeStyle, shadowTint, smoothPlane } from './chunk-CTTZNZFV.js';
|
|
3
3
|
export { CONFIRMATIONS, FADE_MS, FLIP_LUMA, INK_DARK, INK_LIGHT, RETURN_LUMA, ambientFrom, decisiveLuma, shouldInkBeLight } from './chunk-JNRZNMJJ.js';
|
|
4
|
-
export { ACCENT_AMOUNT, ADAPT_RADIUS, ALL_EFFECTS_ON, DEBUG_MODES, DYNAMIC_UNIFORMS, EFFECTS, FRESNEL_EXPONENT, ICON_UNIFORMS, LEGACY_NAMES, LEGACY_OPTICS, LENS_SHADER, MATERIAL_PRESETS, MATERIAL_RANGES, OVERLAY_UNIFORMS, PRESET_NAMES, PRODUCT_DIM, REST_LIGHT, SURFACE_LENGTH_UNIFORMS, VG_FALLOFF, VG_SDF, VIREGLASS_CLEAR_MATERIAL, VIREGLASS_CONTROL_MATERIAL, VIREGLASS_LYRICS_MATERIAL, VIREGLASS_MATERIAL, VIREGLASS_MATERIAL_V4, VIREGLASS_MATERIAL_V5, VIREGLASS_SHEET_MATERIAL, absorption, activeMaterial, applyToggles, blur, bodyDensity, colorPickup, debugIndex, diffraction, dispersion, edgeDensity, edgeLight, fresnelF0, fresnelStrength, gatherRadius, iorSpread, iridescence, lensMagnify, materialForInk, mediumTint, morphBetween, morphOutOf, neckToBridge, refractionScale, refractionStrength, resolveMaterial, resolveOptics, sceneDistance, sceneGradient, sdfRoundedRect, sdfRoundedRectGradient, smin, specularPower, specularStrength, toDeviceSurfaceUniforms, toLensProps, toSurfaceUniforms, touchWarp } from './chunk-
|
|
4
|
+
export { ACCENT_AMOUNT, ADAPT_RADIUS, ALL_EFFECTS_ON, DEBUG_MODES, DYNAMIC_UNIFORMS, EFFECTS, FRESNEL_EXPONENT, ICON_UNIFORMS, LEGACY_NAMES, LEGACY_OPTICS, LENS_SHADER, MATERIAL_PRESETS, MATERIAL_RANGES, OVERLAY_UNIFORMS, PRESET_NAMES, PRODUCT_DIM, REST_LIGHT, SURFACE_LENGTH_UNIFORMS, VG_FALLOFF, VG_SDF, VIREGLASS_CLEAR_MATERIAL, VIREGLASS_CONTROL_MATERIAL, VIREGLASS_LYRICS_MATERIAL, VIREGLASS_MATERIAL, VIREGLASS_MATERIAL_V4, VIREGLASS_MATERIAL_V5, VIREGLASS_SHEET_MATERIAL, absorption, activeMaterial, applyToggles, blur, bodyDensity, colorPickup, debugIndex, diffraction, dispersion, edgeDensity, edgeLight, fresnelF0, fresnelStrength, gatherRadius, iorSpread, iridescence, lensMagnify, materialForInk, mediumTint, morphBetween, morphOutOf, neckToBridge, refractionScale, refractionStrength, resolveMaterial, resolveOptics, sceneDistance, sceneGradient, sdfRoundedRect, sdfRoundedRectGradient, smin, specularPower, specularStrength, toDeviceSurfaceUniforms, toLensProps, toSurfaceUniforms, touchWarp } from './chunk-V47YU75P.js';
|
|
5
5
|
export { MAX_BEVEL_FRACTION, MAX_STRETCH, RIM_FRACTION, bevelDp, bevelFraction, capsuleGeometry, circleGeometry, halfMinDp, lensPadDp, morphReachDp, rimDp, roundedRectGeometry, shadowOpacity, shadowOpacityFrom, shadowReachDp, sizeDp, sizeGain, surfacePadDp, thicknessDp } from './chunk-SLRPHDV7.js';
|
|
6
6
|
import './chunk-MMPK6DCK.js';
|
|
7
7
|
|
package/dist/web/index.cjs
CHANGED
|
@@ -1459,6 +1459,26 @@ function convertEvalCalls(src) {
|
|
|
1459
1459
|
out += src.slice(cursor);
|
|
1460
1460
|
return out;
|
|
1461
1461
|
}
|
|
1462
|
+
function stripComments(src) {
|
|
1463
|
+
let out = "";
|
|
1464
|
+
let i = 0;
|
|
1465
|
+
while (i < src.length) {
|
|
1466
|
+
if (src.startsWith("//", i)) {
|
|
1467
|
+
const end = src.indexOf("\n", i);
|
|
1468
|
+
i = end < 0 ? src.length : end;
|
|
1469
|
+
} else if (src.startsWith("/*", i)) {
|
|
1470
|
+
const end = src.indexOf("*/", i + 2);
|
|
1471
|
+
if (end < 0) throw new Error("vireglass/targets/glsl: unterminated block comment");
|
|
1472
|
+
const stop = end + 2;
|
|
1473
|
+
out += src.slice(i, stop).replace(/[^\n]/g, "");
|
|
1474
|
+
i = stop;
|
|
1475
|
+
} else {
|
|
1476
|
+
out += src[i];
|
|
1477
|
+
i += 1;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
return out;
|
|
1481
|
+
}
|
|
1462
1482
|
function convertReturns(mainBody) {
|
|
1463
1483
|
return mainBody.replace(/\breturn\s+([^;]+);/g, "fragColor = $1; return;");
|
|
1464
1484
|
}
|
|
@@ -1489,7 +1509,7 @@ function addPrologue(src) {
|
|
|
1489
1509
|
return "#version 300 es\nprecision highp float;\n\nout vec4 fragColor;\nuniform vec2 u_resolution;\n\n" + src;
|
|
1490
1510
|
}
|
|
1491
1511
|
function toGLSL(shaderSource) {
|
|
1492
|
-
let out = shaderSource;
|
|
1512
|
+
let out = stripComments(shaderSource);
|
|
1493
1513
|
out = convertEntryPoint(out);
|
|
1494
1514
|
out = convertShaderUniforms(out);
|
|
1495
1515
|
out = convertEvalCalls(out);
|
|
@@ -1546,6 +1566,7 @@ function createTexture(gl, options) {
|
|
|
1546
1566
|
const internalFormat = options.internalFormat ?? gl.RGBA8;
|
|
1547
1567
|
const format = options.format ?? gl.RGBA;
|
|
1548
1568
|
const type = options.type ?? gl.UNSIGNED_BYTE;
|
|
1569
|
+
const wrap = options.wrap ?? gl.CLAMP_TO_EDGE;
|
|
1549
1570
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
1550
1571
|
gl.texImage2D(
|
|
1551
1572
|
gl.TEXTURE_2D,
|
|
@@ -1560,11 +1581,45 @@ function createTexture(gl, options) {
|
|
|
1560
1581
|
);
|
|
1561
1582
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1562
1583
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1563
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S,
|
|
1564
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T,
|
|
1584
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);
|
|
1585
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);
|
|
1565
1586
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
1566
1587
|
return texture;
|
|
1567
1588
|
}
|
|
1589
|
+
function locationCache(gl, program) {
|
|
1590
|
+
const cache = /* @__PURE__ */ new Map();
|
|
1591
|
+
return (name) => {
|
|
1592
|
+
let loc = cache.get(name);
|
|
1593
|
+
if (loc === void 0) {
|
|
1594
|
+
loc = gl.getUniformLocation(program, name);
|
|
1595
|
+
cache.set(name, loc);
|
|
1596
|
+
}
|
|
1597
|
+
return loc;
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1600
|
+
function setUniform(gl, loc, value) {
|
|
1601
|
+
if (!loc) return;
|
|
1602
|
+
if (typeof value === "number") {
|
|
1603
|
+
gl.uniform1f(loc, value);
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1606
|
+
switch (value.length) {
|
|
1607
|
+
case 1:
|
|
1608
|
+
gl.uniform1f(loc, value[0]);
|
|
1609
|
+
break;
|
|
1610
|
+
case 2:
|
|
1611
|
+
gl.uniform2f(loc, value[0], value[1]);
|
|
1612
|
+
break;
|
|
1613
|
+
case 3:
|
|
1614
|
+
gl.uniform3f(loc, value[0], value[1], value[2]);
|
|
1615
|
+
break;
|
|
1616
|
+
case 4:
|
|
1617
|
+
gl.uniform4f(loc, value[0], value[1], value[2], value[3]);
|
|
1618
|
+
break;
|
|
1619
|
+
default:
|
|
1620
|
+
throw new Error(`vireglass/web: unsupported uniform size (${value.length})`);
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1568
1623
|
function createFramebuffer(gl, texture) {
|
|
1569
1624
|
const fbo = gl.createFramebuffer();
|
|
1570
1625
|
if (!fbo) throw new Error("vireglass/web: gl.createFramebuffer returned null");
|
|
@@ -1584,6 +1639,62 @@ function bindTextureAt(gl, unit, texture, program, uniformName) {
|
|
|
1584
1639
|
gl.uniform1i(loc, unit);
|
|
1585
1640
|
}
|
|
1586
1641
|
|
|
1642
|
+
// src/web/gpu-timer.ts
|
|
1643
|
+
var GPU_TIMER_RING_SIZE = 3;
|
|
1644
|
+
function createGpuTimer(gl) {
|
|
1645
|
+
const ext = gl.getExtension("EXT_disjoint_timer_query_webgl2");
|
|
1646
|
+
const slots = ext ? Array.from({ length: GPU_TIMER_RING_SIZE }, () => ({
|
|
1647
|
+
query: gl.createQuery(),
|
|
1648
|
+
pending: false
|
|
1649
|
+
})) : [];
|
|
1650
|
+
let cursor = 0;
|
|
1651
|
+
let active = null;
|
|
1652
|
+
let lastMs = null;
|
|
1653
|
+
function poll() {
|
|
1654
|
+
if (!ext) return;
|
|
1655
|
+
for (const slot of slots) {
|
|
1656
|
+
if (!slot.pending) continue;
|
|
1657
|
+
if (!gl.getQueryParameter(slot.query, gl.QUERY_RESULT_AVAILABLE)) continue;
|
|
1658
|
+
slot.pending = false;
|
|
1659
|
+
if (gl.getParameter(ext.GPU_DISJOINT_EXT)) continue;
|
|
1660
|
+
const ns = gl.getQueryParameter(slot.query, gl.QUERY_RESULT);
|
|
1661
|
+
lastMs = ns / 1e6;
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
function begin() {
|
|
1665
|
+
active = null;
|
|
1666
|
+
if (!ext || slots.length === 0) return;
|
|
1667
|
+
poll();
|
|
1668
|
+
const slot = slots[cursor];
|
|
1669
|
+
if (slot.pending) return;
|
|
1670
|
+
gl.beginQuery(ext.TIME_ELAPSED_EXT, slot.query);
|
|
1671
|
+
active = slot;
|
|
1672
|
+
}
|
|
1673
|
+
function end() {
|
|
1674
|
+
if (!ext || !active) return;
|
|
1675
|
+
gl.endQuery(ext.TIME_ELAPSED_EXT);
|
|
1676
|
+
active.pending = true;
|
|
1677
|
+
cursor = (cursor + 1) % slots.length;
|
|
1678
|
+
active = null;
|
|
1679
|
+
}
|
|
1680
|
+
function time(fn) {
|
|
1681
|
+
begin();
|
|
1682
|
+
try {
|
|
1683
|
+
return fn();
|
|
1684
|
+
} finally {
|
|
1685
|
+
end();
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
function getLastMs() {
|
|
1689
|
+
poll();
|
|
1690
|
+
return lastMs;
|
|
1691
|
+
}
|
|
1692
|
+
function destroy() {
|
|
1693
|
+
for (const slot of slots) gl.deleteQuery(slot.query);
|
|
1694
|
+
}
|
|
1695
|
+
return { time, getLastMs, destroy };
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1587
1698
|
// src/web/probe.ts
|
|
1588
1699
|
var PROBE_GRID_WIDTH = 48;
|
|
1589
1700
|
var PROBE_GRID_HEIGHT = 96;
|
|
@@ -1804,40 +1915,6 @@ void main() {
|
|
|
1804
1915
|
fragColor = texture(u_content, uv);
|
|
1805
1916
|
}
|
|
1806
1917
|
`;
|
|
1807
|
-
function locationCache(gl, program) {
|
|
1808
|
-
const cache = /* @__PURE__ */ new Map();
|
|
1809
|
-
return (name) => {
|
|
1810
|
-
let loc = cache.get(name);
|
|
1811
|
-
if (loc === void 0) {
|
|
1812
|
-
loc = gl.getUniformLocation(program, name);
|
|
1813
|
-
cache.set(name, loc);
|
|
1814
|
-
}
|
|
1815
|
-
return loc;
|
|
1816
|
-
};
|
|
1817
|
-
}
|
|
1818
|
-
function setUniform(gl, loc, value) {
|
|
1819
|
-
if (!loc) return;
|
|
1820
|
-
if (typeof value === "number") {
|
|
1821
|
-
gl.uniform1f(loc, value);
|
|
1822
|
-
return;
|
|
1823
|
-
}
|
|
1824
|
-
switch (value.length) {
|
|
1825
|
-
case 1:
|
|
1826
|
-
gl.uniform1f(loc, value[0]);
|
|
1827
|
-
break;
|
|
1828
|
-
case 2:
|
|
1829
|
-
gl.uniform2f(loc, value[0], value[1]);
|
|
1830
|
-
break;
|
|
1831
|
-
case 3:
|
|
1832
|
-
gl.uniform3f(loc, value[0], value[1], value[2]);
|
|
1833
|
-
break;
|
|
1834
|
-
case 4:
|
|
1835
|
-
gl.uniform4f(loc, value[0], value[1], value[2], value[3]);
|
|
1836
|
-
break;
|
|
1837
|
-
default:
|
|
1838
|
-
throw new Error(`vireglass/web: unsupported uniform size (${value.length})`);
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
1918
|
function applyChannel(gl, get, names, sizes, values) {
|
|
1842
1919
|
let cursor = 0;
|
|
1843
1920
|
for (let i = 0; i < names.length; i += 1) {
|
|
@@ -1900,6 +1977,12 @@ function createVireGlassRenderer(canvas) {
|
|
|
1900
1977
|
width: Math.max(width, 1),
|
|
1901
1978
|
height: Math.max(height, 1)
|
|
1902
1979
|
});
|
|
1980
|
+
let backdropFbo = null;
|
|
1981
|
+
function ensureBackdropFbo() {
|
|
1982
|
+
if (!backdropFbo) backdropFbo = createFramebuffer(gl, contentTexture);
|
|
1983
|
+
return backdropFbo;
|
|
1984
|
+
}
|
|
1985
|
+
const gpuTimer = createGpuTimer(gl);
|
|
1903
1986
|
const iconTexture = createTexture(gl, { width: 1, height: 1 });
|
|
1904
1987
|
const colorTexture = createTexture(gl, { width: 1, height: 1 });
|
|
1905
1988
|
gl.bindTexture(gl.TEXTURE_2D, iconTexture);
|
|
@@ -1928,128 +2011,164 @@ function createVireGlassRenderer(canvas) {
|
|
|
1928
2011
|
if (!sceneCtx) throw new Error("vireglass/web: scene 2D context unavailable");
|
|
1929
2012
|
gl.deleteTexture(contentTexture);
|
|
1930
2013
|
contentTexture = createTexture(gl, { width, height });
|
|
2014
|
+
if (backdropFbo) {
|
|
2015
|
+
gl.deleteFramebuffer(backdropFbo);
|
|
2016
|
+
backdropFbo = null;
|
|
2017
|
+
}
|
|
1931
2018
|
}
|
|
1932
2019
|
function render(options) {
|
|
1933
2020
|
if (!sceneCtx) throw new Error("vireglass/web: renderer not initialized (resize was never called)");
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
if (options.colorLayer) {
|
|
1940
|
-
gl.bindTexture(gl.TEXTURE_2D, colorTexture);
|
|
1941
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, options.colorLayer);
|
|
2021
|
+
const ctx = sceneCtx;
|
|
2022
|
+
if (options.backdrop && options.scene) {
|
|
2023
|
+
throw new Error(
|
|
2024
|
+
"vireglass/web: render() needs exactly one of options.scene or options.backdrop, not both"
|
|
2025
|
+
);
|
|
1942
2026
|
}
|
|
1943
|
-
if (options.
|
|
1944
|
-
|
|
1945
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, options.iconMask);
|
|
1946
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
2027
|
+
if (!options.backdrop && !options.scene) {
|
|
2028
|
+
throw new Error("vireglass/web: render() needs either options.scene or options.backdrop");
|
|
1947
2029
|
}
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
const stats = fresh ? settleStats(index, fresh) : null;
|
|
1969
|
-
probes.push(stats);
|
|
1970
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
1971
|
-
gl.viewport(0, 0, width, height);
|
|
1972
|
-
gl.enable(gl.BLEND);
|
|
1973
|
-
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
1974
|
-
const reachOf = (m) => m ? Math.hypot(m.offsetX, m.offsetY) + Math.max(m.width, m.height) / 2 + m.smoothing : 0;
|
|
1975
|
-
const morphReach = Math.max(reachOf(piece.morph), reachOf(piece.morph2));
|
|
1976
|
-
const touchReach = piece.touch ? Math.hypot(piece.touch.pullX, piece.touch.pullY) + piece.touch.waveAmp * 2 + Math.max(piece.geometry.width, piece.geometry.height) * 0.05 * piece.touch.press : 0;
|
|
1977
|
-
const padPx = (lensPadDp(piece.geometry, piece.optics) + surfacePadDp(piece.geometry, 0) + morphReach + touchReach) * options.density;
|
|
1978
|
-
const left = Math.max(0, Math.floor(piece.centerX - halfWidth - padPx));
|
|
1979
|
-
const right = Math.min(width, Math.ceil(piece.centerX + halfWidth + padPx));
|
|
1980
|
-
const top = Math.max(0, Math.floor(height - (piece.centerY + halfHeight + padPx)));
|
|
1981
|
-
const bottom = Math.min(height, Math.ceil(height - (piece.centerY - halfHeight - padPx)));
|
|
1982
|
-
gl.enable(gl.SCISSOR_TEST);
|
|
1983
|
-
gl.scissor(left, top, Math.max(0, right - left), Math.max(0, bottom - top));
|
|
1984
|
-
gl.useProgram(lensProgram);
|
|
1985
|
-
bindTextureAt(gl, 0, contentTexture, lensProgram, "content");
|
|
1986
|
-
setUniform(gl, lensLoc("u_contentSize"), [width, height]);
|
|
1987
|
-
setUniform(gl, lensLoc("u_resolution"), [width, height]);
|
|
1988
|
-
setUniform(gl, lensLoc("u_center"), [piece.centerX, piece.centerY]);
|
|
1989
|
-
setUniform(gl, lensLoc("u_reach"), Math.max(width, height));
|
|
1990
|
-
setUniform(gl, lensLoc("u_contentMin"), [1, 1]);
|
|
1991
|
-
setUniform(gl, lensLoc("u_contentMax"), [width - 1, height - 1]);
|
|
1992
|
-
if (stats) {
|
|
1993
|
-
setUniform(gl, lensLoc("u_probeLuma"), stats.luma);
|
|
1994
|
-
setUniform(gl, lensLoc("u_probeBusy"), stats.busy);
|
|
1995
|
-
setUniform(gl, lensLoc("u_probeRange"), [stats.lo, stats.hi]);
|
|
1996
|
-
setUniform(gl, lensLoc("u_probeSlope"), [stats.slopeX, stats.slopeY]);
|
|
1997
|
-
setUniform(gl, lensLoc("u_probe"), [stats.r, stats.g, stats.b]);
|
|
2030
|
+
return gpuTimer.time(() => {
|
|
2031
|
+
if (options.backdrop) {
|
|
2032
|
+
const fbo = ensureBackdropFbo();
|
|
2033
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
|
2034
|
+
gl.viewport(0, 0, width, height);
|
|
2035
|
+
options.backdrop(gl, { framebuffer: fbo, width, height });
|
|
2036
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
2037
|
+
gl.viewport(0, 0, width, height);
|
|
2038
|
+
gl.disable(gl.BLEND);
|
|
2039
|
+
gl.disable(gl.SCISSOR_TEST);
|
|
2040
|
+
gl.disable(gl.DEPTH_TEST);
|
|
2041
|
+
gl.disable(gl.CULL_FACE);
|
|
2042
|
+
gl.disable(gl.STENCIL_TEST);
|
|
2043
|
+
gl.colorMask(true, true, true, true);
|
|
2044
|
+
gl.depthMask(true);
|
|
2045
|
+
gl.bindVertexArray(null);
|
|
2046
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
2047
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
2048
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
2049
|
+
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.BROWSER_DEFAULT_WEBGL);
|
|
1998
2050
|
} else {
|
|
1999
|
-
|
|
2051
|
+
ctx.clearRect(0, 0, width, height);
|
|
2052
|
+
options.scene?.(ctx, width, height, options.offsetX ?? 0, options.offsetY ?? 0, options.density);
|
|
2053
|
+
gl.bindTexture(gl.TEXTURE_2D, contentTexture);
|
|
2054
|
+
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, sceneCanvas);
|
|
2055
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
2000
2056
|
}
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
gl.
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
morph2: piece.morph2,
|
|
2018
|
-
bodyInLens: true,
|
|
2019
|
-
touch: piece.touch,
|
|
2020
|
-
progress: piece.progress,
|
|
2021
|
-
// The shadow is denser over text, weaker over a flat backdrop (M 11:47). The rule lives
|
|
2022
|
-
// in the core: while it lived here, Android didn't have it at all.
|
|
2023
|
-
shadow: stats ? shadowOpacity(stats.busy) : 1,
|
|
2024
|
-
// The probe has already computed the ambient color — the shadow gets it for free. Taken
|
|
2025
|
-
// as-is: `settleStats` has already smoothed it, and rounding would bring back exactly the
|
|
2026
|
-
// steps the smoothing was written to remove.
|
|
2027
|
-
ambient: stats ? [stats.r, stats.g, stats.b] : void 0,
|
|
2028
|
-
appear: piece.appear,
|
|
2029
|
-
lift: piece.lift
|
|
2030
|
-
});
|
|
2031
|
-
applyObject(gl, surfaceLoc, {
|
|
2032
|
-
...toDeviceSurfaceUniforms(rawSurface, options.density),
|
|
2033
|
-
u_center: [piece.centerX, piece.centerY]
|
|
2034
|
-
});
|
|
2035
|
-
setUniform(gl, surfaceLoc(DYNAMIC_UNIFORMS[0]), piece.press ?? 0);
|
|
2036
|
-
setUniform(gl, surfaceLoc(DYNAMIC_UNIFORMS[1]), piece.active ?? 0);
|
|
2037
|
-
const hasIcon = Boolean(piece.icon && options.iconMask);
|
|
2038
|
-
setUniform(gl, surfaceLoc(ICON_UNIFORMS[0]), hasIcon ? 1 : 0);
|
|
2039
|
-
setUniform(gl, surfaceLoc(ICON_UNIFORMS[1]), 1);
|
|
2040
|
-
setUniform(gl, surfaceLoc(ICON_UNIFORMS[2]), piece.inkIdle ?? [1, 1, 1, 1]);
|
|
2041
|
-
setUniform(gl, surfaceLoc(ICON_UNIFORMS[3]), piece.inkActive ?? [1, 1, 1, 1]);
|
|
2042
|
-
bindTextureAt(gl, 1, iconTexture, surfaceProgram, "u_icon");
|
|
2043
|
-
setUniform(gl, surfaceLoc("u_iconSize"), hasIcon ? [width, height] : [1, 1]);
|
|
2044
|
-
const hasColor = Boolean(piece.overlay && options.colorLayer);
|
|
2045
|
-
setUniform(gl, surfaceLoc(OVERLAY_UNIFORMS[0]), hasColor ? 1 : 0);
|
|
2046
|
-
bindTextureAt(gl, 2, colorTexture, surfaceProgram, "u_overlay");
|
|
2047
|
-
setUniform(gl, surfaceLoc("u_overlaySize"), hasColor ? [width, height] : [1, 1]);
|
|
2048
|
-
setUniform(gl, surfaceLoc("u_resolution"), [width, height]);
|
|
2057
|
+
if (options.colorLayer) {
|
|
2058
|
+
gl.bindTexture(gl.TEXTURE_2D, colorTexture);
|
|
2059
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, options.colorLayer);
|
|
2060
|
+
}
|
|
2061
|
+
if (options.iconMask) {
|
|
2062
|
+
gl.bindTexture(gl.TEXTURE_2D, iconTexture);
|
|
2063
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, options.iconMask);
|
|
2064
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
2065
|
+
}
|
|
2066
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
2067
|
+
gl.viewport(0, 0, width, height);
|
|
2068
|
+
gl.disable(gl.BLEND);
|
|
2069
|
+
gl.disable(gl.SCISSOR_TEST);
|
|
2070
|
+
gl.useProgram(blitProgram);
|
|
2071
|
+
bindTextureAt(gl, 0, contentTexture, blitProgram, "u_content");
|
|
2072
|
+
setUniform(gl, blitLoc("u_resolution"), [width, height]);
|
|
2049
2073
|
drawFullscreenTriangle(gl);
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2074
|
+
const probes = [];
|
|
2075
|
+
for (let index = 0; index < options.pieces.length; index += 1) {
|
|
2076
|
+
const piece = options.pieces[index];
|
|
2077
|
+
const halfWidth = piece.geometry.width * options.density / 2;
|
|
2078
|
+
const halfHeight = piece.geometry.height * options.density / 2;
|
|
2079
|
+
const rect = {
|
|
2080
|
+
centerX: piece.centerX,
|
|
2081
|
+
centerY: piece.centerY,
|
|
2082
|
+
halfWidth,
|
|
2083
|
+
halfHeight
|
|
2084
|
+
};
|
|
2085
|
+
const fresh = index === 0 ? probe.sample(contentTexture, width, height, rect) : probe.statsFor(width, height, rect);
|
|
2086
|
+
const stats = fresh ? settleStats(index, fresh) : null;
|
|
2087
|
+
probes.push(stats);
|
|
2088
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
2089
|
+
gl.viewport(0, 0, width, height);
|
|
2090
|
+
gl.enable(gl.BLEND);
|
|
2091
|
+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
2092
|
+
const reachOf = (m) => m ? Math.hypot(m.offsetX, m.offsetY) + Math.max(m.width, m.height) / 2 + m.smoothing : 0;
|
|
2093
|
+
const morphReach = Math.max(reachOf(piece.morph), reachOf(piece.morph2));
|
|
2094
|
+
const touchReach = piece.touch ? Math.hypot(piece.touch.pullX, piece.touch.pullY) + piece.touch.waveAmp * 2 + Math.max(piece.geometry.width, piece.geometry.height) * 0.05 * piece.touch.press : 0;
|
|
2095
|
+
const padPx = (lensPadDp(piece.geometry, piece.optics) + surfacePadDp(piece.geometry, 0) + morphReach + touchReach) * options.density;
|
|
2096
|
+
const left = Math.max(0, Math.floor(piece.centerX - halfWidth - padPx));
|
|
2097
|
+
const right = Math.min(width, Math.ceil(piece.centerX + halfWidth + padPx));
|
|
2098
|
+
const top = Math.max(0, Math.floor(height - (piece.centerY + halfHeight + padPx)));
|
|
2099
|
+
const bottom = Math.min(height, Math.ceil(height - (piece.centerY - halfHeight - padPx)));
|
|
2100
|
+
gl.enable(gl.SCISSOR_TEST);
|
|
2101
|
+
gl.scissor(left, top, Math.max(0, right - left), Math.max(0, bottom - top));
|
|
2102
|
+
gl.useProgram(lensProgram);
|
|
2103
|
+
bindTextureAt(gl, 0, contentTexture, lensProgram, "content");
|
|
2104
|
+
setUniform(gl, lensLoc("u_contentSize"), [width, height]);
|
|
2105
|
+
setUniform(gl, lensLoc("u_resolution"), [width, height]);
|
|
2106
|
+
setUniform(gl, lensLoc("u_center"), [piece.centerX, piece.centerY]);
|
|
2107
|
+
setUniform(gl, lensLoc("u_reach"), Math.max(width, height));
|
|
2108
|
+
setUniform(gl, lensLoc("u_contentMin"), [1, 1]);
|
|
2109
|
+
setUniform(gl, lensLoc("u_contentMax"), [width - 1, height - 1]);
|
|
2110
|
+
if (stats) {
|
|
2111
|
+
setUniform(gl, lensLoc("u_probeLuma"), stats.luma);
|
|
2112
|
+
setUniform(gl, lensLoc("u_probeBusy"), stats.busy);
|
|
2113
|
+
setUniform(gl, lensLoc("u_probeRange"), [stats.lo, stats.hi]);
|
|
2114
|
+
setUniform(gl, lensLoc("u_probeSlope"), [stats.slopeX, stats.slopeY]);
|
|
2115
|
+
setUniform(gl, lensLoc("u_probe"), [stats.r, stats.g, stats.b]);
|
|
2116
|
+
} else {
|
|
2117
|
+
setUniform(gl, lensLoc("u_probeLuma"), -1);
|
|
2118
|
+
}
|
|
2119
|
+
const lens = toLensProps(piece.optics, piece.geometry, options.density, {
|
|
2120
|
+
debug: options.debug,
|
|
2121
|
+
morph: piece.morph,
|
|
2122
|
+
morph2: piece.morph2,
|
|
2123
|
+
touch: piece.touch,
|
|
2124
|
+
progress: piece.progress,
|
|
2125
|
+
light: piece.light,
|
|
2126
|
+
appear: piece.appear,
|
|
2127
|
+
accent: piece.accent
|
|
2128
|
+
});
|
|
2129
|
+
applyChannel(gl, lensLoc, lens.uniformNames, lens.uniformSizes, lens.uniformValues);
|
|
2130
|
+
drawFullscreenTriangle(gl);
|
|
2131
|
+
gl.useProgram(surfaceProgram);
|
|
2132
|
+
const rawSurface = toSurfaceUniforms(piece.optics, piece.geometry, {
|
|
2133
|
+
debug: options.debug,
|
|
2134
|
+
morph: piece.morph,
|
|
2135
|
+
morph2: piece.morph2,
|
|
2136
|
+
bodyInLens: true,
|
|
2137
|
+
touch: piece.touch,
|
|
2138
|
+
progress: piece.progress,
|
|
2139
|
+
// The shadow is denser over text, weaker over a flat backdrop (M 11:47). The rule lives
|
|
2140
|
+
// in the core: while it lived here, Android didn't have it at all.
|
|
2141
|
+
shadow: stats ? shadowOpacity(stats.busy) : 1,
|
|
2142
|
+
// The probe has already computed the ambient color — the shadow gets it for free. Taken
|
|
2143
|
+
// as-is: `settleStats` has already smoothed it, and rounding would bring back exactly the
|
|
2144
|
+
// steps the smoothing was written to remove.
|
|
2145
|
+
ambient: stats ? [stats.r, stats.g, stats.b] : void 0,
|
|
2146
|
+
appear: piece.appear,
|
|
2147
|
+
lift: piece.lift
|
|
2148
|
+
});
|
|
2149
|
+
applyObject(gl, surfaceLoc, {
|
|
2150
|
+
...toDeviceSurfaceUniforms(rawSurface, options.density),
|
|
2151
|
+
u_center: [piece.centerX, piece.centerY]
|
|
2152
|
+
});
|
|
2153
|
+
setUniform(gl, surfaceLoc(DYNAMIC_UNIFORMS[0]), piece.press ?? 0);
|
|
2154
|
+
setUniform(gl, surfaceLoc(DYNAMIC_UNIFORMS[1]), piece.active ?? 0);
|
|
2155
|
+
const hasIcon = Boolean(piece.icon && options.iconMask);
|
|
2156
|
+
setUniform(gl, surfaceLoc(ICON_UNIFORMS[0]), hasIcon ? 1 : 0);
|
|
2157
|
+
setUniform(gl, surfaceLoc(ICON_UNIFORMS[1]), 1);
|
|
2158
|
+
setUniform(gl, surfaceLoc(ICON_UNIFORMS[2]), piece.inkIdle ?? [1, 1, 1, 1]);
|
|
2159
|
+
setUniform(gl, surfaceLoc(ICON_UNIFORMS[3]), piece.inkActive ?? [1, 1, 1, 1]);
|
|
2160
|
+
bindTextureAt(gl, 1, iconTexture, surfaceProgram, "u_icon");
|
|
2161
|
+
setUniform(gl, surfaceLoc("u_iconSize"), hasIcon ? [width, height] : [1, 1]);
|
|
2162
|
+
const hasColor = Boolean(piece.overlay && options.colorLayer);
|
|
2163
|
+
setUniform(gl, surfaceLoc(OVERLAY_UNIFORMS[0]), hasColor ? 1 : 0);
|
|
2164
|
+
bindTextureAt(gl, 2, colorTexture, surfaceProgram, "u_overlay");
|
|
2165
|
+
setUniform(gl, surfaceLoc("u_overlaySize"), hasColor ? [width, height] : [1, 1]);
|
|
2166
|
+
setUniform(gl, surfaceLoc("u_resolution"), [width, height]);
|
|
2167
|
+
drawFullscreenTriangle(gl);
|
|
2168
|
+
}
|
|
2169
|
+
gl.disable(gl.SCISSOR_TEST);
|
|
2170
|
+
return { probes };
|
|
2171
|
+
});
|
|
2053
2172
|
}
|
|
2054
2173
|
function destroy() {
|
|
2055
2174
|
probe.destroy();
|
|
@@ -2059,13 +2178,24 @@ function createVireGlassRenderer(canvas) {
|
|
|
2059
2178
|
gl.deleteTexture(contentTexture);
|
|
2060
2179
|
gl.deleteTexture(iconTexture);
|
|
2061
2180
|
gl.deleteTexture(colorTexture);
|
|
2181
|
+
if (backdropFbo) gl.deleteFramebuffer(backdropFbo);
|
|
2182
|
+
gpuTimer.destroy();
|
|
2062
2183
|
}
|
|
2063
|
-
return { resize, render, destroy };
|
|
2184
|
+
return { resize, render, getLastGpuMs: gpuTimer.getLastMs, destroy };
|
|
2064
2185
|
}
|
|
2065
2186
|
|
|
2187
|
+
exports.FULLSCREEN_TRIANGLE_VERTEX_SOURCE = FULLSCREEN_TRIANGLE_VERTEX_SOURCE;
|
|
2066
2188
|
exports.PROBE_GRID_HEIGHT = PROBE_GRID_HEIGHT;
|
|
2067
2189
|
exports.PROBE_GRID_WIDTH = PROBE_GRID_WIDTH;
|
|
2190
|
+
exports.bindTextureAt = bindTextureAt;
|
|
2191
|
+
exports.compileShader = compileShader;
|
|
2192
|
+
exports.createFramebuffer = createFramebuffer;
|
|
2068
2193
|
exports.createProbe = createProbe;
|
|
2194
|
+
exports.createProgram = createProgram;
|
|
2195
|
+
exports.createTexture = createTexture;
|
|
2069
2196
|
exports.createVireGlassRenderer = createVireGlassRenderer;
|
|
2197
|
+
exports.drawFullscreenTriangle = drawFullscreenTriangle;
|
|
2198
|
+
exports.locationCache = locationCache;
|
|
2199
|
+
exports.setUniform = setUniform;
|
|
2070
2200
|
//# sourceMappingURL=index.cjs.map
|
|
2071
2201
|
//# sourceMappingURL=index.cjs.map
|