@vitreajs/vitrea 0.15.0 → 0.17.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 +4 -3
- package/dist/{chunk-WM2DV3ZD.js → chunk-IOTISK2R.js} +2 -2
- package/dist/{chunk-WM2DV3ZD.js.map → chunk-IOTISK2R.js.map} +1 -1
- package/dist/{dist-PT4PUS4K.js → dist-T7PRMUM4.js} +504 -96
- package/dist/dist-T7PRMUM4.js.map +1 -0
- package/dist/index.d.ts +104 -24
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/dist-PT4PUS4K.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_GROUP_UNION, LowPassHysteresisDriver, WGSL_RSUPN, WGSL_RSUP, resolveFromChannels, resolveConcentric, governorFieldParams, fieldParams, DEFAULT_MOTION_PROFILE } from './chunk-
|
|
1
|
+
import { DEFAULT_GROUP_UNION, LowPassHysteresisDriver, WGSL_RSUPN, WGSL_RSUP, resolveFromChannels, resolveConcentric, governorFieldParams, fieldParams, DEFAULT_MOTION_PROFILE } from './chunk-IOTISK2R.js';
|
|
2
2
|
|
|
3
3
|
// ../renderer-webgpu/dist/wgsl/analysis.js
|
|
4
4
|
var ANALYSIS_WORKGROUP = 64;
|
|
@@ -220,6 +220,12 @@ function occlusionAlphaUnderPolicy(nominal, occlusion, lift = INCREASED_OCCLUSIO
|
|
|
220
220
|
return 1;
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
|
+
function occlusionLiftForPolicy(policy, profile = DEFAULT_MATERIAL_PROFILE) {
|
|
224
|
+
if (policy.occlusion !== "increased")
|
|
225
|
+
return profile.increasedOcclusionLift;
|
|
226
|
+
const levels = profile.increasedOcclusionLiftByPolicy;
|
|
227
|
+
return policy.ambientTint === "reduced" ? levels?.increaseContrast ?? profile.increasedOcclusionLift : levels?.reduceTransparency ?? profile.increasedOcclusionLift;
|
|
228
|
+
}
|
|
223
229
|
var DEFAULT_MATERIAL_PROFILE = {
|
|
224
230
|
optics: {
|
|
225
231
|
// σ = 8 for the regular variant, which keeps this package's blur and
|
|
@@ -1152,6 +1158,20 @@ function rejectRetiredOuterShadowLeaves(patch) {
|
|
|
1152
1158
|
throw new Error(`outerShadow.${leaf} was retired by W14 G1 (claims \xA75.62) and is replaced by ${replacement}. Applying this patch would have rendered the default shadow while recording itself as configured. It is refused rather than mapped: a single span-flat amplitude is the material the measurement retired.`);
|
|
1153
1159
|
}
|
|
1154
1160
|
}
|
|
1161
|
+
function rejectMixedBackdropToneArity(anchorX, thin, thick) {
|
|
1162
|
+
for (const [name, row] of [
|
|
1163
|
+
["backdropToneAnchorX", anchorX],
|
|
1164
|
+
["backdropToneResponseThin", thin],
|
|
1165
|
+
["backdropToneResponseThick", thick]
|
|
1166
|
+
]) {
|
|
1167
|
+
if (Array.isArray(row) && (row.length === 3 || row.length === 4))
|
|
1168
|
+
continue;
|
|
1169
|
+
throw new Error(`The backdrop tone response's ${name} is ${JSON.stringify(row) ?? String(row)}, which is not an array of three or four knots. The curve has exactly those two forms, and anything else is read as a different one by each tier: the CPU curve and the CSS mirror take the four-knot branch for any length but three, where the shader takes the three-knot branch for any length but four.`);
|
|
1170
|
+
}
|
|
1171
|
+
if (anchorX.length === thin.length && thin.length === thick.length)
|
|
1172
|
+
return;
|
|
1173
|
+
throw new Error(`The backdrop tone response's three rows resolved to different knot counts \u2014 backdropToneAnchorX ${anchorX.length}, backdropToneResponseThin ${thin.length}, backdropToneResponseThick ${thick.length}. They are one curve's knots and that curve's levels at its two thickness ends, and the shader reads the knot count off the anchors alone, so a mixed triplet renders as NaN on the CPU curve and as a fabricated segment on the GPU. A patch moving the response to a new knot count has to name all three rows.`);
|
|
1174
|
+
}
|
|
1155
1175
|
function withMaterialOverrides(base, patch) {
|
|
1156
1176
|
rejectRetiredOuterShadowLeaves(patch.outerShadow);
|
|
1157
1177
|
const optics = {};
|
|
@@ -1162,6 +1182,10 @@ function withMaterialOverrides(base, patch) {
|
|
|
1162
1182
|
for (const rung of REFRACTION_LADDER) {
|
|
1163
1183
|
refractionScale[rung] = patch.refractionScale?.[rung] ?? base.refractionScale[rung];
|
|
1164
1184
|
}
|
|
1185
|
+
const backdropToneAnchorX = patch.backdropToneAnchorX ?? base.backdropToneAnchorX;
|
|
1186
|
+
const backdropToneResponseThin = patch.backdropToneResponseThin ?? base.backdropToneResponseThin;
|
|
1187
|
+
const backdropToneResponseThick = patch.backdropToneResponseThick ?? base.backdropToneResponseThick;
|
|
1188
|
+
rejectMixedBackdropToneArity(backdropToneAnchorX, backdropToneResponseThin, backdropToneResponseThick);
|
|
1165
1189
|
return {
|
|
1166
1190
|
optics,
|
|
1167
1191
|
adaptiveTintDark: patch.adaptiveTintDark ?? base.adaptiveTintDark,
|
|
@@ -1207,11 +1231,21 @@ function withMaterialOverrides(base, patch) {
|
|
|
1207
1231
|
lensOvalizationSpanMax: patch.lensOvalizationSpanMax ?? base.lensOvalizationSpanMax,
|
|
1208
1232
|
reducedTransparencyFrost: patch.reducedTransparencyFrost ?? base.reducedTransparencyFrost,
|
|
1209
1233
|
increasedOcclusionLift: patch.increasedOcclusionLift ?? base.increasedOcclusionLift,
|
|
1234
|
+
...(patch.increasedOcclusionLiftByPolicy ?? base.increasedOcclusionLiftByPolicy) === void 0 ? {} : { increasedOcclusionLiftByPolicy: {
|
|
1235
|
+
...base.increasedOcclusionLiftByPolicy,
|
|
1236
|
+
...patch.increasedOcclusionLiftByPolicy
|
|
1237
|
+
} },
|
|
1210
1238
|
strongBorderRim: { ...base.strongBorderRim, ...patch.strongBorderRim },
|
|
1211
1239
|
reducedTintAdaptation: patch.reducedTintAdaptation ?? base.reducedTintAdaptation,
|
|
1212
1240
|
tintShadeDark: patch.tintShadeDark ?? base.tintShadeDark,
|
|
1213
1241
|
tintShadeLight: patch.tintShadeLight ?? base.tintShadeLight,
|
|
1214
1242
|
tintShadeStrength: patch.tintShadeStrength ?? base.tintShadeStrength,
|
|
1243
|
+
...(patch.tintChromaScale ?? base.tintChromaScale ?? 1) === 1 ? {} : {
|
|
1244
|
+
tintChromaScale: patch.tintChromaScale ?? base.tintChromaScale
|
|
1245
|
+
},
|
|
1246
|
+
...(patch.tintShadeCollapseRetention ?? base.tintShadeCollapseRetention ?? 0) === 0 ? {} : {
|
|
1247
|
+
tintShadeCollapseRetention: patch.tintShadeCollapseRetention ?? base.tintShadeCollapseRetention
|
|
1248
|
+
},
|
|
1215
1249
|
backdropToneMax: patch.backdropToneMax ?? base.backdropToneMax,
|
|
1216
1250
|
backdropToneLow: patch.backdropToneLow ?? base.backdropToneLow,
|
|
1217
1251
|
backdropToneHigh: patch.backdropToneHigh ?? base.backdropToneHigh,
|
|
@@ -1221,9 +1255,9 @@ function withMaterialOverrides(base, patch) {
|
|
|
1221
1255
|
rimCollapsed: patch.rimCollapsed ?? base.rimCollapsed,
|
|
1222
1256
|
rimCollapsedTinted: patch.rimCollapsedTinted ?? base.rimCollapsedTinted,
|
|
1223
1257
|
rimTintChroma: patch.rimTintChroma ?? base.rimTintChroma,
|
|
1224
|
-
backdropToneAnchorX
|
|
1225
|
-
backdropToneResponseThin
|
|
1226
|
-
backdropToneResponseThick
|
|
1258
|
+
backdropToneAnchorX,
|
|
1259
|
+
backdropToneResponseThin,
|
|
1260
|
+
backdropToneResponseThick,
|
|
1227
1261
|
backdropToneResponseStrength: patch.backdropToneResponseStrength ?? base.backdropToneResponseStrength,
|
|
1228
1262
|
outerShadow: { ...base.outerShadow, ...patch.outerShadow },
|
|
1229
1263
|
lightDirection: patch.lightDirection ?? base.lightDirection,
|
|
@@ -1243,7 +1277,7 @@ function opticsUnderPolicy(optics, policy, profile = DEFAULT_MATERIAL_PROFILE) {
|
|
|
1243
1277
|
}
|
|
1244
1278
|
next = {
|
|
1245
1279
|
...next,
|
|
1246
|
-
tintAlpha: occlusionAlphaUnderPolicy(next.tintAlpha, policy.occlusion, profile
|
|
1280
|
+
tintAlpha: occlusionAlphaUnderPolicy(next.tintAlpha, policy.occlusion, occlusionLiftForPolicy(policy, profile))
|
|
1247
1281
|
};
|
|
1248
1282
|
if (policy.border === "strong") {
|
|
1249
1283
|
next = {
|
|
@@ -1300,7 +1334,15 @@ function tintShade(materialLuminance, grip, profile = DEFAULT_MATERIAL_PROFILE)
|
|
|
1300
1334
|
}
|
|
1301
1335
|
function tintShadeLayer(seed, materialLuminance, grip, profile = DEFAULT_MATERIAL_PROFILE) {
|
|
1302
1336
|
const shade = tintShade(materialLuminance, grip, profile);
|
|
1303
|
-
|
|
1337
|
+
const chroma = Math.min(1, Math.max(0, profile.tintChromaScale ?? 1));
|
|
1338
|
+
if (chroma === 1)
|
|
1339
|
+
return [seed[0] * shade, seed[1] * shade, seed[2] * shade];
|
|
1340
|
+
const neutral = Math.max(...seed);
|
|
1341
|
+
return [
|
|
1342
|
+
(neutral + (seed[0] - neutral) * chroma) * shade,
|
|
1343
|
+
(neutral + (seed[1] - neutral) * chroma) * shade,
|
|
1344
|
+
(neutral + (seed[2] - neutral) * chroma) * shade
|
|
1345
|
+
];
|
|
1304
1346
|
}
|
|
1305
1347
|
function tintedMaterialColour(material, tint, grip, profile = DEFAULT_MATERIAL_PROFILE) {
|
|
1306
1348
|
if (tint === void 0 || tint.strength <= 0)
|
|
@@ -1359,19 +1401,45 @@ function backdropToneResponse(encodedInput, thickness, profile = DEFAULT_MATERIA
|
|
|
1359
1401
|
const xs = profile.backdropToneAnchorX;
|
|
1360
1402
|
const f = smoothstep(0, 1, thickness);
|
|
1361
1403
|
const ys = [0, 1, 2].map((i) => (profile.backdropToneResponseThin[i] ?? 0) + ((profile.backdropToneResponseThick[i] ?? 0) - (profile.backdropToneResponseThin[i] ?? 0)) * f);
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1404
|
+
let x, h, t, y0, y1, s0, s1;
|
|
1405
|
+
if (xs.length === 3) {
|
|
1406
|
+
x = Math.min(xs[2], Math.max(xs[0], encodedInput));
|
|
1407
|
+
const h0 = xs[1] - xs[0];
|
|
1408
|
+
const h1 = xs[2] - xs[1];
|
|
1409
|
+
const d0 = (ys[1] - ys[0]) / h0;
|
|
1410
|
+
const d1 = (ys[2] - ys[1]) / h1;
|
|
1411
|
+
const m1 = d0 * d1 <= 0 ? 0 : 2 * d0 * d1 / (d0 + d1);
|
|
1412
|
+
const seg = x <= xs[1] ? 0 : 1;
|
|
1413
|
+
h = seg === 0 ? h0 : h1;
|
|
1414
|
+
t = (x - (seg === 0 ? xs[0] : xs[1])) / h;
|
|
1415
|
+
y0 = seg === 0 ? ys[0] : ys[1];
|
|
1416
|
+
y1 = seg === 0 ? ys[1] : ys[2];
|
|
1417
|
+
s0 = seg === 0 ? d0 : m1;
|
|
1418
|
+
s1 = seg === 0 ? m1 : d1;
|
|
1419
|
+
} else {
|
|
1420
|
+
const ys4 = [
|
|
1421
|
+
ys[0],
|
|
1422
|
+
ys[1],
|
|
1423
|
+
ys[2],
|
|
1424
|
+
profile.backdropToneResponseThin[3] + (profile.backdropToneResponseThick[3] - profile.backdropToneResponseThin[3]) * f
|
|
1425
|
+
];
|
|
1426
|
+
x = Math.min(xs[3], Math.max(xs[0], encodedInput));
|
|
1427
|
+
const h0 = xs[1] - xs[0], h1 = xs[2] - xs[1], h2 = xs[3] - xs[2];
|
|
1428
|
+
const d0 = (ys4[1] - ys4[0]) / h0;
|
|
1429
|
+
const d1 = (ys4[2] - ys4[1]) / h1;
|
|
1430
|
+
const d2 = (ys4[3] - ys4[2]) / h2;
|
|
1431
|
+
const m1 = d0 * d1 <= 0 ? 0 : 2 * d0 * d1 / (d0 + d1);
|
|
1432
|
+
const m2 = d1 * d2 <= 0 ? 0 : 2 * d1 * d2 / (d1 + d2);
|
|
1433
|
+
const seg = x <= xs[1] ? 0 : x <= xs[2] ? 1 : 2;
|
|
1434
|
+
const hs = [h0, h1, h2];
|
|
1435
|
+
const slopes = [d0, m1, m2, d2];
|
|
1436
|
+
h = hs[seg];
|
|
1437
|
+
t = (x - xs[seg]) / h;
|
|
1438
|
+
y0 = ys4[seg];
|
|
1439
|
+
y1 = ys4[seg + 1];
|
|
1440
|
+
s0 = slopes[seg];
|
|
1441
|
+
s1 = slopes[seg + 1];
|
|
1442
|
+
}
|
|
1375
1443
|
return y0 * (1 + 2 * t) * (1 - t) * (1 - t) + s0 * h * t * (1 - t) * (1 - t) + y1 * t * t * (3 - 2 * t) + s1 * h * t * t * (t - 1) + levelFar;
|
|
1376
1444
|
}
|
|
1377
1445
|
function backdropToneSolveWeight(encodedInput, profile = DEFAULT_MATERIAL_PROFILE) {
|
|
@@ -2498,9 +2566,17 @@ var poolKey = {
|
|
|
2498
2566
|
backdropHeavy: (sourceId) => `backdrop:${sourceId}:heavy`,
|
|
2499
2567
|
backdropHeavyScratch: (sourceId) => `backdrop:${sourceId}:heavy-scratch`,
|
|
2500
2568
|
backdropUpload: (sourceId) => `backdrop:${sourceId}:upload`,
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2569
|
+
/*
|
|
2570
|
+
* The four field targets. Their key is a group's RESOURCE identity — the id
|
|
2571
|
+
* qualified by the plane it draws on (`groupResourceId`) — and not the group
|
|
2572
|
+
* id, because one group can draw on two planes in one frame and each plane's
|
|
2573
|
+
* field is its own size.
|
|
2574
|
+
*/
|
|
2575
|
+
groupField: (resourceId) => `group:${resourceId}:field`,
|
|
2576
|
+
groupAux: (resourceId) => `group:${resourceId}:aux`,
|
|
2577
|
+
groupAux2: (resourceId) => `group:${resourceId}:aux2`,
|
|
2578
|
+
/** The surface's presence per pixel (W27d) — the field pass's fourth target. */
|
|
2579
|
+
groupPresence: (resourceId) => `group:${resourceId}:presence`
|
|
2504
2580
|
};
|
|
2505
2581
|
|
|
2506
2582
|
// ../renderer-webgpu/dist/gpu-context.js
|
|
@@ -2589,12 +2665,32 @@ var IDLE_CHANNELS = {
|
|
|
2589
2665
|
glow: 0,
|
|
2590
2666
|
sweep: 0,
|
|
2591
2667
|
shimmer: 0,
|
|
2592
|
-
lensStrength: 1
|
|
2668
|
+
lensStrength: 1,
|
|
2669
|
+
// 1 rather than 0, for `lensStrength`'s reason: a surface nobody is driving is
|
|
2670
|
+
// a surface that is fully there, and 0 is a distinct claim a driver can make.
|
|
2671
|
+
materialization: 1
|
|
2593
2672
|
};
|
|
2594
2673
|
|
|
2595
2674
|
// ../renderer-webgpu/dist/instances.js
|
|
2596
2675
|
var INSTANCE_FLOATS = 18;
|
|
2597
2676
|
var INSTANCE_BYTES = INSTANCE_FLOATS * 4;
|
|
2677
|
+
var LENS_STRENGTH_MAX = 4;
|
|
2678
|
+
function boundedLensStrength(strength) {
|
|
2679
|
+
if (Number.isNaN(strength))
|
|
2680
|
+
return IDLE_CHANNELS.lensStrength;
|
|
2681
|
+
return Math.min(LENS_STRENGTH_MAX, Math.max(0, strength));
|
|
2682
|
+
}
|
|
2683
|
+
function boundedMaterialization(value) {
|
|
2684
|
+
if (Number.isNaN(value))
|
|
2685
|
+
return IDLE_CHANNELS.materialization;
|
|
2686
|
+
return Math.min(1, Math.max(0, value));
|
|
2687
|
+
}
|
|
2688
|
+
function drawsMaterial(surface) {
|
|
2689
|
+
if (surface.fieldReferenceOnly === true)
|
|
2690
|
+
return false;
|
|
2691
|
+
const presence = surface.channels?.materialization ?? IDLE_CHANNELS.materialization;
|
|
2692
|
+
return boundedMaterialization(presence) > 0;
|
|
2693
|
+
}
|
|
2598
2694
|
var channelsOf = (input) => ({
|
|
2599
2695
|
...IDLE_CHANNELS,
|
|
2600
2696
|
...input.channels
|
|
@@ -2643,7 +2739,7 @@ function resolveSurfaces(group, family, profile = DEFAULT_MATERIAL_PROFILE, poli
|
|
|
2643
2739
|
return shape;
|
|
2644
2740
|
};
|
|
2645
2741
|
const paramsFor = (shape) => family === "rsup" ? governorFieldParams(shape) : fieldParams(shape);
|
|
2646
|
-
return group.surfaces.filter(
|
|
2742
|
+
return group.surfaces.filter(drawsMaterial).map((surface) => {
|
|
2647
2743
|
const channels = channelsOf(surface);
|
|
2648
2744
|
const shape = resolveShapeOf(surface);
|
|
2649
2745
|
const fieldSource = surface.concentricOf === void 0 ? shape : resolveShapeOf(byId.get(surface.concentricOf.nodeId));
|
|
@@ -2660,6 +2756,7 @@ function resolveSurfaces(group, family, profile = DEFAULT_MATERIAL_PROFILE, poli
|
|
|
2660
2756
|
spanPx,
|
|
2661
2757
|
lensDepthPx: lensDepthPx(shape.channels.thickness, spanPx, profile, profile.refractionScale[accessibilityRefractionCap(policy)]),
|
|
2662
2758
|
sizeThickness: thickness,
|
|
2759
|
+
materialization: boundedMaterialization(channels.materialization),
|
|
2663
2760
|
tintStrength: Math.min(1, Math.max(0, surface.tint?.strength ?? 0))
|
|
2664
2761
|
};
|
|
2665
2762
|
});
|
|
@@ -2723,10 +2820,10 @@ function packInstances(surfaces, origin, into) {
|
|
|
2723
2820
|
data[o + 11] = s.shape.channels.thickness;
|
|
2724
2821
|
data[o + 12] = s.channels.press;
|
|
2725
2822
|
data[o + 13] = s.channels.glow;
|
|
2726
|
-
data[o + 14] = Math.max(s.shape.channels.thickness, 0) *
|
|
2823
|
+
data[o + 14] = Math.max(s.shape.channels.thickness, 0) * boundedLensStrength(s.channels.lensStrength);
|
|
2727
2824
|
data[o + 15] = s.tintStrength;
|
|
2728
2825
|
data[o + 16] = s.spanPx;
|
|
2729
|
-
data[o + 17] =
|
|
2826
|
+
data[o + 17] = s.materialization;
|
|
2730
2827
|
}
|
|
2731
2828
|
return { data, count: surfaces.length };
|
|
2732
2829
|
}
|
|
@@ -3004,7 +3101,7 @@ var WGSL_INSTANCE_STRUCT = `struct Instance {
|
|
|
3004
3101
|
lensThick : f32, // 56 authored thickness in CSS px times the lensStrength channel (W12 G2): both depths are evaluated from it per pixel
|
|
3005
3102
|
tintK : f32, // 60 author tint strength, 0..1 \u2014 the seed itself is a group uniform
|
|
3006
3103
|
span : f32, // 64 the surface's shorter extent, CSS px \u2014 the size law's input, both curves (W11c)
|
|
3007
|
-
|
|
3104
|
+
mat : f32, // 68 presence, 0..1 (W27d): the slot the 8-byte alignment already required
|
|
3008
3105
|
};`;
|
|
3009
3106
|
var WGSL_FIELD_SAMPLE = `struct FieldSample {
|
|
3010
3107
|
d : f32,
|
|
@@ -3214,6 +3311,17 @@ var WGSL_FIELD_PASS = `struct FieldUniforms {
|
|
|
3214
3311
|
// two merged members share one oval there \u2014 a value nothing measured either.
|
|
3215
3312
|
// For a concentric child the box is the parent's (the child is the parent's
|
|
3216
3313
|
// level set), which is the same centre and a slightly larger oval.
|
|
3314
|
+
//
|
|
3315
|
+
// 'presence' (W27d) is the fourth target and carries one number: the surface's
|
|
3316
|
+
// materialization, blended through the union on the same weight as everything
|
|
3317
|
+
// else. It is a target of its own rather than a component of one of the three
|
|
3318
|
+
// above because all three are full \u2014 the field carries the distance, the normal
|
|
3319
|
+
// and the coverage, 'aux' the four optical scalars, 'aux2' the surface's own box
|
|
3320
|
+
// \u2014 and repurposing a component would mean re-deriving a value the fragment
|
|
3321
|
+
// stages read, which is how a golden moves for a reason nobody named. It is
|
|
3322
|
+
// r16float rather than the working rgba16float for the same honesty: one scalar
|
|
3323
|
+
// costs one channel, and a wave that needs a second widens the format in the one
|
|
3324
|
+
// place it is declared ('passes.ts').
|
|
3217
3325
|
|
|
3218
3326
|
@group(0) @binding(0) var<uniform> fu : FieldUniforms;
|
|
3219
3327
|
@group(0) @binding(1) var<storage, read> instances : array<Instance>;
|
|
@@ -3223,6 +3331,7 @@ struct Member {
|
|
|
3223
3331
|
g : vec2f,
|
|
3224
3332
|
aux : vec4f,
|
|
3225
3333
|
aux2 : vec4f,
|
|
3334
|
+
mat : f32,
|
|
3226
3335
|
};
|
|
3227
3336
|
|
|
3228
3337
|
fn eval_instance(i : u32, p : vec2f) -> Member {
|
|
@@ -3239,6 +3348,7 @@ fn eval_instance(i : u32, p : vec2f) -> Member {
|
|
|
3239
3348
|
// The pixel relative to the surface's centre, and the half-extents: what the
|
|
3240
3349
|
// oval's gradient needs, written here where the group-local position is exact.
|
|
3241
3350
|
m.aux2 = vec4f(p - s.centre, s.half);
|
|
3351
|
+
m.mat = s.mat;
|
|
3242
3352
|
return m;
|
|
3243
3353
|
}
|
|
3244
3354
|
|
|
@@ -3246,6 +3356,7 @@ struct FieldOut {
|
|
|
3246
3356
|
@location(0) field : vec4f,
|
|
3247
3357
|
@location(1) aux : vec4f,
|
|
3248
3358
|
@location(2) aux2 : vec4f,
|
|
3359
|
+
@location(3) presence : vec4f,
|
|
3249
3360
|
};
|
|
3250
3361
|
|
|
3251
3362
|
@fragment
|
|
@@ -3264,6 +3375,10 @@ fn fs_field(in : FullscreenOut) -> FieldOut {
|
|
|
3264
3375
|
out.field = vec4f(65000.0, 0.0, -1.0, 0.0);
|
|
3265
3376
|
out.aux = vec4f(0.0);
|
|
3266
3377
|
out.aux2 = vec4f(0.0);
|
|
3378
|
+
// The idle, not zero: no surface here means nothing to be absent, and a
|
|
3379
|
+
// reader that walks off the instances (the outer shadow's offset read) must
|
|
3380
|
+
// not find a material it has to fade.
|
|
3381
|
+
out.presence = vec4f(1.0, 0.0, 0.0, 0.0);
|
|
3267
3382
|
return out;
|
|
3268
3383
|
}
|
|
3269
3384
|
|
|
@@ -3277,6 +3392,7 @@ fn fs_field(in : FullscreenOut) -> FieldOut {
|
|
|
3277
3392
|
acc.g = mix(s.g, acc.g, h);
|
|
3278
3393
|
acc.aux = mix(s.aux, acc.aux, h);
|
|
3279
3394
|
acc.aux2 = mix(s.aux2, acc.aux2, h);
|
|
3395
|
+
acc.mat = mix(s.mat, acc.mat, h);
|
|
3280
3396
|
nearest = min(nearest, s.d);
|
|
3281
3397
|
}
|
|
3282
3398
|
// One clamp at the end of the fold, so |union - min| <= maxBulge holds for any
|
|
@@ -3290,6 +3406,7 @@ fn fs_field(in : FullscreenOut) -> FieldOut {
|
|
|
3290
3406
|
out.field = vec4f(acc.d, normal.x, normal.y, coverage);
|
|
3291
3407
|
out.aux = acc.aux;
|
|
3292
3408
|
out.aux2 = acc.aux2;
|
|
3409
|
+
out.presence = vec4f(acc.mat, 0.0, 0.0, 0.0);
|
|
3293
3410
|
return out;
|
|
3294
3411
|
}`;
|
|
3295
3412
|
function fieldPassSource(family) {
|
|
@@ -3349,6 +3466,10 @@ var WGSL_HIGHLIGHT_PASS = `struct HighlightUniforms {
|
|
|
3349
3466
|
@group(0) @binding(1) var fieldTexture : texture_2d<f32>;
|
|
3350
3467
|
@group(0) @binding(2) var auxTexture : texture_2d<f32>;
|
|
3351
3468
|
@group(0) @binding(3) var fieldSampler : sampler;
|
|
3469
|
+
/// The surface's presence per pixel (W27d) \u2014 the field pass's fourth target,
|
|
3470
|
+
/// bound here for the same reason the optics pass binds it: a highlight is the
|
|
3471
|
+
/// material catching light, and a material that is not there catches none.
|
|
3472
|
+
@group(0) @binding(4) var presenceTexture : texture_2d<f32>;
|
|
3352
3473
|
|
|
3353
3474
|
const TAU = 6.283185307179586;
|
|
3354
3475
|
|
|
@@ -3367,14 +3488,18 @@ fn fs_highlight(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
3367
3488
|
let fieldUv = in.uv * hu.fieldFit.xy + hu.fieldFit.zw;
|
|
3368
3489
|
var field : vec4f;
|
|
3369
3490
|
var aux : vec4f;
|
|
3491
|
+
var presence : vec4f;
|
|
3370
3492
|
if (hu.flags.z > 0.5) {
|
|
3371
3493
|
field = textureSampleLevel(fieldTexture, fieldSampler, fieldUv, 0.0);
|
|
3372
3494
|
aux = textureSampleLevel(auxTexture, fieldSampler, fieldUv, 0.0);
|
|
3495
|
+
presence = textureSampleLevel(presenceTexture, fieldSampler, fieldUv, 0.0);
|
|
3373
3496
|
} else {
|
|
3374
3497
|
let texel = vec2i(fieldUv * hu.flags.xy);
|
|
3375
3498
|
field = textureLoad(fieldTexture, texel, 0);
|
|
3376
3499
|
aux = textureLoad(auxTexture, texel, 0);
|
|
3500
|
+
presence = textureLoad(presenceTexture, texel, 0);
|
|
3377
3501
|
}
|
|
3502
|
+
let mat = clamp(presence.x, 0.0, 1.0);
|
|
3378
3503
|
let d = field.x;
|
|
3379
3504
|
let normal = field.yz;
|
|
3380
3505
|
let coverage = field.w;
|
|
@@ -3432,7 +3557,15 @@ fn fs_highlight(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
3432
3557
|
toneAdapt = clamp(hu.toneAdapt.w, 0.0, 1.0) * (1.0 - toneT * toneT * (3.0 - 2.0 * toneT));
|
|
3433
3558
|
}
|
|
3434
3559
|
|
|
3435
|
-
|
|
3560
|
+
/*
|
|
3561
|
+
* The presence (W27d) fades both lights on one factor, exactly as the collapse
|
|
3562
|
+
* above fades them: the sweep is the material's own rim catching a travelling
|
|
3563
|
+
* light and the glow is the material lit from a press, so neither survives a
|
|
3564
|
+
* surface that is not there. It is applied to the composed intensity rather
|
|
3565
|
+
* than to each term, because a highlight that fades on two statements of one
|
|
3566
|
+
* rule is a highlight that will one day fade on one of them.
|
|
3567
|
+
*/
|
|
3568
|
+
let intensity = clamp(sweep + press, 0.0, 1.0) * coverage * (1.0 - toneAdapt) * mat;
|
|
3436
3569
|
if (intensity <= 0.0) {
|
|
3437
3570
|
return vec4f(0.0);
|
|
3438
3571
|
}
|
|
@@ -3460,9 +3593,8 @@ var WGSL_OPTICS_PASS = `struct OpticsUniforms {
|
|
|
3460
3593
|
/// accessibility fold \u2014 the refraction ladder read at the preference's cap,
|
|
3461
3594
|
/// which every facet's span-dependent rise is multiplied by (W11c)
|
|
3462
3595
|
tone : vec4f,
|
|
3463
|
-
/// rimWidthPx, rimAlpha;
|
|
3464
|
-
///
|
|
3465
|
-
/// section 1) and are written but unread
|
|
3596
|
+
/// rimWidthPx, rimAlpha; the slots retired by W24 now carry W27c's
|
|
3597
|
+
/// tintChromaScale (z) and tintShadeCollapseRetention (w).
|
|
3466
3598
|
rim : vec4f,
|
|
3467
3599
|
/// light direction, unit (xy), shadowDepth (z), shadowAlpha (w)
|
|
3468
3600
|
light : vec4f,
|
|
@@ -3578,8 +3710,14 @@ var WGSL_OPTICS_PASS = `struct OpticsUniforms {
|
|
|
3578
3710
|
/// carries a heavy texture, 0 where it does not. The WIDTH is not here: the
|
|
3579
3711
|
/// pyramid blurred it into 'backdropHeavy' before any group was drawn, so all
|
|
3580
3712
|
/// this pass decides is which of two textures the deep sample comes from.
|
|
3581
|
-
/// (y) (
|
|
3713
|
+
/// (y) is the DOM material mode (0 off, 1 unknown tone, 2 measured tone);
|
|
3714
|
+
/// (z) and (w) carry its reference level and minimum tint contrast.
|
|
3715
|
+
/// Texture draws keep those lanes zero, so their input bytes do not move.
|
|
3582
3716
|
heavyTap : vec4f,
|
|
3717
|
+
/// Decision Log 18's optional fourth response knot: encoded x, thin y,
|
|
3718
|
+
/// thick z, and a length gate w. Appended so every three-knot field keeps its
|
|
3719
|
+
/// byte offset and its original shader branch.
|
|
3720
|
+
toneExtra : vec4f,
|
|
3583
3721
|
};
|
|
3584
3722
|
|
|
3585
3723
|
@group(0) @binding(0) var<uniform> ou : OpticsUniforms;
|
|
@@ -3598,6 +3736,11 @@ var WGSL_OPTICS_PASS = `struct OpticsUniforms {
|
|
|
3598
3736
|
/// from. Bound at every draw; read only where 'heavyTap.x' says there is one.
|
|
3599
3737
|
@group(0) @binding(8) var backdropHeavy : texture_2d<f32>;
|
|
3600
3738
|
|
|
3739
|
+
/// The surface's PRESENCE per pixel (W27d; contract X6): the 'materialization'
|
|
3740
|
+
/// channel, unioned in the field pass like every other per-surface scalar. One
|
|
3741
|
+
/// channel, in the field pass's fourth target \u2014 see 'wgsl/field.ts'.
|
|
3742
|
+
@group(0) @binding(9) var presenceTexture : texture_2d<f32>;
|
|
3743
|
+
|
|
3601
3744
|
/// One encoded sRGB channel from a linear one \u2014 the space the backdrop tone
|
|
3602
3745
|
/// response's anchors live in (W9). Mirrors material.ts's 'linearToSrgbChannel'.
|
|
3603
3746
|
fn srgb_encode(c : f32) -> f32 {
|
|
@@ -3613,6 +3756,35 @@ fn tone_response(x : f32, sizeK : f32, levelFar : f32) -> f32 {
|
|
|
3613
3756
|
let f = sizeK * sizeK * (3.0 - 2.0 * sizeK);
|
|
3614
3757
|
let ys = mix(ou.toneRowThin.xyz, ou.toneRowThick.xyz, vec3f(f));
|
|
3615
3758
|
let xs = ou.toneAnchor.xyz;
|
|
3759
|
+
if (ou.toneExtra.w > 0.5) {
|
|
3760
|
+
let ys4 = vec4f(ys, mix(ou.toneExtra.y, ou.toneExtra.z, f));
|
|
3761
|
+
let xs4 = vec4f(xs, ou.toneExtra.x);
|
|
3762
|
+
let xc4 = clamp(x, xs4.x, xs4.w);
|
|
3763
|
+
let h0 = max(xs4.y - xs4.x, 1e-4);
|
|
3764
|
+
let h1 = max(xs4.z - xs4.y, 1e-4);
|
|
3765
|
+
let h2 = max(xs4.w - xs4.z, 1e-4);
|
|
3766
|
+
let d0 = (ys4.y - ys4.x) / h0;
|
|
3767
|
+
let d1 = (ys4.z - ys4.y) / h1;
|
|
3768
|
+
let d2 = (ys4.w - ys4.z) / h2;
|
|
3769
|
+
var m1 = 0.0; var m2 = 0.0;
|
|
3770
|
+
if (d0 * d1 > 0.0) { m1 = 2.0 * d0 * d1 / (d0 + d1); }
|
|
3771
|
+
if (d1 * d2 > 0.0) { m2 = 2.0 * d1 * d2 / (d1 + d2); }
|
|
3772
|
+
var h = h0; var t = (xc4 - xs4.x) / h0;
|
|
3773
|
+
var y0 = ys4.x; var y1 = ys4.y; var s0 = d0; var s1 = m1;
|
|
3774
|
+
if (xc4 > xs4.y) {
|
|
3775
|
+
h = h1; t = (xc4 - xs4.y) / h1;
|
|
3776
|
+
y0 = ys4.y; y1 = ys4.z; s0 = m1; s1 = m2;
|
|
3777
|
+
}
|
|
3778
|
+
if (xc4 > xs4.z) {
|
|
3779
|
+
h = h2; t = (xc4 - xs4.z) / h2;
|
|
3780
|
+
y0 = ys4.z; y1 = ys4.w; s0 = m2; s1 = d2;
|
|
3781
|
+
}
|
|
3782
|
+
return y0 * (1.0 + 2.0 * t) * (1.0 - t) * (1.0 - t)
|
|
3783
|
+
+ s0 * h * t * (1.0 - t) * (1.0 - t)
|
|
3784
|
+
+ y1 * t * t * (3.0 - 2.0 * t)
|
|
3785
|
+
+ s1 * h * t * t * (t - 1.0)
|
|
3786
|
+
+ levelFar;
|
|
3787
|
+
}
|
|
3616
3788
|
let xc = clamp(x, xs.x, xs.z);
|
|
3617
3789
|
let h0 = max(xs.y - xs.x, 1e-4);
|
|
3618
3790
|
let h1 = max(xs.z - xs.y, 1e-4);
|
|
@@ -3672,6 +3844,12 @@ struct ShadowSample {
|
|
|
3672
3844
|
alpha : f32,
|
|
3673
3845
|
falloff : f32,
|
|
3674
3846
|
castSpanCss : f32,
|
|
3847
|
+
/// The presence of the surface that CAST the shadow (W27d), read at the offset
|
|
3848
|
+
/// position beside its span. A shadow belongs to the surface above it, so it
|
|
3849
|
+
/// fades with that surface's materialization and not with the one under this
|
|
3850
|
+
/// pixel \u2014 which is a real difference wherever a dissolving surface's shadow
|
|
3851
|
+
/// falls across a present one.
|
|
3852
|
+
castMat : f32,
|
|
3675
3853
|
};
|
|
3676
3854
|
|
|
3677
3855
|
/// The composite's peak linear occlusion above the knee, at a casting span \u2014
|
|
@@ -3702,6 +3880,7 @@ fn outer_shadow(uv : vec2f, upsampled : f32, fieldSize : vec2f) -> ShadowSample
|
|
|
3702
3880
|
out.alpha = 0.0;
|
|
3703
3881
|
out.falloff = 0.0;
|
|
3704
3882
|
out.castSpanCss = 0.0;
|
|
3883
|
+
out.castMat = 1.0;
|
|
3705
3884
|
if (ou.shadow.x <= 0.0 && ou.shadowThick.x <= 0.0) {
|
|
3706
3885
|
return out;
|
|
3707
3886
|
}
|
|
@@ -3729,14 +3908,18 @@ fn outer_shadow(uv : vec2f, upsampled : f32, fieldSize : vec2f) -> ShadowSample
|
|
|
3729
3908
|
let shadowUv = clamp(vec2f(uv.x, shiftedY), vec2f(0.0), vec2f(1.0));
|
|
3730
3909
|
var shadowField : vec4f;
|
|
3731
3910
|
var shadowAux : vec4f;
|
|
3911
|
+
var shadowPresence : vec4f;
|
|
3732
3912
|
if (upsampled > 0.5) {
|
|
3733
3913
|
shadowField = textureSampleLevel(fieldTexture, fieldSampler, shadowUv, 0.0);
|
|
3734
3914
|
shadowAux = textureSampleLevel(auxTexture, fieldSampler, shadowUv, 0.0);
|
|
3915
|
+
shadowPresence = textureSampleLevel(presenceTexture, fieldSampler, shadowUv, 0.0);
|
|
3735
3916
|
} else {
|
|
3736
3917
|
let texel = clamp(vec2i(shadowUv * fieldSize), vec2i(0), vec2i(fieldSize) - vec2i(1));
|
|
3737
3918
|
shadowField = textureLoad(fieldTexture, texel, 0);
|
|
3738
3919
|
shadowAux = textureLoad(auxTexture, texel, 0);
|
|
3920
|
+
shadowPresence = textureLoad(presenceTexture, texel, 0);
|
|
3739
3921
|
}
|
|
3922
|
+
let castMat = clamp(shadowPresence.x, 0.0, 1.0);
|
|
3740
3923
|
|
|
3741
3924
|
// The size law reaches the amplitude and nothing else \u2014 the reference's three
|
|
3742
3925
|
// lengths are span-invariant across 32\u2026160 px. Every span-keyed quantity here
|
|
@@ -3766,9 +3949,12 @@ fn outer_shadow(uv : vec2f, upsampled : f32, fieldSize : vec2f) -> ShadowSample
|
|
|
3766
3949
|
// LINEAR light; then the one conversion to the canvas's compositing space,
|
|
3767
3950
|
// which is where the black term is actually composited.
|
|
3768
3951
|
let occ = clamp(regime + ou.shadowSize.x * sizeK * (1.0 - regime), 0.0, 1.0);
|
|
3769
|
-
|
|
3952
|
+
// Times the casting surface's presence (W27d): a material that is not there
|
|
3953
|
+
// occludes nothing. At presence 1 this is the alpha the bed measures.
|
|
3954
|
+
out.alpha = (1.0 - pow(1.0 - occ, 1.0 / 2.4)) * castMat;
|
|
3770
3955
|
out.falloff = outer_shadow_falloff(shadowField.x + clampedOffCss - ou.shadow.z, ou.shadow.y);
|
|
3771
3956
|
out.castSpanCss = shadowAux.z;
|
|
3957
|
+
out.castMat = castMat;
|
|
3772
3958
|
return out;
|
|
3773
3959
|
}
|
|
3774
3960
|
|
|
@@ -3788,7 +3974,8 @@ fn outer_shadow(uv : vec2f, upsampled : f32, fieldSize : vec2f) -> ShadowSample
|
|
|
3788
3974
|
/// zero where the group has no backdrop to copy \u2014 so 'dark-solid', 'impulse',
|
|
3789
3975
|
/// every thin cell and every unsampled group stay byte-for-byte what they were.
|
|
3790
3976
|
fn outer_shadow_lift(viewport01 : vec2f, shadow : ShadowSample) -> vec3f {
|
|
3791
|
-
if (ou.flags.x <= 0.5
|
|
3977
|
+
if ((ou.flags.x <= 0.5 && ou.heavyTap.y < 1.5) ||
|
|
3978
|
+
ou.shadowLift.x <= 0.0 || shadow.falloff <= 0.0) {
|
|
3792
3979
|
return vec3f(0.0);
|
|
3793
3980
|
}
|
|
3794
3981
|
// Written out rather than through WGSL's 'smoothstep', which is undefined
|
|
@@ -3804,13 +3991,53 @@ fn outer_shadow_lift(viewport01 : vec2f, shadow : ShadowSample) -> vec3f {
|
|
|
3804
3991
|
if (rise <= 0.0) {
|
|
3805
3992
|
return vec3f(0.0);
|
|
3806
3993
|
}
|
|
3994
|
+
if (ou.flags.x <= 0.5) {
|
|
3995
|
+
// A DOM page has no exterior texture: this is the law at the stated tone,
|
|
3996
|
+
// not a claim to reproduce the colour or structure beyond the silhouette.
|
|
3997
|
+
return ou.toneColour.rgb * (ou.shadowLift.x * rise * shadow.falloff);
|
|
3998
|
+
}
|
|
3807
3999
|
let uv = clamp(viewport01 * ou.fit.xy + ou.fit.zw, vec2f(0.0), vec2f(1.0));
|
|
3808
4000
|
let chainSample = textureSampleLevel(backdropChain, backdropSampler, uv, ou.shadowLift.w);
|
|
3809
4001
|
// Premultiplied linear in, straight colour out \u2014 the same unpremultiply the
|
|
3810
4002
|
// body's own samples take, for the same reason: a partially transparent
|
|
3811
4003
|
// backdrop must not darken what the material adds back.
|
|
3812
4004
|
let v = chainSample.rgb / max(chainSample.a, 1e-6);
|
|
3813
|
-
|
|
4005
|
+
// The black term's presence, on the shadow's second term: the two are one
|
|
4006
|
+
// shadow with one falloff (W14 G0), so one channel fades both.
|
|
4007
|
+
return v * (ou.shadowLift.x * rise * shadow.falloff * shadow.castMat);
|
|
4008
|
+
}
|
|
4009
|
+
|
|
4010
|
+
/// The DOM branch is the per-pixel mirror of platform-web's materialAtBackdrop.
|
|
4011
|
+
/// It evaluates the linear response, collapse, paint and rim at the stated tone,
|
|
4012
|
+
/// then solves the encoded layer the browser composites. A union's span stays
|
|
4013
|
+
/// per pixel, and the conversion reference never enables an unknown tone.
|
|
4014
|
+
fn dom_material_backdrop() -> vec3f {
|
|
4015
|
+
if (ou.heavyTap.y > 1.5) { return ou.toneColour.rgb; }
|
|
4016
|
+
return vec3f(ou.heavyTap.z);
|
|
4017
|
+
}
|
|
4018
|
+
|
|
4019
|
+
/// The cssTintAlpha secant, at the actual tone rather than before the response.
|
|
4020
|
+
fn dom_material_alpha(composite : vec3f, backdrop : vec3f, alpha : f32) -> f32 {
|
|
4021
|
+
if (alpha <= 1e-6) { return 0.0; }
|
|
4022
|
+
let weights = vec3f(0.2126, 0.7152, 0.0722);
|
|
4023
|
+
let neutral = max((composite - backdrop * (1.0 - alpha)) / alpha, vec3f(0.0));
|
|
4024
|
+
let b = srgb_encode(dot(backdrop, weights));
|
|
4025
|
+
let span = srgb_encode(dot(neutral, weights)) - b;
|
|
4026
|
+
if (abs(span) < ou.heavyTap.w) { return alpha; }
|
|
4027
|
+
return clamp((srgb_encode(dot(composite, weights)) - b) / span, 0.0, 1.0);
|
|
4028
|
+
}
|
|
4029
|
+
|
|
4030
|
+
/// The final encoded solve, including paint and contour light. The least opacity
|
|
4031
|
+
/// needed to keep every channel in gamut is an algebraic constraint, not a fit.
|
|
4032
|
+
/// At the reference B this returns E(C) exactly after browser source-over; away
|
|
4033
|
+
/// from B the scalar layer cannot reproduce the sampled path's local structure.
|
|
4034
|
+
fn dom_material_output(encodedComposite : vec3f, encodedBackdrop : vec3f, alpha : f32) -> vec4f {
|
|
4035
|
+
let c = clamp(encodedComposite, vec3f(0.0), vec3f(1.0));
|
|
4036
|
+
let b = clamp(encodedBackdrop, vec3f(0.0), vec3f(1.0));
|
|
4037
|
+
let need = select((b - c) / max(b, vec3f(1e-6)),
|
|
4038
|
+
(c - b) / max(vec3f(1.0) - b, vec3f(1e-6)), c >= b);
|
|
4039
|
+
let a = clamp(max(alpha, max(need.x, max(need.y, need.z))), 0.0, 1.0);
|
|
4040
|
+
return vec4f(clamp(c - b * (1.0 - a), vec3f(0.0), vec3f(a)), a);
|
|
3814
4041
|
}
|
|
3815
4042
|
|
|
3816
4043
|
@fragment
|
|
@@ -3823,20 +4050,48 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
3823
4050
|
var field : vec4f;
|
|
3824
4051
|
var aux : vec4f;
|
|
3825
4052
|
var aux2 : vec4f;
|
|
4053
|
+
var presence : vec4f;
|
|
3826
4054
|
if (ou.flags.w > 0.5) {
|
|
3827
4055
|
field = textureSampleLevel(fieldTexture, fieldSampler, in.uv, 0.0);
|
|
3828
4056
|
aux = textureSampleLevel(auxTexture, fieldSampler, in.uv, 0.0);
|
|
3829
4057
|
aux2 = textureSampleLevel(aux2Texture, fieldSampler, in.uv, 0.0);
|
|
4058
|
+
presence = textureSampleLevel(presenceTexture, fieldSampler, in.uv, 0.0);
|
|
3830
4059
|
} else {
|
|
3831
4060
|
let texel = vec2i(in.uv * ou.flags.yz);
|
|
3832
4061
|
field = textureLoad(fieldTexture, texel, 0);
|
|
3833
4062
|
aux = textureLoad(auxTexture, texel, 0);
|
|
3834
4063
|
aux2 = textureLoad(aux2Texture, texel, 0);
|
|
4064
|
+
presence = textureLoad(presenceTexture, texel, 0);
|
|
3835
4065
|
}
|
|
3836
4066
|
|
|
3837
4067
|
let d = field.x;
|
|
3838
4068
|
let normal = field.yz;
|
|
3839
4069
|
let coverage = field.w;
|
|
4070
|
+
/*
|
|
4071
|
+
* The surface's PRESENCE at this pixel (W27d; contract X6) \u2014 the
|
|
4072
|
+
* 'materialization' channel, 1 on a surface nobody is driving.
|
|
4073
|
+
*
|
|
4074
|
+
* It multiplies every term the material ADDS to what is behind it: the lens's
|
|
4075
|
+
* depth and magnitude, the body's mix away from the unblurred backdrop, the
|
|
4076
|
+
* material's own alpha, the author tint's coverage, the inner shadow, the rim,
|
|
4077
|
+
* the outer shadow and the highlight pass's light. It does NOT multiply the
|
|
4078
|
+
* coverage: a presence spent there would be a crossfade of the whole composite,
|
|
4079
|
+
* which is the alpha Apple's rule rules out ("prefer setting the effect
|
|
4080
|
+
* property over the alpha") and which the runtime cannot afford either \u2014 the
|
|
4081
|
+
* host that wrote it would form a Backdrop Root and lose the group's sampling.
|
|
4082
|
+
*
|
|
4083
|
+
* Not to be confused with 'present' below, which is what survives the backdrop
|
|
4084
|
+
* COLLAPSE. The two multiply many of the same terms and mean different things:
|
|
4085
|
+
* one is the author's presence, the other is the material having taken its
|
|
4086
|
+
* backdrop's tone. Both are one multiplication by one on the resting bed.
|
|
4087
|
+
*
|
|
4088
|
+
* The channel is strictly ABOVE zero here. Exactly 0 is 'Glass.identity' and is
|
|
4089
|
+
* resolved on the CPU by dropping the member before this pass ever runs
|
|
4090
|
+
* ('instances.ts'), so a surface that is not there has no silhouette to draw a
|
|
4091
|
+
* faded material into and no shape to union with its neighbours. What this
|
|
4092
|
+
* shader owns is the continuum between the endpoints.
|
|
4093
|
+
*/
|
|
4094
|
+
let mat = clamp(presence.x, 0.0, 1.0);
|
|
3840
4095
|
|
|
3841
4096
|
/*
|
|
3842
4097
|
* The outer shadow (W8) sits UNDER the material, so it is resolved before the
|
|
@@ -3892,7 +4147,13 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
3892
4147
|
// Per-pixel, unioned through the field pass. See the module note. 'aux.x' is
|
|
3893
4148
|
// the authored thickness times the lensStrength channel (W12 G2); the lens's
|
|
3894
4149
|
// depth and the inner shadow's are both evaluated from it and the span below.
|
|
3895
|
-
|
|
4150
|
+
//
|
|
4151
|
+
// Times the presence (W27d), because this is the one number Apple's own
|
|
4152
|
+
// description of materializing names \u2014 "by gradually modulating the light
|
|
4153
|
+
// bending and lensing" \u2014 and both depths are functions of it, so the lens
|
|
4154
|
+
// shallows and weakens together and the inner shadow's depth follows the same
|
|
4155
|
+
// channel rather than a second statement of it.
|
|
4156
|
+
let lensThick = max(aux.x, 0.0) * mat;
|
|
3896
4157
|
// The thickness curve off the span of whichever surface owns this pixel
|
|
3897
4158
|
// (W11c). 'sizeK' is the thickness factor, 0..1: zero on anything at or below
|
|
3898
4159
|
// the profile's 'sizeSpanMin', saturated at 'sizeSpanMax', folded under the
|
|
@@ -4070,6 +4331,8 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4070
4331
|
let scatterLod = clamp(ou.size.w + log2(max(gainEff, 1e-4)), 0.0, ou.lens.w);
|
|
4071
4332
|
|
|
4072
4333
|
var backdrop = vec3f(0.0);
|
|
4334
|
+
let domMaterial = ou.heavyTap.y > 0.5;
|
|
4335
|
+
if (domMaterial) { backdrop = dom_material_backdrop(); }
|
|
4073
4336
|
if (ou.flags.x > 0.5) {
|
|
4074
4337
|
// Both components at the refracted position (W11c G2): the band and the
|
|
4075
4338
|
// interior are one body, and the displacement alone is the lens.
|
|
@@ -4105,6 +4368,26 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4105
4368
|
// the glass.
|
|
4106
4369
|
let scatterColour = scatterSample.rgb / max(scatterSample.a, 1e-6);
|
|
4107
4370
|
backdrop = mix(bodySample.rgb / max(bodySample.a, 1e-6), scatterColour, kScatter);
|
|
4371
|
+
/*
|
|
4372
|
+
* The body's own half of the presence (W27d): a material at half presence
|
|
4373
|
+
* shows half the BLUR, not half the surface. What a surface at presence 0
|
|
4374
|
+
* stands over is the page as it is, so the two components' composite lerps
|
|
4375
|
+
* back to the unblurred backdrop \u2014 the chain's own level 0, which is the
|
|
4376
|
+
* texture before any of the pyramid's widths were applied.
|
|
4377
|
+
*
|
|
4378
|
+
* Read at 'refractedUv' rather than at this pixel's own position: the lens is
|
|
4379
|
+
* scaled by the same channel, so the sample walks back to the pixel as the
|
|
4380
|
+
* presence falls and arrives exactly there at 0. One uv, one read, and no
|
|
4381
|
+
* discontinuity between the two ends.
|
|
4382
|
+
*
|
|
4383
|
+
* The branch is what keeps the resting material byte-identical \u2014 at presence
|
|
4384
|
+
* 1 the extra tap is not taken at all \u2014 and it is also what keeps a present
|
|
4385
|
+
* surface from paying for a channel it is not using.
|
|
4386
|
+
*/
|
|
4387
|
+
if (mat < 1.0) {
|
|
4388
|
+
let sharpSample = textureSampleLevel(backdropChain, backdropSampler, refractedUv, 0.0);
|
|
4389
|
+
backdrop = mix(sharpSample.rgb / max(sharpSample.a, 1e-6), backdrop, mat);
|
|
4390
|
+
}
|
|
4108
4391
|
}
|
|
4109
4392
|
|
|
4110
4393
|
// Adaptive tint. 'adapt.w' is the strength the accessibility policy and the
|
|
@@ -4255,7 +4538,7 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4255
4538
|
* There the CSS tier's own 'backdrop-filter' is what carries the transmission.
|
|
4256
4539
|
*/
|
|
4257
4540
|
var toneTarget = ou.toneColour.rgb;
|
|
4258
|
-
if (ou.flags.x > 0.5) {
|
|
4541
|
+
if (ou.flags.x > 0.5 || domMaterial) {
|
|
4259
4542
|
toneTarget = mix(toneTarget, backdrop, clamp(ou.toneRowThick.w, 0.0, 1.0));
|
|
4260
4543
|
}
|
|
4261
4544
|
|
|
@@ -4273,7 +4556,15 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4273
4556
|
// opaque" is a statement about how much material there is), and the backdrop
|
|
4274
4557
|
// adaptation moved it above. The author's colour never touches it \u2014 but not
|
|
4275
4558
|
// for the reason the composition contract first gave (claims \xA75.36).
|
|
4276
|
-
|
|
4559
|
+
/*
|
|
4560
|
+
* The material's alpha, times the presence (W27d) \u2014 and applied HERE rather
|
|
4561
|
+
* than to 'adaptedAlpha' above, which is load-bearing: that alpha is the
|
|
4562
|
+
* divisor the collapse's own composite is un-premultiplied by, so scaling it
|
|
4563
|
+
* there would move the adapted COLOUR as well as the amount of it. Presence is
|
|
4564
|
+
* how much of the material is there, not what the material is.
|
|
4565
|
+
*/
|
|
4566
|
+
let presentAlpha = adaptedAlpha * mat;
|
|
4567
|
+
var colour = mix(backdrop, adapted, presentAlpha);
|
|
4277
4568
|
/*
|
|
4278
4569
|
* How much of this pixel the SURFACE owns, as the canvas will composite it.
|
|
4279
4570
|
*
|
|
@@ -4295,10 +4586,41 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4295
4586
|
* in encoded sRGB, so the alpha is the CSS tier's, not the linear profile's.
|
|
4296
4587
|
*/
|
|
4297
4588
|
var bodyAlpha = 1.0;
|
|
4298
|
-
|
|
4589
|
+
var domAlpha = 1.0;
|
|
4590
|
+
if (domMaterial) {
|
|
4591
|
+
// The collapse transmits k*c of the DOM proxy as well. Solve the secant
|
|
4592
|
+
// after the linear material, never feed its encoded alpha back into R.
|
|
4593
|
+
/*
|
|
4594
|
+
* Times the presence (W27d), on the same factor 'presentAlpha' carries into
|
|
4595
|
+
* 'colour' just above \u2014 this branch's body is a SOLVED layer rather than a
|
|
4596
|
+
* composite, so the secant's own input is where the channel reaches it.
|
|
4597
|
+
*
|
|
4598
|
+
* It has to be here rather than on the result. The secant divides the
|
|
4599
|
+
* composite by this alpha to recover the material's own neutral, so scaling
|
|
4600
|
+
* both together leaves that neutral (and the span it spans) at exactly what
|
|
4601
|
+
* presence 1 solves, and only the returned coverage travels. Left unscaled,
|
|
4602
|
+
* the neutral would walk toward the backdrop as the surface thins, the span
|
|
4603
|
+
* would fall under 'heavyTap.w', and the guard would hand back the FULL
|
|
4604
|
+
* alpha \u2014 a flat tone painted over a page the surface has left.
|
|
4605
|
+
*
|
|
4606
|
+
* At presence 1 the factor is exactly 1.0 and the expression is bit-identical
|
|
4607
|
+
* to the resting one; at 0 the secant's own '<= 1e-6' guard returns 0.
|
|
4608
|
+
*/
|
|
4609
|
+
let transmission = toneAdapt * clamp(ou.toneRowThick.w, 0.0, 1.0);
|
|
4610
|
+
domAlpha = dom_material_alpha(colour, backdrop,
|
|
4611
|
+
clamp(adaptedAlpha - transmission, 0.0, 1.0) * mat);
|
|
4612
|
+
} else if (ou.flags.x <= 0.5) {
|
|
4299
4613
|
colour = adapted;
|
|
4300
|
-
bodyAlpha =
|
|
4614
|
+
bodyAlpha = presentAlpha;
|
|
4301
4615
|
}
|
|
4616
|
+
/*
|
|
4617
|
+
* One gap this tier cannot close from here, named rather than left to be
|
|
4618
|
+
* discovered (W27d): on an unsampled group the blurred backdrop is a DOM proxy
|
|
4619
|
+
* beneath this canvas, so the body's mix toward the unblurred backdrop above
|
|
4620
|
+
* has no texture to mix with. A layer that fades to alpha 0 there reveals the
|
|
4621
|
+
* PROXY's blur rather than the page \u2014 presence takes the tint, the rim and the
|
|
4622
|
+
* shadows out, and the blur is the host's to fade with it.
|
|
4623
|
+
*/
|
|
4302
4624
|
|
|
4303
4625
|
// The author tint (W10). 'aux.w' is the per-pixel strength, unioned in the
|
|
4304
4626
|
// field pass, so a toolbar can carry one tinted control among plain ones; the
|
|
@@ -4360,16 +4682,40 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4360
4682
|
* reach painted pixels only (W23 S10).
|
|
4361
4683
|
*/
|
|
4362
4684
|
var rimTintColour = vec3f(1.0);
|
|
4363
|
-
|
|
4685
|
+
/*
|
|
4686
|
+
* The author tint's coverage at this pixel, times the presence (W27d). The
|
|
4687
|
+
* paint is part of the material and not a thing painted onto the page, so a
|
|
4688
|
+
* dissolving surface takes its colour with it \u2014 at presence 0 the pixel is the
|
|
4689
|
+
* backdrop and not a flat orange over it. At presence 1 this is
|
|
4690
|
+
* 'clamp(aux.w, 0, 1)' exactly, which is what the tint's own law was fitted on.
|
|
4691
|
+
*/
|
|
4692
|
+
let tintK = clamp(aux.w, 0.0, 1.0) * mat;
|
|
4693
|
+
if (tintK > 0.0) {
|
|
4364
4694
|
// The untinted material's luminance at this pixel. Over a backdrop that is
|
|
4365
4695
|
// the composite; as a layer it is the layer over the tone the host measured
|
|
4366
4696
|
// for the group \u2014 zero where nothing was measured, the same reference-level
|
|
4367
4697
|
// convention the CSS tier's 'materialLuminance' takes (within its 0.02).
|
|
4368
4698
|
let u = bodyAlpha * dot(colour, vec3f(0.2126, 0.7152, 0.0722)) + (1.0 - bodyAlpha) * ou.toneColour.w;
|
|
4369
|
-
let grip = clamp(ou.seed.w, 0.0, 1.0) * clamp(ou.tone.z, 0.0, 1.0) *
|
|
4699
|
+
let grip = clamp(ou.seed.w, 0.0, 1.0) * clamp(ou.tone.z, 0.0, 1.0) *
|
|
4700
|
+
(1.0 - toneAdapt * (1.0 - clamp(ou.rim.w, 0.0, 1.0)));
|
|
4370
4701
|
let shade = mix(1.0, clamp(mix(ou.tone.x, ou.tone.y, clamp(u, 0.0, 1.0)), 0.0, 1.0), grip);
|
|
4371
|
-
|
|
4372
|
-
|
|
4702
|
+
// The identity branch preserves the active seed's arithmetic bit for bit.
|
|
4703
|
+
var seed = ou.seed.rgb;
|
|
4704
|
+
if (ou.rim.z < 1.0) {
|
|
4705
|
+
let neutral = max(seed.r, max(seed.g, seed.b));
|
|
4706
|
+
seed = mix(vec3f(neutral), seed, clamp(ou.rim.z, 0.0, 1.0));
|
|
4707
|
+
}
|
|
4708
|
+
let layer = seed * shade;
|
|
4709
|
+
/*
|
|
4710
|
+
* The recede's chroma collapse (W27c) shapes WHAT the paint is; presence
|
|
4711
|
+
* (W27d) is how much of it is there. They compose on this one strength and
|
|
4712
|
+
* each reaches it once: the collapse through 'seed', the presence through
|
|
4713
|
+
* 'tintK'. 's' is the coverage every consumer below reads \u2014 the rim's tint
|
|
4714
|
+
* mix, the encoded fold, and the DOM branch's own alpha \u2014 so folding the
|
|
4715
|
+
* presence in here is what keeps it from being applied twice downstream.
|
|
4716
|
+
*/
|
|
4717
|
+
let s = tintK;
|
|
4718
|
+
if (domMaterial) { domAlpha = 1.0 - (1.0 - s) * (1.0 - domAlpha); }
|
|
4373
4719
|
let layerLuma = max(dot(layer, vec3f(0.2126, 0.7152, 0.0722)), 0.05);
|
|
4374
4720
|
rimTintColour = mix(vec3f(1.0), layer / layerLuma, clamp(ou.rimLaw.w, 0.0, 1.0) * s);
|
|
4375
4721
|
let encodedMaterial = linear_to_srgb(clamp(colour, vec3f(0.0), vec3f(1.0)));
|
|
@@ -4412,7 +4758,11 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4412
4758
|
// A multiplicative occlusion of the whole composite. As a layer that is the
|
|
4413
4759
|
// colour scaled and the alpha raised \u2014 (k\xB7a\xB7c, 1 \u2212 k\xB7(1 \u2212 a)) composites to
|
|
4414
4760
|
// k times what (a\xB7c, a) would \u2014 and at bodyAlpha 1 it is the plain product.
|
|
4415
|
-
|
|
4761
|
+
// Times the presence (W27d) on the AMPLITUDE, beside the depth the same channel
|
|
4762
|
+
// already shallowed through 'lensThick': the occlusion is the material's own,
|
|
4763
|
+
// and a material that is half there occludes half as much of what is behind it.
|
|
4764
|
+
let shadowKeep = 1.0 - shadowProfile * shadowDepth * ou.light.w * present * mat;
|
|
4765
|
+
if (domMaterial) { domAlpha = 1.0 - shadowKeep * (1.0 - domAlpha); }
|
|
4416
4766
|
let shadowedAlpha = 1.0 - shadowKeep * (1.0 - bodyAlpha);
|
|
4417
4767
|
colour = colour * (shadowKeep * bodyAlpha / max(shadowedAlpha, 1e-6));
|
|
4418
4768
|
bodyAlpha = shadowedAlpha;
|
|
@@ -4464,7 +4814,7 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4464
4814
|
let rimLuma = materialAlpha * dot(materialColour, vec3f(0.2126, 0.7152, 0.0722))
|
|
4465
4815
|
+ (1.0 - materialAlpha) * ou.toneColour.w;
|
|
4466
4816
|
let rimAmplitude = ou.rim.y + ou.rimLaw.x * rimLuma;
|
|
4467
|
-
let rimCollapsed = mix(ou.rimLaw.y, ou.rimLaw.z,
|
|
4817
|
+
let rimCollapsed = mix(ou.rimLaw.y, ou.rimLaw.z, tintK);
|
|
4468
4818
|
/*
|
|
4469
4819
|
* The lit edge (W24; claims \xA75.107) \u2014 the directional factor the whole rim is
|
|
4470
4820
|
* multiplied by, symmetric about 'rimLit.xy'.
|
|
@@ -4524,10 +4874,15 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4524
4874
|
*/
|
|
4525
4875
|
let alongSide = clamp((rel.x / halfExt.x) * (rel.y / halfExt.y), -1.0, 1.0);
|
|
4526
4876
|
let alongFactor = max(1.0 + ou.rimLit.w * sizeThick * alongSide, 0.0);
|
|
4527
|
-
|
|
4877
|
+
// The whole rim \u2014 both the appearance's own and the one the collapse keeps \u2014
|
|
4878
|
+
// times the presence (W27d). The rim is the mark that says a surface is HERE,
|
|
4879
|
+
// which is the first thing a surface that is not there stops saying; the same
|
|
4880
|
+
// argument the collapse's 'present' makes, from the author's side.
|
|
4881
|
+
let rim = rw * lit * alongFactor * (rimAmplitude * present + rimCollapsed * toneAdapt) * mat;
|
|
4528
4882
|
let rimLight = rim * rimTintColour;
|
|
4529
|
-
if (ou.flags.x > 0.5) {
|
|
4883
|
+
if (ou.flags.x > 0.5 || domMaterial) {
|
|
4530
4884
|
colour = colour + rimLight;
|
|
4885
|
+
if (domMaterial) { domAlpha = clamp(domAlpha + rim, 0.0, 1.0); }
|
|
4531
4886
|
} else {
|
|
4532
4887
|
// Added light has no premultiplied form of its own \u2014 a canvas colour may
|
|
4533
4888
|
// not exceed its alpha \u2014 so the layer carries the light in its opacity:
|
|
@@ -4555,6 +4910,17 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4555
4910
|
// translucent surface shows the page through it, not its own shadow. (With
|
|
4556
4911
|
// an opaque body the two are the same quantity, which is how the shadow was
|
|
4557
4912
|
// first written and why the difference only surfaced with the layer form.)
|
|
4913
|
+
if (domMaterial) {
|
|
4914
|
+
// Coverage precedes the gamut solve. The sampled rim may exceed white
|
|
4915
|
+
// before antialiasing; clipping it first would dim the half-covered edge.
|
|
4916
|
+
// Include the exterior shadow in the same target so its light and opacity
|
|
4917
|
+
// remain one valid premultiplied layer at that edge too.
|
|
4918
|
+
let b = linear_to_srgb(backdrop);
|
|
4919
|
+
let compositeEncoded = linear_to_srgb(max(colour, vec3f(0.0))) * coverage
|
|
4920
|
+
+ (b * (1.0 - shadowAlpha) + liftEncoded) * (1.0 - coverage);
|
|
4921
|
+
let alpha = domAlpha * coverage + shadowAlpha * (1.0 - coverage);
|
|
4922
|
+
return dom_material_output(compositeEncoded, b, alpha);
|
|
4923
|
+
}
|
|
4558
4924
|
let body = encode_output(max(colour, vec3f(0.0)), coverage * bodyAlpha);
|
|
4559
4925
|
return vec4f(
|
|
4560
4926
|
body.rgb + liftEncoded * (1.0 - coverage),
|
|
@@ -4647,10 +5013,12 @@ function allShaderSource() {
|
|
|
4647
5013
|
|
|
4648
5014
|
// ../renderer-webgpu/dist/passes.js
|
|
4649
5015
|
var fieldUsage = () => GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING;
|
|
5016
|
+
var PRESENCE_TEXTURE_FORMAT = "r16float";
|
|
4650
5017
|
var PREMULTIPLIED_OVER = {
|
|
4651
5018
|
color: { srcFactor: "one", dstFactor: "one-minus-src-alpha", operation: "add" },
|
|
4652
5019
|
alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha", operation: "add" }
|
|
4653
5020
|
};
|
|
5021
|
+
var groupResourceId = (plane, groupId) => plane === "" ? groupId : `${plane}/${groupId}`;
|
|
4654
5022
|
function createPassRunner(context) {
|
|
4655
5023
|
const { device, pool, cache } = context;
|
|
4656
5024
|
const uniforms = /* @__PURE__ */ new Map();
|
|
@@ -4690,7 +5058,8 @@ function createPassRunner(context) {
|
|
|
4690
5058
|
targets: [
|
|
4691
5059
|
{ format: WORKING_TEXTURE_FORMAT },
|
|
4692
5060
|
{ format: WORKING_TEXTURE_FORMAT },
|
|
4693
|
-
{ format: WORKING_TEXTURE_FORMAT }
|
|
5061
|
+
{ format: WORKING_TEXTURE_FORMAT },
|
|
5062
|
+
{ format: PRESENCE_TEXTURE_FORMAT }
|
|
4694
5063
|
]
|
|
4695
5064
|
},
|
|
4696
5065
|
primitive: { topology: "triangle-list" }
|
|
@@ -4741,28 +5110,35 @@ function createPassRunner(context) {
|
|
|
4741
5110
|
const rectHeight = Math.max(1, Math.round(args.rectDevice.height));
|
|
4742
5111
|
const width = Math.max(1, Math.round(args.rectDevice.width * args.renderScale));
|
|
4743
5112
|
const height = Math.max(1, Math.round(args.rectDevice.height * args.renderScale));
|
|
4744
|
-
const field = pool.acquire(poolKey.groupField(args.
|
|
5113
|
+
const field = pool.acquire(poolKey.groupField(args.resourceId), {
|
|
4745
5114
|
width,
|
|
4746
5115
|
height,
|
|
4747
5116
|
format: WORKING_TEXTURE_FORMAT,
|
|
4748
5117
|
usage: fieldUsage(),
|
|
4749
|
-
label: `vitrea:group:${args.
|
|
5118
|
+
label: `vitrea:group:${args.resourceId}:field`
|
|
4750
5119
|
});
|
|
4751
|
-
const aux = pool.acquire(poolKey.groupAux(args.
|
|
5120
|
+
const aux = pool.acquire(poolKey.groupAux(args.resourceId), {
|
|
4752
5121
|
width,
|
|
4753
5122
|
height,
|
|
4754
5123
|
format: WORKING_TEXTURE_FORMAT,
|
|
4755
5124
|
usage: fieldUsage(),
|
|
4756
|
-
label: `vitrea:group:${args.
|
|
5125
|
+
label: `vitrea:group:${args.resourceId}:aux`
|
|
4757
5126
|
});
|
|
4758
|
-
const aux2 = pool.acquire(poolKey.groupAux2(args.
|
|
5127
|
+
const aux2 = pool.acquire(poolKey.groupAux2(args.resourceId), {
|
|
4759
5128
|
width,
|
|
4760
5129
|
height,
|
|
4761
5130
|
format: WORKING_TEXTURE_FORMAT,
|
|
4762
5131
|
usage: fieldUsage(),
|
|
4763
|
-
label: `vitrea:group:${args.
|
|
5132
|
+
label: `vitrea:group:${args.resourceId}:aux2`
|
|
5133
|
+
});
|
|
5134
|
+
const presence = pool.acquire(poolKey.groupPresence(args.resourceId), {
|
|
5135
|
+
width,
|
|
5136
|
+
height,
|
|
5137
|
+
format: PRESENCE_TEXTURE_FORMAT,
|
|
5138
|
+
usage: fieldUsage(),
|
|
5139
|
+
label: `vitrea:group:${args.resourceId}:presence`
|
|
4764
5140
|
});
|
|
4765
|
-
const slot = uniformSlot(`field:${args.
|
|
5141
|
+
const slot = uniformSlot(`field:${args.resourceId}`, 12);
|
|
4766
5142
|
slot.data[0] = rectWidth;
|
|
4767
5143
|
slot.data[1] = rectHeight;
|
|
4768
5144
|
slot.data[2] = args.cssPerDevice;
|
|
@@ -4776,12 +5152,12 @@ function createPassRunner(context) {
|
|
|
4776
5152
|
slot.data[11] = 0;
|
|
4777
5153
|
new Uint32Array(slot.data.buffer, slot.data.byteOffset + 32, 1)[0] = args.instanceCount;
|
|
4778
5154
|
slot.write();
|
|
4779
|
-
const instances = storageSlot(args.
|
|
5155
|
+
const instances = storageSlot(args.resourceId);
|
|
4780
5156
|
instances.ensure(Math.max(args.instanceCount, 1) * INSTANCE_BYTES);
|
|
4781
5157
|
instances.write(args.instances, Math.max(args.instanceCount, 1) * (INSTANCE_BYTES / 4));
|
|
4782
5158
|
const pipeline = fieldPipeline(args.family);
|
|
4783
5159
|
const pass = encoder.beginRenderPass({
|
|
4784
|
-
label: `vitrea:pass:field:${args.
|
|
5160
|
+
label: `vitrea:pass:field:${args.resourceId}`,
|
|
4785
5161
|
...timed(PASS_LABEL.field),
|
|
4786
5162
|
colorAttachments: [
|
|
4787
5163
|
{
|
|
@@ -4801,6 +5177,15 @@ function createPassRunner(context) {
|
|
|
4801
5177
|
loadOp: "clear",
|
|
4802
5178
|
storeOp: "store",
|
|
4803
5179
|
clearValue: { r: 0, g: 0, b: 0, a: 0 }
|
|
5180
|
+
},
|
|
5181
|
+
{
|
|
5182
|
+
view: presence.createView(),
|
|
5183
|
+
loadOp: "clear",
|
|
5184
|
+
// Cleared to the IDLE presence rather than to zero: a texel the
|
|
5185
|
+
// fullscreen triangle never wrote must not read as a material that
|
|
5186
|
+
// has been asked to disappear.
|
|
5187
|
+
storeOp: "store",
|
|
5188
|
+
clearValue: { r: 1, g: 0, b: 0, a: 0 }
|
|
4804
5189
|
}
|
|
4805
5190
|
]
|
|
4806
5191
|
});
|
|
@@ -4818,13 +5203,14 @@ function createPassRunner(context) {
|
|
|
4818
5203
|
field,
|
|
4819
5204
|
aux,
|
|
4820
5205
|
aux2,
|
|
5206
|
+
presence,
|
|
4821
5207
|
width,
|
|
4822
5208
|
height,
|
|
4823
5209
|
upsampled: width !== rectWidth || height !== rectHeight
|
|
4824
5210
|
};
|
|
4825
5211
|
},
|
|
4826
5212
|
opticsPass(encoder, args) {
|
|
4827
|
-
const slot = uniformSlot(`optics:${args.
|
|
5213
|
+
const slot = uniformSlot(`optics:${args.resourceId}`, 116);
|
|
4828
5214
|
const d = slot.data;
|
|
4829
5215
|
d[0] = args.viewportDevice[0];
|
|
4830
5216
|
d[1] = args.viewportDevice[1];
|
|
@@ -4856,8 +5242,8 @@ function createPassRunner(context) {
|
|
|
4856
5242
|
d[27] = args.sizeFold;
|
|
4857
5243
|
d[28] = args.rimWidth;
|
|
4858
5244
|
d[29] = args.rimAlpha;
|
|
4859
|
-
d[30] = args.
|
|
4860
|
-
d[31] = args.
|
|
5245
|
+
d[30] = args.tintChromaScale ?? 1;
|
|
5246
|
+
d[31] = args.tintShadeCollapseRetention ?? 0;
|
|
4861
5247
|
d[32] = args.lightDirection[0];
|
|
4862
5248
|
d[33] = args.lightDirection[1];
|
|
4863
5249
|
d[34] = args.shadowDepth;
|
|
@@ -4935,16 +5321,20 @@ function createPassRunner(context) {
|
|
|
4935
5321
|
d[106] = 0;
|
|
4936
5322
|
d[107] = 0;
|
|
4937
5323
|
d[108] = args.heavyTapEnabled ? 1 : 0;
|
|
4938
|
-
d[109] = 0;
|
|
4939
|
-
d[110] = 0;
|
|
4940
|
-
d[111] = 0;
|
|
5324
|
+
d[109] = args.domMaterial?.mode ?? 0;
|
|
5325
|
+
d[110] = args.domMaterial?.referenceBackdropLuminance ?? 0;
|
|
5326
|
+
d[111] = args.domMaterial?.minimumTintContrast ?? 0;
|
|
5327
|
+
d[112] = args.backdropToneAnchorX[3] ?? args.backdropToneAnchorX[2];
|
|
5328
|
+
d[113] = args.backdropToneResponseThin[3] ?? args.backdropToneResponseThin[2];
|
|
5329
|
+
d[114] = args.backdropToneResponseThick[3] ?? args.backdropToneResponseThick[2];
|
|
5330
|
+
d[115] = args.backdropToneAnchorX.length === 4 ? 1 : 0;
|
|
4941
5331
|
slot.write();
|
|
4942
5332
|
const chain = args.backdrop?.chain ?? placeholderView;
|
|
4943
5333
|
const body = args.backdrop?.body ?? placeholderView;
|
|
4944
5334
|
const heavy = args.backdrop?.heavy ?? placeholderView;
|
|
4945
5335
|
const pipeline = opticsPipeline(args.targetFormat);
|
|
4946
5336
|
const pass = encoder.beginRenderPass({
|
|
4947
|
-
label: `vitrea:pass:optics:${args.
|
|
5337
|
+
label: `vitrea:pass:optics:${args.resourceId}`,
|
|
4948
5338
|
...timed(PASS_LABEL.optics),
|
|
4949
5339
|
colorAttachments: [{ view: args.target, loadOp: "load", storeOp: "store" }]
|
|
4950
5340
|
});
|
|
@@ -4963,14 +5353,15 @@ function createPassRunner(context) {
|
|
|
4963
5353
|
// read at all when the governor shrank them below the group's rect.
|
|
4964
5354
|
{ binding: 6, resource: context.flatSampler },
|
|
4965
5355
|
{ binding: 7, resource: args.fields.aux2.createView() },
|
|
4966
|
-
{ binding: 8, resource: heavy }
|
|
5356
|
+
{ binding: 8, resource: heavy },
|
|
5357
|
+
{ binding: 9, resource: args.fields.presence.createView() }
|
|
4967
5358
|
]
|
|
4968
5359
|
}));
|
|
4969
5360
|
pass.draw(3);
|
|
4970
5361
|
pass.end();
|
|
4971
5362
|
},
|
|
4972
5363
|
highlightPass(encoder, args) {
|
|
4973
|
-
const slot = uniformSlot(`highlight:${args.
|
|
5364
|
+
const slot = uniformSlot(`highlight:${args.resourceId}`, 32);
|
|
4974
5365
|
const d = slot.data;
|
|
4975
5366
|
d[0] = args.viewportDevice[0];
|
|
4976
5367
|
d[1] = args.viewportDevice[1];
|
|
@@ -5008,7 +5399,7 @@ function createPassRunner(context) {
|
|
|
5008
5399
|
slot.write();
|
|
5009
5400
|
const pipeline = highlightPipeline(args.targetFormat);
|
|
5010
5401
|
const pass = encoder.beginRenderPass({
|
|
5011
|
-
label: `vitrea:pass:highlight:${args.
|
|
5402
|
+
label: `vitrea:pass:highlight:${args.resourceId}`,
|
|
5012
5403
|
...timed(PASS_LABEL.highlight),
|
|
5013
5404
|
colorAttachments: [{ view: args.target, loadOp: "load", storeOp: "store" }]
|
|
5014
5405
|
});
|
|
@@ -5020,7 +5411,8 @@ function createPassRunner(context) {
|
|
|
5020
5411
|
{ binding: 0, resource: { buffer: slot.buffer } },
|
|
5021
5412
|
{ binding: 1, resource: args.fields.field.createView() },
|
|
5022
5413
|
{ binding: 2, resource: args.fields.aux.createView() },
|
|
5023
|
-
{ binding: 3, resource: context.flatSampler }
|
|
5414
|
+
{ binding: 3, resource: context.flatSampler },
|
|
5415
|
+
{ binding: 4, resource: args.fields.presence.createView() }
|
|
5024
5416
|
]
|
|
5025
5417
|
}));
|
|
5026
5418
|
pass.draw(3);
|
|
@@ -5043,13 +5435,15 @@ function createPassRunner(context) {
|
|
|
5043
5435
|
setTimeline(next) {
|
|
5044
5436
|
timeline = next;
|
|
5045
5437
|
},
|
|
5046
|
-
forget(
|
|
5047
|
-
pool.release(poolKey.groupField(
|
|
5048
|
-
pool.release(poolKey.groupAux(
|
|
5049
|
-
pool.release(poolKey.groupAux2(
|
|
5050
|
-
|
|
5051
|
-
storages.
|
|
5052
|
-
|
|
5438
|
+
forget(resourceId) {
|
|
5439
|
+
pool.release(poolKey.groupField(resourceId));
|
|
5440
|
+
pool.release(poolKey.groupAux(resourceId));
|
|
5441
|
+
pool.release(poolKey.groupAux2(resourceId));
|
|
5442
|
+
pool.release(poolKey.groupPresence(resourceId));
|
|
5443
|
+
storages.get(resourceId)?.destroy();
|
|
5444
|
+
storages.delete(resourceId);
|
|
5445
|
+
for (const pass of ["field", "optics", "highlight"]) {
|
|
5446
|
+
const key = `${pass}:${resourceId}`;
|
|
5053
5447
|
uniforms.get(key)?.buffer.destroy();
|
|
5054
5448
|
uniforms.delete(key);
|
|
5055
5449
|
}
|
|
@@ -5710,6 +6104,7 @@ function createWebGPURenderer(options = {}) {
|
|
|
5710
6104
|
let generations = 0;
|
|
5711
6105
|
let lastFrameTimeMs;
|
|
5712
6106
|
let targets;
|
|
6107
|
+
const planesDrawn = /* @__PURE__ */ new Set();
|
|
5713
6108
|
let pendingEncoder;
|
|
5714
6109
|
let pendingRebuilds = 0;
|
|
5715
6110
|
let pendingUnbuilt = [];
|
|
@@ -5831,7 +6226,7 @@ function createWebGPURenderer(options = {}) {
|
|
|
5831
6226
|
return 0;
|
|
5832
6227
|
return heavyTapSigmaAtScale(material, viewport.devicePixelRatio) / Math.max(viewport.devicePixelRatio, 1e-3);
|
|
5833
6228
|
};
|
|
5834
|
-
const groupTintSeed = (input) => input.surfaces.find((surface) => surface
|
|
6229
|
+
const groupTintSeed = (input) => input.surfaces.find((surface) => drawsMaterial(surface) && (surface.tint?.strength ?? 0) > 0)?.tint?.color;
|
|
5835
6230
|
const stateOf = (input, resolution) => {
|
|
5836
6231
|
const resolved = resolution?.groups.find((group) => group.groupId === input.groupId);
|
|
5837
6232
|
if (resolved === void 0) {
|
|
@@ -5933,10 +6328,15 @@ function createWebGPURenderer(options = {}) {
|
|
|
5933
6328
|
];
|
|
5934
6329
|
const skipped = [];
|
|
5935
6330
|
let drawn = 0;
|
|
6331
|
+
planesDrawn.add(active.plane);
|
|
6332
|
+
const resourceOf = (groupId) => groupResourceId(active.plane, groupId);
|
|
6333
|
+
const releaseIdle = (groupId) => passes.forget(resourceOf(groupId));
|
|
5936
6334
|
for (const entry of groups.values()) {
|
|
5937
6335
|
const input = entry.input;
|
|
5938
|
-
if (input.surfaces.length === 0)
|
|
6336
|
+
if (input.surfaces.length === 0) {
|
|
6337
|
+
releaseIdle(input.groupId);
|
|
5939
6338
|
continue;
|
|
6339
|
+
}
|
|
5940
6340
|
const policy = resolution?.accessibility.material ?? accessibility;
|
|
5941
6341
|
let surfaces;
|
|
5942
6342
|
try {
|
|
@@ -5946,6 +6346,7 @@ function createWebGPURenderer(options = {}) {
|
|
|
5946
6346
|
groupId: input.groupId,
|
|
5947
6347
|
reason: error instanceof Error ? error.message : String(error)
|
|
5948
6348
|
});
|
|
6349
|
+
releaseIdle(input.groupId);
|
|
5949
6350
|
continue;
|
|
5950
6351
|
}
|
|
5951
6352
|
const union = unionOf(input);
|
|
@@ -5958,15 +6359,17 @@ function createWebGPURenderer(options = {}) {
|
|
|
5958
6359
|
const shadowReachPx = outerShadowReachPx(shadow, reachOcclusion);
|
|
5959
6360
|
const snapped = snapRectToDevicePixels(groupFieldRect(surfaces, union, void 0, shadowReachPx), dpr);
|
|
5960
6361
|
const rectDevice = clipFieldRectToCanvas(snapped, dpr, viewportDevice);
|
|
5961
|
-
if (rectDevice === void 0)
|
|
6362
|
+
if (rectDevice === void 0) {
|
|
6363
|
+
releaseIdle(input.groupId);
|
|
5962
6364
|
continue;
|
|
6365
|
+
}
|
|
5963
6366
|
const surfaceRectDevice = shadowReachPx === 0 ? rectDevice : clipFieldRectToCanvas(snapRectToDevicePixels(groupFieldRect(surfaces, union), dpr), dpr, viewportDevice) ?? rectDevice;
|
|
5964
6367
|
const packed = packInstances(surfaces, [
|
|
5965
6368
|
rectDevice.x * cssPerDevice,
|
|
5966
6369
|
rectDevice.y * cssPerDevice
|
|
5967
6370
|
]);
|
|
5968
6371
|
const fields = passes.fieldPass(encoder, {
|
|
5969
|
-
|
|
6372
|
+
resourceId: resourceOf(input.groupId),
|
|
5970
6373
|
family: governor.knobs.fieldFamily,
|
|
5971
6374
|
rectDevice,
|
|
5972
6375
|
cssPerDevice,
|
|
@@ -5984,11 +6387,7 @@ function createWebGPURenderer(options = {}) {
|
|
|
5984
6387
|
const pyramid = sourceId === void 0 ? void 0 : pyramids.resources(sourceId);
|
|
5985
6388
|
const adapt = sourceId === void 0 ? void 0 : adaptationFor(sourceId).values;
|
|
5986
6389
|
const nominalOptics = material.optics[variant];
|
|
5987
|
-
const optics = opticsUnderPolicy(
|
|
5988
|
-
...nominalOptics,
|
|
5989
|
-
tint: input.unsampledMaterial.tint,
|
|
5990
|
-
tintAlpha: input.unsampledMaterial.tintAlpha
|
|
5991
|
-
} : nominalOptics, policy, material);
|
|
6390
|
+
const optics = opticsUnderPolicy(nominalOptics, policy, material);
|
|
5992
6391
|
const backdropTone = [
|
|
5993
6392
|
material.backdropToneLow,
|
|
5994
6393
|
material.backdropToneHigh,
|
|
@@ -5999,7 +6398,7 @@ function createWebGPURenderer(options = {}) {
|
|
|
5999
6398
|
const refraction = effectiveRefraction(accessibilityRefractionCap(policy), state.refraction);
|
|
6000
6399
|
const refractionScale = material.refractionScale[refraction];
|
|
6001
6400
|
passes.opticsPass(encoder, {
|
|
6002
|
-
|
|
6401
|
+
resourceId: resourceOf(input.groupId),
|
|
6003
6402
|
target: active.optics,
|
|
6004
6403
|
targetFormat: active.format,
|
|
6005
6404
|
rectDevice,
|
|
@@ -6043,6 +6442,8 @@ function createWebGPURenderer(options = {}) {
|
|
|
6043
6442
|
tintSeed: (policy.glass === "none" ? void 0 : groupTintSeed(input)) ?? optics.tint,
|
|
6044
6443
|
tintToneAdaptation: tintToneAdaptation(policy, material),
|
|
6045
6444
|
tintShade: [material.tintShadeDark, material.tintShadeLight, material.tintShadeStrength],
|
|
6445
|
+
tintChromaScale: material.tintChromaScale ?? 1,
|
|
6446
|
+
tintShadeCollapseRetention: material.tintShadeCollapseRetention ?? 0,
|
|
6046
6447
|
// The band's half-width is a per-scale reading since W23: the reference's
|
|
6047
6448
|
// rim narrows between the scales where vitrea's widened (claims §5.100
|
|
6048
6449
|
// §5). At dpr 1, and on any variant whose two anchors are equal, this is
|
|
@@ -6091,6 +6492,10 @@ function createWebGPURenderer(options = {}) {
|
|
|
6091
6492
|
// itself is already in the texture, so this pass only chooses which of
|
|
6092
6493
|
// two textures the deep sample comes from.
|
|
6093
6494
|
heavyTapEnabled: pyramid?.heavy !== void 0,
|
|
6495
|
+
...pyramid === void 0 && input.unsampledMaterial !== void 0 ? { domMaterial: {
|
|
6496
|
+
...input.unsampledMaterial,
|
|
6497
|
+
mode: input.backdropTone === void 0 ? 1 : 2
|
|
6498
|
+
} } : {},
|
|
6094
6499
|
shadowDepth: optics.shadowDepth,
|
|
6095
6500
|
shadowAlpha: optics.shadowAlpha,
|
|
6096
6501
|
// The size law's gains, per group (W2); the per-pixel factor they
|
|
@@ -6196,9 +6601,9 @@ function createWebGPURenderer(options = {}) {
|
|
|
6196
6601
|
shadow.thickOcclusionAt160
|
|
6197
6602
|
],
|
|
6198
6603
|
outerShadowLift: [
|
|
6199
|
-
//
|
|
6200
|
-
//
|
|
6201
|
-
pyramid === void 0 ||
|
|
6604
|
+
// A DOM layer can evaluate the lift at its stated tone, but not at
|
|
6605
|
+
// unknown exterior pixels. No tone still means no light to add.
|
|
6606
|
+
policy.glass === "none" || pyramid === void 0 && (input.unsampledMaterial === void 0 || input.backdropTone === void 0) ? 0 : shadow.liftAmplitude,
|
|
6202
6607
|
shadow.liftSpanMin,
|
|
6203
6608
|
shadow.liftSpanFull,
|
|
6204
6609
|
liftChainLod(shadow.liftBlurSigmaCss, pyramid)
|
|
@@ -6214,7 +6619,7 @@ function createWebGPURenderer(options = {}) {
|
|
|
6214
6619
|
if (active.highlight !== void 0) {
|
|
6215
6620
|
const lead = surfaces.reduce((best, surface) => surface.channels.glow > best.channels.glow ? surface : best, surfaces[0]);
|
|
6216
6621
|
passes.highlightPass(encoder, {
|
|
6217
|
-
|
|
6622
|
+
resourceId: resourceOf(input.groupId),
|
|
6218
6623
|
target: active.highlight,
|
|
6219
6624
|
targetFormat: active.format,
|
|
6220
6625
|
// The surface's own rect, not the shadow's — see `surfaceRectDevice`.
|
|
@@ -6361,7 +6766,8 @@ function createWebGPURenderer(options = {}) {
|
|
|
6361
6766
|
},
|
|
6362
6767
|
removeGroup(groupId) {
|
|
6363
6768
|
groups.delete(groupId);
|
|
6364
|
-
|
|
6769
|
+
for (const plane of planesDrawn)
|
|
6770
|
+
runner?.forget(groupResourceId(plane, groupId));
|
|
6365
6771
|
},
|
|
6366
6772
|
setAccessibility(policy) {
|
|
6367
6773
|
accessibility = policy;
|
|
@@ -6377,7 +6783,8 @@ function createWebGPURenderer(options = {}) {
|
|
|
6377
6783
|
targets = {
|
|
6378
6784
|
optics: next.optics,
|
|
6379
6785
|
...next.highlight === void 0 ? {} : { highlight: next.highlight },
|
|
6380
|
-
format: next.format ?? OUTPUT_TEXTURE_FORMAT
|
|
6786
|
+
format: next.format ?? OUTPUT_TEXTURE_FORMAT,
|
|
6787
|
+
plane: next.plane ?? ""
|
|
6381
6788
|
};
|
|
6382
6789
|
},
|
|
6383
6790
|
drawFrame(args) {
|
|
@@ -6385,7 +6792,8 @@ function createWebGPURenderer(options = {}) {
|
|
|
6385
6792
|
targets = {
|
|
6386
6793
|
optics: args.optics,
|
|
6387
6794
|
...args.highlight === void 0 ? {} : { highlight: args.highlight },
|
|
6388
|
-
format: args.format ?? OUTPUT_TEXTURE_FORMAT
|
|
6795
|
+
format: args.format ?? OUTPUT_TEXTURE_FORMAT,
|
|
6796
|
+
plane: args.plane ?? ""
|
|
6389
6797
|
};
|
|
6390
6798
|
pyramids.beginFrame(args.frame.id);
|
|
6391
6799
|
pyramids.setTimeline(args.timing);
|
|
@@ -6502,6 +6910,6 @@ function createWebGPURenderer(options = {}) {
|
|
|
6502
6910
|
};
|
|
6503
6911
|
}
|
|
6504
6912
|
|
|
6505
|
-
export { ADAPTIVE_LUMINANCE_HIGH, ADAPTIVE_LUMINANCE_LOW, ADAPTIVE_TINT_DARK, ADAPTIVE_TINT_LIGHT, ANALYSIS_DISPATCH, ANALYSIS_GRID, ANALYSIS_PASS_ID, ANALYSIS_STATS_FLOATS, ANALYSIS_TARGET_EXTENT, ANALYSIS_WORKGROUP, BACKDROP_ALPHA_MODES, BACKDROP_COLOR_SPACES, BACKDROP_KINDS, BACKDROP_PASS_ID, BACKDROP_TONE_HIGH, BACKDROP_TONE_LOW, BACKDROP_TONE_MAX, BACKDROP_TONE_SIZE_BIAS, CANVAS_FORMAT, CHAIN_SIGMA_AT_LEVEL_1, CROSS_CHECK_SHAPE_FLOATS, CROSS_CHECK_WORKGROUP, DEFAULT_MATERIAL_PROFILE, FAMILY_C_CROSS_CHECK, FIELD_PASS_ID, GOVERNOR_LADDER, HIGHLIGHT_PASS_ID, IDENTITY_FIT, IDLE_CHANNELS, INCREASED_OCCLUSION_LIFT, INSTANCE_BYTES, INSTANCE_FLOATS, LENS_AMOUNT_MAX, LENS_AMOUNT_PER_SPAN, LENS_EXTENT_GAIN, LENS_HEIGHT_MAX, LENS_HEIGHT_PER_SPAN, LENS_OVALIZATION, LENS_PROFILE_EXPONENT, LENS_REFRACTION_GAIN, LENS_SIZE_GAIN_MAX, LENS_THICKNESS_REFERENCE, LUMINANCE_WEIGHTS, MATERIAL_OPTICS, MATERIAL_VARIANTS, MAX_CHAIN_LEVELS, MIN_LEVEL_EXTENT, NOMINAL_GOVERNOR, NOMINAL_MATERIAL_POLICY, OPTICS_PASS_ID, OUTER_SHADOW, OUTER_SHADOW_THICK_SPANS, OUTER_SHADOW_THIN_L, OUTER_SHADOW_UNMEASURED_BACKDROP_LUMINANCE, OUTPUT_TEXTURE_FORMAT, PASS_LABEL, REFRACTION_LADDER, REFRACTION_SCALE, RENDERER_ERROR_CODES, RENDERER_PASS_IDS, RendererError, SIZE_OCCLUSION_GAIN, SIZE_SCATTER_FLOOR, SIZE_SCATTER_FLOOR_2X, SIZE_SCATTER_GAIN_FAR_2X, SIZE_SCATTER_GAIN_MAX, SIZE_SCATTER_GAIN_MAX_2X, SIZE_SCATTER_RAMP_REACH_1X_PX, SIZE_SCATTER_RAMP_REACH_2X_PX, SIZE_SCATTER_RAMP_START_FAR_1X, SIZE_SCATTER_RAMP_START_FAR_2X, SIZE_SCATTER_RAMP_START_THICK_1X, SIZE_SCATTER_RAMP_START_THICK_2X, SIZE_SCATTER_RAMP_START_THIN_1X, SIZE_SCATTER_RAMP_START_THIN_2X, SIZE_SCATTER_SPAN_MAX, SIZE_SCATTER_SPAN_MAX_2X, SIZE_SHADOW_GAIN_MAX, SIZE_SPAN_MAX, SIZE_SPAN_MIN, SRGB_ENCODING_EXPONENT, SUPPORTED_APP_TEXTURE_FORMATS, WGSL_ANALYSIS_PASS, WGSL_CROSS_CHECK_PASS, WGSL_DOWNSAMPLE_PASS, WGSL_FIELD_KERNELS, WGSL_FIELD_PASS, WGSL_FIELD_SAMPLE, WGSL_HIGHLIGHT_PASS, WGSL_IMPORT_PASS, WGSL_INSTANCE_STRUCT, WGSL_OPTICS_PASS, WGSL_PRELUDE, WGSL_RSUPN_GRAD, WGSL_RSUP_GRAD, WGSL_SMOOTH_UNION, WORKING_TEXTURE_FORMAT, ZERO_STATS, accessibilityRefractionCap, adaptationStrength, adaptedTintAlpha, adaptedTintColour, adaptiveTint, allShaderSource, alphaNormalisationMode, analysisModule, backdropFit, backdropToneAdaptation, backdropToneResponse, backdropToneSizeBiasUnderPolicy, backdropToneSolveWeight, backdropToneUnderPolicy, bodyBlurPlan, chainModule, clipFieldRectToCanvas, collapsedRimUnderPolicy, coverFit, createAdaptationState, createAppTextureProvider, createCopyProvider, createDeviceHost, createGovernor, createGpuContext, createGradientProvider, createPassRunner, createPipelineCache, createPyramidStore, createRebuildLedger, createStorageSlot, createTexturePool, createTimingCollector, createUniformSlot, createVideoProvider, createWebGPURenderer, crossCheckKernelModule, displayP3ToSrgbLinear, effectiveRefraction, encodeOutput, encodeOutputBytes, fieldModule, fieldPassSource, groupFieldRect, heavyTapSigmaAtScale, highlightModule, importColorMatrix, importModule, importPassSource, isUsablePlacement, lensAmountBasePx, lensDepthPx, lensDirection, lensDisplacementPx, lensExtentPx, lensHeightBasePx, lensMagnitudePx, lensOvalizationAt, lensSizeGain, lensSizeGainFromThickness, linearGradientStops, linearToSrgb, linearToSrgbChannel, occlusionAlphaUnderPolicy, opticsModule, opticsUnderPolicy, outerShadowAlpha, outerShadowFalloff, outerShadowLiftRise, outerShadowOcclusionAt, outerShadowReachPx, outerShadowThickOcclusion, outerShadowThinOcclusion, outerShadowUnderPolicy, packInstances, pipelineKey, placementFit, planPyramid, poolKey, readbackDue, refractionRank, relativeLuminance, rendererError, resolveSurfaces, rimAlongSideFactor, rimAlongSideField, samePlacement, scatterDeepThickness, scatterFloorAtScale, scatterGainAt, scatterGainAtScale, scatterGainFarAtScale, scatterHeavyShareThickAtScale, scatterRampAreaMean, scatterRampReachDevicePx, scatterRampStart, scatterSharpShare, scatterSpanMaxAtScale, scatterThickness, shadowDepthPx, sizeOcclusionAlpha, sizeOcclusionAlphaAt, sizeOuterShadowOcclusion, sizeOuterShadowOcclusionAt, sizeScatterSigma, sizeScatterSigmaAt, sizeShadowDepth, sizeShadowDepthAt, sizeThickness, sizeThicknessUnderPolicy, sizeToneLevelFar, snapRectToDevicePixels, srgbToLinear, srgbToLinearChannel, statsFromBuffer, supportsTimestamps, texelsPerCssPx, tintShade, tintShadeLayer, tintToneAdaptation, tintedMaterialColour, validateAppTexture, withMaterialOverrides };
|
|
6506
|
-
//# sourceMappingURL=dist-
|
|
6507
|
-
//# sourceMappingURL=dist-
|
|
6913
|
+
export { ADAPTIVE_LUMINANCE_HIGH, ADAPTIVE_LUMINANCE_LOW, ADAPTIVE_TINT_DARK, ADAPTIVE_TINT_LIGHT, ANALYSIS_DISPATCH, ANALYSIS_GRID, ANALYSIS_PASS_ID, ANALYSIS_STATS_FLOATS, ANALYSIS_TARGET_EXTENT, ANALYSIS_WORKGROUP, BACKDROP_ALPHA_MODES, BACKDROP_COLOR_SPACES, BACKDROP_KINDS, BACKDROP_PASS_ID, BACKDROP_TONE_HIGH, BACKDROP_TONE_LOW, BACKDROP_TONE_MAX, BACKDROP_TONE_SIZE_BIAS, CANVAS_FORMAT, CHAIN_SIGMA_AT_LEVEL_1, CROSS_CHECK_SHAPE_FLOATS, CROSS_CHECK_WORKGROUP, DEFAULT_MATERIAL_PROFILE, FAMILY_C_CROSS_CHECK, FIELD_PASS_ID, GOVERNOR_LADDER, HIGHLIGHT_PASS_ID, IDENTITY_FIT, IDLE_CHANNELS, INCREASED_OCCLUSION_LIFT, INSTANCE_BYTES, INSTANCE_FLOATS, LENS_AMOUNT_MAX, LENS_AMOUNT_PER_SPAN, LENS_EXTENT_GAIN, LENS_HEIGHT_MAX, LENS_HEIGHT_PER_SPAN, LENS_OVALIZATION, LENS_PROFILE_EXPONENT, LENS_REFRACTION_GAIN, LENS_SIZE_GAIN_MAX, LENS_THICKNESS_REFERENCE, LUMINANCE_WEIGHTS, MATERIAL_OPTICS, MATERIAL_VARIANTS, MAX_CHAIN_LEVELS, MIN_LEVEL_EXTENT, NOMINAL_GOVERNOR, NOMINAL_MATERIAL_POLICY, OPTICS_PASS_ID, OUTER_SHADOW, OUTER_SHADOW_THICK_SPANS, OUTER_SHADOW_THIN_L, OUTER_SHADOW_UNMEASURED_BACKDROP_LUMINANCE, OUTPUT_TEXTURE_FORMAT, PASS_LABEL, REFRACTION_LADDER, REFRACTION_SCALE, RENDERER_ERROR_CODES, RENDERER_PASS_IDS, RendererError, SIZE_OCCLUSION_GAIN, SIZE_SCATTER_FLOOR, SIZE_SCATTER_FLOOR_2X, SIZE_SCATTER_GAIN_FAR_2X, SIZE_SCATTER_GAIN_MAX, SIZE_SCATTER_GAIN_MAX_2X, SIZE_SCATTER_RAMP_REACH_1X_PX, SIZE_SCATTER_RAMP_REACH_2X_PX, SIZE_SCATTER_RAMP_START_FAR_1X, SIZE_SCATTER_RAMP_START_FAR_2X, SIZE_SCATTER_RAMP_START_THICK_1X, SIZE_SCATTER_RAMP_START_THICK_2X, SIZE_SCATTER_RAMP_START_THIN_1X, SIZE_SCATTER_RAMP_START_THIN_2X, SIZE_SCATTER_SPAN_MAX, SIZE_SCATTER_SPAN_MAX_2X, SIZE_SHADOW_GAIN_MAX, SIZE_SPAN_MAX, SIZE_SPAN_MIN, SRGB_ENCODING_EXPONENT, SUPPORTED_APP_TEXTURE_FORMATS, WGSL_ANALYSIS_PASS, WGSL_CROSS_CHECK_PASS, WGSL_DOWNSAMPLE_PASS, WGSL_FIELD_KERNELS, WGSL_FIELD_PASS, WGSL_FIELD_SAMPLE, WGSL_HIGHLIGHT_PASS, WGSL_IMPORT_PASS, WGSL_INSTANCE_STRUCT, WGSL_OPTICS_PASS, WGSL_PRELUDE, WGSL_RSUPN_GRAD, WGSL_RSUP_GRAD, WGSL_SMOOTH_UNION, WORKING_TEXTURE_FORMAT, ZERO_STATS, accessibilityRefractionCap, adaptationStrength, adaptedTintAlpha, adaptedTintColour, adaptiveTint, allShaderSource, alphaNormalisationMode, analysisModule, backdropFit, backdropToneAdaptation, backdropToneResponse, backdropToneSizeBiasUnderPolicy, backdropToneSolveWeight, backdropToneUnderPolicy, bodyBlurPlan, chainModule, clipFieldRectToCanvas, collapsedRimUnderPolicy, coverFit, createAdaptationState, createAppTextureProvider, createCopyProvider, createDeviceHost, createGovernor, createGpuContext, createGradientProvider, createPassRunner, createPipelineCache, createPyramidStore, createRebuildLedger, createStorageSlot, createTexturePool, createTimingCollector, createUniformSlot, createVideoProvider, createWebGPURenderer, crossCheckKernelModule, displayP3ToSrgbLinear, effectiveRefraction, encodeOutput, encodeOutputBytes, fieldModule, fieldPassSource, groupFieldRect, heavyTapSigmaAtScale, highlightModule, importColorMatrix, importModule, importPassSource, isUsablePlacement, lensAmountBasePx, lensDepthPx, lensDirection, lensDisplacementPx, lensExtentPx, lensHeightBasePx, lensMagnitudePx, lensOvalizationAt, lensSizeGain, lensSizeGainFromThickness, linearGradientStops, linearToSrgb, linearToSrgbChannel, occlusionAlphaUnderPolicy, occlusionLiftForPolicy, opticsModule, opticsUnderPolicy, outerShadowAlpha, outerShadowFalloff, outerShadowLiftRise, outerShadowOcclusionAt, outerShadowReachPx, outerShadowThickOcclusion, outerShadowThinOcclusion, outerShadowUnderPolicy, packInstances, pipelineKey, placementFit, planPyramid, poolKey, readbackDue, refractionRank, relativeLuminance, rendererError, resolveSurfaces, rimAlongSideFactor, rimAlongSideField, samePlacement, scatterDeepThickness, scatterFloorAtScale, scatterGainAt, scatterGainAtScale, scatterGainFarAtScale, scatterHeavyShareThickAtScale, scatterRampAreaMean, scatterRampReachDevicePx, scatterRampStart, scatterSharpShare, scatterSpanMaxAtScale, scatterThickness, shadowDepthPx, sizeOcclusionAlpha, sizeOcclusionAlphaAt, sizeOuterShadowOcclusion, sizeOuterShadowOcclusionAt, sizeScatterSigma, sizeScatterSigmaAt, sizeShadowDepth, sizeShadowDepthAt, sizeThickness, sizeThicknessUnderPolicy, sizeToneLevelFar, snapRectToDevicePixels, srgbToLinear, srgbToLinearChannel, statsFromBuffer, supportsTimestamps, texelsPerCssPx, tintShade, tintShadeLayer, tintToneAdaptation, tintedMaterialColour, validateAppTexture, withMaterialOverrides };
|
|
6914
|
+
//# sourceMappingURL=dist-T7PRMUM4.js.map
|
|
6915
|
+
//# sourceMappingURL=dist-T7PRMUM4.js.map
|