@vitreajs/vitrea 0.19.0 → 0.21.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/dist/{dist-VQPRX7BX.js → dist-N437MSRG.js} +505 -23
- package/dist/dist-N437MSRG.js.map +1 -0
- package/dist/index.d.ts +249 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/dist-VQPRX7BX.js.map +0 -1
|
@@ -226,6 +226,15 @@ function occlusionLiftForPolicy(policy, profile = DEFAULT_MATERIAL_PROFILE) {
|
|
|
226
226
|
const levels = profile.increasedOcclusionLiftByPolicy;
|
|
227
227
|
return policy.ambientTint === "reduced" ? levels?.increaseContrast ?? profile.increasedOcclusionLift : levels?.reduceTransparency ?? profile.increasedOcclusionLift;
|
|
228
228
|
}
|
|
229
|
+
function bodyChromaRetentionUnderPolicy(retention, policy) {
|
|
230
|
+
switch (policy.occlusion) {
|
|
231
|
+
case "nominal":
|
|
232
|
+
return retention;
|
|
233
|
+
case "increased":
|
|
234
|
+
case "opaque":
|
|
235
|
+
return 0;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
229
238
|
var DEFAULT_MATERIAL_PROFILE = {
|
|
230
239
|
optics: {
|
|
231
240
|
// σ = 8 for the regular variant, which keeps this package's blur and
|
|
@@ -735,6 +744,18 @@ var DEFAULT_MATERIAL_PROFILE = {
|
|
|
735
744
|
// chain's level-1 width, and the tracker carries the floor that would close it.
|
|
736
745
|
sizeHeavyTapSigma: 9,
|
|
737
746
|
sizeHeavyTapSigma2x: 9,
|
|
747
|
+
// W30 G2's spanning set for the scale-selective scatter, at the values that
|
|
748
|
+
// make every term of it exactly zero (claims §5.156 §3, §5.158). The share is
|
|
749
|
+
// the single gate: at 0 no second heavy texture is allocated, no pass is
|
|
750
|
+
// encoded and no sample is taken, so the two widths are unread and the
|
|
751
|
+
// reference is unreachable behind its own zero gain. The two signed amounts
|
|
752
|
+
// are the scheme-conditioned leaves §5.159 fits; the widths and the reference
|
|
753
|
+
// are one raster's property and are not.
|
|
754
|
+
sizeHeavySecondSigma: 0,
|
|
755
|
+
sizeHeavySecondSigma2x: 0,
|
|
756
|
+
sizeHeavySecondShare: 0,
|
|
757
|
+
sizeScatterScaleGain: 0,
|
|
758
|
+
sizeScatterScaleRef: 0,
|
|
738
759
|
sizeOcclusionGain: 0.05,
|
|
739
760
|
sizeShadowGainMax: 1,
|
|
740
761
|
/*
|
|
@@ -906,6 +927,17 @@ var DEFAULT_MATERIAL_PROFILE = {
|
|
|
906
927
|
*/
|
|
907
928
|
collapseTransmission: 0.017,
|
|
908
929
|
collapseTransmission2x: 0.07,
|
|
930
|
+
/*
|
|
931
|
+
* **SHIPS AT 0** (W31 G3; claims §5.164). The identity, and a post-seal leaf's
|
|
932
|
+
* default IS its identity, forever: `MATERIAL_IDENTITY_TABLE` is append-only
|
|
933
|
+
* and the fingerprint drops this leaf while it holds this value, so a default
|
|
934
|
+
* that moved off 0 would move every shipped document's digest at once.
|
|
935
|
+
*
|
|
936
|
+
* The macOS 27 documents carry their fitted values as patches; the two frozen
|
|
937
|
+
* macOS 26.5 documents carry none, which is what makes their recorded digests
|
|
938
|
+
* reproduce under the rule (claims §5.161 §7b).
|
|
939
|
+
*/
|
|
940
|
+
bodyChromaRetention: 0,
|
|
909
941
|
/*
|
|
910
942
|
* FITTED 0.038 (W23 G1; claims §5.100 §3, W23 Decision Log 2 (b)) — and it is
|
|
911
943
|
* NOT the dark material's rim, which is the one thing the charter thought it
|
|
@@ -1079,6 +1111,14 @@ var DEFAULT_MATERIAL_PROFILE = {
|
|
|
1079
1111
|
outerShadow: {
|
|
1080
1112
|
offsetPx: 7.95,
|
|
1081
1113
|
sigmaPx: 15.55,
|
|
1114
|
+
// W30 G2's σ law, at the three zeros that make it the identity (claims
|
|
1115
|
+
// §5.156 §2, §5.158): σ(span) = sigmaPx + max(0, 0 · (span − 0)) = sigmaPx,
|
|
1116
|
+
// at every span and every scale. The macOS 26.5 material's σ genuinely is
|
|
1117
|
+
// span-invariant — 15.4…15.9 CSS px across spans 32…160 — so these zeros are
|
|
1118
|
+
// that measurement and not a placeholder for it.
|
|
1119
|
+
sigmaSlopePerSpan: 0,
|
|
1120
|
+
sigmaSpanRefPx: 0,
|
|
1121
|
+
sigmaThinOffsetPx: 0,
|
|
1082
1122
|
spreadPx: 3.1,
|
|
1083
1123
|
thinOcclusionDark: 0,
|
|
1084
1124
|
thinOcclusionMid: 0.33,
|
|
@@ -1100,6 +1140,90 @@ var DEFAULT_MATERIAL_PROFILE = {
|
|
|
1100
1140
|
glowGain: 0.6,
|
|
1101
1141
|
sweepGain: 0.85
|
|
1102
1142
|
};
|
|
1143
|
+
var MATERIAL_DIGEST_RULE_VERSION = 2;
|
|
1144
|
+
var MATERIAL_IDENTITY_TABLE = [
|
|
1145
|
+
{
|
|
1146
|
+
wave: "W30",
|
|
1147
|
+
/*
|
|
1148
|
+
* A TWO-LEAF gate, and the second leaf is in it rather than gated by it.
|
|
1149
|
+
* `sigmaThinOffsetPx` is not gated by the slope — at slope 0 a non-zero
|
|
1150
|
+
* offset moves σ at every span — and it is not inert on its own at a
|
|
1151
|
+
* non-zero slope either, where it is a real floor on the line. What the
|
|
1152
|
+
* committed case proves is the pair TOGETHER, and the grouping that would
|
|
1153
|
+
* put the offset under the slope's gate merges a macOS 26.5 light material
|
|
1154
|
+
* carrying `sigmaThinOffsetPx` 5 — five CSS px of extra blur on every outer
|
|
1155
|
+
* shadow, on both tiers — into the frozen digest itself (claims §5.161 §11,
|
|
1156
|
+
* finding B4 (b)).
|
|
1157
|
+
*/
|
|
1158
|
+
gate: { "outerShadow.sigmaSlopePerSpan": 0, "outerShadow.sigmaThinOffsetPx": 0 },
|
|
1159
|
+
gated: ["outerShadow.sigmaSpanRefPx"],
|
|
1160
|
+
law: "\u03C3(span) = sigmaPx + max(sigmaThinOffsetPx, sigmaSlopePerSpan\xB7(span \u2212 sigmaSpanRefPx))",
|
|
1161
|
+
inertLawCase: 'packages/renderer-webgpu/test/w31-gate-groups.test.ts \u2014 "gate-group 1 \u2014 {sigmaSlopePerSpan 0, sigmaThinOffsetPx 0} gates sigmaSpanRefPx"; with the shipped-value half in w30-inert-laws.test.ts',
|
|
1162
|
+
whyGated: "The pivot is multiplied by the slope, so at slope 0 no value of it can reach \u03C3. The offset is NOT gated by the slope and is in the gate for that reason.",
|
|
1163
|
+
claims: "c9a \xA75.156 \xA72, \xA75.158, \xA75.161 \xA77b"
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
wave: "W30",
|
|
1167
|
+
gate: { sizeHeavySecondShare: 0 },
|
|
1168
|
+
gated: ["sizeHeavySecondSigma", "sizeHeavySecondSigma2x"],
|
|
1169
|
+
law: "deep = heavy + sizeHeavySecondShare\xB7(heavy2 \u2212 heavy), heavy2 at sizeHeavySecondSigma{,2x}",
|
|
1170
|
+
inertLawCase: 'packages/renderer-webgpu/test/w31-gate-groups.test.ts \u2014 "gate-group 2 \u2014 {sizeHeavySecondShare 0} gates the two second-heavy widths"; with the shipped-value half in w30-inert-laws.test.ts',
|
|
1171
|
+
whyGated: "At share 0 the second heavy texture is not allocated, no pass is encoded and the optics pass never samples one, so the widths are unread whatever they hold.",
|
|
1172
|
+
claims: "c9a \xA75.156 \xA73, \xA75.158, \xA75.161 \xA77b"
|
|
1173
|
+
},
|
|
1174
|
+
{
|
|
1175
|
+
wave: "W30",
|
|
1176
|
+
gate: { sizeScatterScaleGain: 0 },
|
|
1177
|
+
gated: ["sizeScatterScaleRef"],
|
|
1178
|
+
law: "kScatter += sizeScatterScaleGain\xB7(stat \u2212 sizeScatterScaleRef)",
|
|
1179
|
+
inertLawCase: 'packages/renderer-webgpu/test/w31-gate-groups.test.ts \u2014 "gate-group 3 \u2014 {sizeScatterScaleGain 0} gates sizeScatterScaleRef"; with the shipped-value half in w30-inert-laws.test.ts',
|
|
1180
|
+
whyGated: "The reference is only ever read as a difference the gain multiplies, so at gain 0 no value of it can reach the mix. The macOS 27 LIGHT document exercises this entry: it declines the scatter with the gain at 0 and ships the reference at 0.03.",
|
|
1181
|
+
claims: "c9a \xA75.156 \xA73, \xA75.158, \xA75.161 \xA77b"
|
|
1182
|
+
},
|
|
1183
|
+
{
|
|
1184
|
+
wave: "W31",
|
|
1185
|
+
/*
|
|
1186
|
+
* A plain value drop, and injective for free. The retention multiplies the
|
|
1187
|
+
* mix's second term, so at 0 the composite is bit-identical to the one W30
|
|
1188
|
+
* left — which is what the goldens and the composite-identity case below
|
|
1189
|
+
* assert, and what lets this leaf land without an exemption.
|
|
1190
|
+
*/
|
|
1191
|
+
gate: { bodyChromaRetention: 0 },
|
|
1192
|
+
gated: [],
|
|
1193
|
+
law: "colour = gamutAtLuma(mix(colour, backdrop\xB7(Y/Y_backdrop), bodyChromaRetention), Y)",
|
|
1194
|
+
inertLawCase: `packages/renderer-webgpu/test/w31-body-chroma.test.ts \u2014 "the composite is bit-identical at retention 0", "linear luma is held at every retention" and "is the shader's expression, term for term"; the drawn half in packages/renderer-webgpu/e2e/gpu/w31-body-chroma.spec.ts \u2014 "is bit-identical at the shipped identity, named explicitly" and "ON draws differently from OFF"; the CSS tier's half in packages/platform-web/test/w30-css-declaration-identity.test.ts, which compares every declaration against bytes recorded before any leaf existed`,
|
|
1195
|
+
whyGated: "Not gated \u2014 a plain value drop. At retention 0 the mix's second term is multiplied by zero and `colour` leaves the composite exactly as mix(backdrop, adapted, presentAlpha) produced it.",
|
|
1196
|
+
claims: "c9a \xA75.161 \xA75, \xA75.164",
|
|
1197
|
+
declaredFirstAs: {
|
|
1198
|
+
law: "colour = renormaliseToLinearLuma(mix(colour, chromaticityOf(backdrop) at colour's luma, bodyChromaRetention))",
|
|
1199
|
+
inertLawCase: "TO BE COMMITTED BY W31 G3 \u2014 the leaf does not exist yet. G0 names the shape and its identity (W31 X2); the case that proves the composite is bit-identical at 0, and the `test:gpu` case that the on state draws differently from off, land with the leaf."
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
];
|
|
1203
|
+
function materialLeafAt(resolved, path) {
|
|
1204
|
+
return path.split(".").reduce((node, key) => node !== null && typeof node === "object" ? node[key] : void 0, resolved);
|
|
1205
|
+
}
|
|
1206
|
+
function materialDigestDroppedLeaves(resolved) {
|
|
1207
|
+
const dropped = [];
|
|
1208
|
+
for (const entry of MATERIAL_IDENTITY_TABLE) {
|
|
1209
|
+
const held = Object.entries(entry.gate).every(([path, identity]) => {
|
|
1210
|
+
const value = materialLeafAt(resolved, path);
|
|
1211
|
+
return value !== void 0 && value === identity;
|
|
1212
|
+
});
|
|
1213
|
+
if (held)
|
|
1214
|
+
dropped.push(...Object.keys(entry.gate), ...entry.gated);
|
|
1215
|
+
}
|
|
1216
|
+
return dropped.sort();
|
|
1217
|
+
}
|
|
1218
|
+
function materialDigestInput(resolved) {
|
|
1219
|
+
const dropped = materialDigestDroppedLeaves(resolved);
|
|
1220
|
+
const strip = (value, prefix = "") => {
|
|
1221
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
1222
|
+
return value;
|
|
1223
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [prefix === "" ? key : `${prefix}.${key}`, key, child]).filter(([path]) => !dropped.includes(path)).map(([path, key, child]) => [key, strip(child, path)]));
|
|
1224
|
+
};
|
|
1225
|
+
return strip(resolved);
|
|
1226
|
+
}
|
|
1103
1227
|
var REFRACTION_SCALE = DEFAULT_MATERIAL_PROFILE.refractionScale;
|
|
1104
1228
|
var MATERIAL_OPTICS = DEFAULT_MATERIAL_PROFILE.optics;
|
|
1105
1229
|
var ADAPTIVE_TINT_DARK = DEFAULT_MATERIAL_PROFILE.adaptiveTintDark;
|
|
@@ -1220,6 +1344,14 @@ function withMaterialOverrides(base, patch) {
|
|
|
1220
1344
|
sizeToneLevelFar: patch.sizeToneLevelFar ?? base.sizeToneLevelFar,
|
|
1221
1345
|
sizeHeavyTapSigma: patch.sizeHeavyTapSigma ?? base.sizeHeavyTapSigma,
|
|
1222
1346
|
sizeHeavyTapSigma2x: patch.sizeHeavyTapSigma2x ?? base.sizeHeavyTapSigma2x,
|
|
1347
|
+
// W30 G2's spanning set. One line each, because this merge is explicit per
|
|
1348
|
+
// leaf and a leaf without its own line resolves silently to the base —
|
|
1349
|
+
// which for a leaf a document is meant to fit is a fit that does nothing.
|
|
1350
|
+
sizeHeavySecondSigma: patch.sizeHeavySecondSigma ?? base.sizeHeavySecondSigma,
|
|
1351
|
+
sizeHeavySecondSigma2x: patch.sizeHeavySecondSigma2x ?? base.sizeHeavySecondSigma2x,
|
|
1352
|
+
sizeHeavySecondShare: patch.sizeHeavySecondShare ?? base.sizeHeavySecondShare,
|
|
1353
|
+
sizeScatterScaleGain: patch.sizeScatterScaleGain ?? base.sizeScatterScaleGain,
|
|
1354
|
+
sizeScatterScaleRef: patch.sizeScatterScaleRef ?? base.sizeScatterScaleRef,
|
|
1223
1355
|
sizeOcclusionGain: patch.sizeOcclusionGain ?? base.sizeOcclusionGain,
|
|
1224
1356
|
sizeShadowGainMax: patch.sizeShadowGainMax ?? base.sizeShadowGainMax,
|
|
1225
1357
|
lensRefractionGain: patch.lensRefractionGain ?? base.lensRefractionGain,
|
|
@@ -1256,6 +1388,7 @@ function withMaterialOverrides(base, patch) {
|
|
|
1256
1388
|
backdropToneSizeBias: patch.backdropToneSizeBias ?? base.backdropToneSizeBias,
|
|
1257
1389
|
collapseTransmission: patch.collapseTransmission ?? base.collapseTransmission,
|
|
1258
1390
|
collapseTransmission2x: patch.collapseTransmission2x ?? patch.collapseTransmission ?? base.collapseTransmission2x,
|
|
1391
|
+
bodyChromaRetention: patch.bodyChromaRetention ?? base.bodyChromaRetention,
|
|
1259
1392
|
rimCollapsed: patch.rimCollapsed ?? base.rimCollapsed,
|
|
1260
1393
|
rimCollapsedTinted: patch.rimCollapsedTinted ?? base.rimCollapsedTinted,
|
|
1261
1394
|
rimTintChroma: patch.rimTintChroma ?? base.rimTintChroma,
|
|
@@ -1554,6 +1687,11 @@ function scatterHeavyShareThickAtScale(profile = DEFAULT_MATERIAL_PROFILE, devic
|
|
|
1554
1687
|
function heavyTapSigmaAtScale(profile = DEFAULT_MATERIAL_PROFILE, devicePixelRatio = 1) {
|
|
1555
1688
|
return rampAtScale(profile.sizeHeavyTapSigma, profile.sizeHeavyTapSigma2x, devicePixelRatio);
|
|
1556
1689
|
}
|
|
1690
|
+
function heavySecondTapSigmaAtScale(profile = DEFAULT_MATERIAL_PROFILE, devicePixelRatio = 1) {
|
|
1691
|
+
if (profile.sizeHeavySecondShare === 0)
|
|
1692
|
+
return 0;
|
|
1693
|
+
return rampAtScale(profile.sizeHeavySecondSigma, profile.sizeHeavySecondSigma2x, devicePixelRatio);
|
|
1694
|
+
}
|
|
1557
1695
|
function sizeToneLevelFar(spanPx, profile = DEFAULT_MATERIAL_PROFILE, devicePixelRatio = 1, fold = 1) {
|
|
1558
1696
|
return profile.sizeToneLevelFar * smoothstep(profile.sizeSpanMax, scatterSpanMaxAtScale(profile, devicePixelRatio), spanPx) * fold;
|
|
1559
1697
|
}
|
|
@@ -1695,20 +1833,24 @@ function flatOuterShadow(shadow, amplitude) {
|
|
|
1695
1833
|
var SRGB_ENCODING_EXPONENT = 2.4;
|
|
1696
1834
|
function outerShadowFalloff(signedDistancePx, sigmaPx) {
|
|
1697
1835
|
const x = -signedDistancePx / Math.max(sigmaPx, 1e-4);
|
|
1698
|
-
|
|
1836
|
+
const t = Math.min(20, Math.max(-20, 0.7978845608028654 * (x + 0.044715 * x * x * x)));
|
|
1837
|
+
return 0.5 * (1 + Math.tanh(t));
|
|
1838
|
+
}
|
|
1839
|
+
function outerShadowSigmaPx(shadow, spanPx) {
|
|
1840
|
+
return shadow.sigmaPx + Math.max(shadow.sigmaThinOffsetPx, shadow.sigmaSlopePerSpan * (spanPx - shadow.sigmaSpanRefPx));
|
|
1699
1841
|
}
|
|
1700
1842
|
function outerShadowAlpha(occlusion) {
|
|
1701
1843
|
const occ = Math.min(1, Math.max(0, occlusion));
|
|
1702
1844
|
return 1 - Math.pow(1 - occ, 1 / SRGB_ENCODING_EXPONENT);
|
|
1703
1845
|
}
|
|
1704
|
-
function outerShadowReachPx(shadow, occlusion) {
|
|
1846
|
+
function outerShadowReachPx(shadow, occlusion, spanPx) {
|
|
1705
1847
|
const alpha = outerShadowAlpha(occlusion);
|
|
1706
1848
|
if (!(alpha > 0))
|
|
1707
1849
|
return 0;
|
|
1708
1850
|
const cutoff = 1 / 255 / alpha;
|
|
1709
1851
|
if (cutoff >= 1)
|
|
1710
1852
|
return 0;
|
|
1711
|
-
const sigma = Math.max(shadow
|
|
1853
|
+
const sigma = Math.max(outerShadowSigmaPx(shadow, spanPx), 1e-4);
|
|
1712
1854
|
let lo = -(8 * sigma + Math.abs(shadow.offsetPx) + Math.abs(shadow.spreadPx));
|
|
1713
1855
|
let hi = 8 * sigma;
|
|
1714
1856
|
for (let i = 0; i < 48; i += 1) {
|
|
@@ -2570,6 +2712,10 @@ var poolKey = {
|
|
|
2570
2712
|
/** The heavy blur and its scratch (W26) — the body's pair, one width deeper. */
|
|
2571
2713
|
backdropHeavy: (sourceId) => `backdrop:${sourceId}:heavy`,
|
|
2572
2714
|
backdropHeavyScratch: (sourceId) => `backdrop:${sourceId}:heavy-scratch`,
|
|
2715
|
+
/** The SECOND heavy blur and its scratch (W30 G2) — the same pair, one more
|
|
2716
|
+
* width along, acquired only where `sizeHeavySecondShare` is non-zero. */
|
|
2717
|
+
backdropHeavy2: (sourceId) => `backdrop:${sourceId}:heavy2`,
|
|
2718
|
+
backdropHeavy2Scratch: (sourceId) => `backdrop:${sourceId}:heavy2-scratch`,
|
|
2573
2719
|
backdropUpload: (sourceId) => `backdrop:${sourceId}:upload`,
|
|
2574
2720
|
/*
|
|
2575
2721
|
* The four field targets. Their key is a group's RESOURCE identity — the id
|
|
@@ -3481,9 +3627,26 @@ const TAU = 6.283185307179586;
|
|
|
3481
3627
|
|
|
3482
3628
|
/// Shortest angular distance, so the band wraps continuously past the seam
|
|
3483
3629
|
/// instead of stalling there for one revolution.
|
|
3630
|
+
///
|
|
3631
|
+
/// THE RESULT IS FLOORED AT ZERO, AND THE FLOOR IS THE IDENTITY (W31 G2; claims
|
|
3632
|
+
/// 5.163). A distance is non-negative, and this expression is only non-negative
|
|
3633
|
+
/// while 'raw' stays inside one revolution: past 'TAU' the second branch goes
|
|
3634
|
+
/// negative and 'min' takes it. The single caller squares the quotient through
|
|
3635
|
+
/// 'pow(x, 2.0)', whose base WGSL leaves UNDEFINED below zero \u2014 the same shape
|
|
3636
|
+
/// of defect as 5.159b's 'tanh', one function along. Both arguments are angles
|
|
3637
|
+
/// only while the sweep phase is inside [0, 1], and the phase is read off a CSS
|
|
3638
|
+
/// custom property that nothing clamps (platform-web's 'readHostChannels'
|
|
3639
|
+
/// clamps 'materialization' and not 'sweep'), so '--vitrea-sweep: 3' puts the
|
|
3640
|
+
/// centre at 3 TAU and this function at -12.6 radians. 'max(., 0)' returns the
|
|
3641
|
+
/// same bits at every input the unfloored form was defined at, so no pixel any
|
|
3642
|
+
/// material or any bed reaches moves; what it removes is the undefined one.
|
|
3643
|
+
/// Where the phase IS out of range the band is now centred on the pixel rather
|
|
3644
|
+
/// than NaN, which is a defensible reading of nothing in particular \u2014 wrapping
|
|
3645
|
+
/// the phase where it is read is the fix that would make it mean something, and
|
|
3646
|
+
/// it is outside this gate's contract.
|
|
3484
3647
|
fn angle_delta(a : f32, b : f32) -> f32 {
|
|
3485
3648
|
let raw = abs(a - b);
|
|
3486
|
-
return min(raw, TAU - raw);
|
|
3649
|
+
return max(min(raw, TAU - raw), 0.0);
|
|
3487
3650
|
}
|
|
3488
3651
|
|
|
3489
3652
|
@fragment
|
|
@@ -3736,6 +3899,36 @@ var WGSL_OPTICS_PASS = `struct OpticsUniforms {
|
|
|
3736
3899
|
toneExtra : vec4f,
|
|
3737
3900
|
/// W28: whether the per-surface reference field is present (x).
|
|
3738
3901
|
localTone : vec4f,
|
|
3902
|
+
/// W30's span-graded shadow sigma (claims 5.156 section 2): the law's slope
|
|
3903
|
+
/// in CSS px of sigma per CSS px of casting span (x), the reference span it
|
|
3904
|
+
/// pivots about (y) and the signed floor it is clamped below at, as an offset
|
|
3905
|
+
/// from 'shadow.y' (z). (w) free. At the shipped zeros this evaluates to
|
|
3906
|
+
/// 'shadow.y' at every span, identically, which is why the 34 goldens do not
|
|
3907
|
+
/// move. No device ratio: the cut rejected the device-px reading of the thin
|
|
3908
|
+
/// regime, so the law is one function of CSS span on both tiers.
|
|
3909
|
+
shadowSigma : vec4f,
|
|
3910
|
+
/// W30's scale-selective scatter, candidate (ii) (claims 5.156 section 3): the
|
|
3911
|
+
/// gain on 'kScatter' per unit of the source's measured scale statistic (x),
|
|
3912
|
+
/// the reference that statistic is measured about (y), and the statistic
|
|
3913
|
+
/// itself for THIS group's source (z) \u2014 the analysis pass's edge density,
|
|
3914
|
+
/// resolved on the CPU because it arrives by readback. (w) free.
|
|
3915
|
+
scatterScale : vec4f,
|
|
3916
|
+
/// W30's scale-selective scatter, candidate (i) (claims 5.156 section 3): the
|
|
3917
|
+
/// second heavy sample's SIGNED share in the deep mix (x), and whether this
|
|
3918
|
+
/// group's source carries a second heavy texture at all (y) \u2014 1 where the
|
|
3919
|
+
/// pyramid built one, 0 where the share declined it. A vec4 of its own rather
|
|
3920
|
+
/// than two lanes in the layout above, on 'heavyTap's precedent: a width's
|
|
3921
|
+
/// switch living in another facet's spare lane is a layout nobody could read
|
|
3922
|
+
/// back. (z) and (w) free.
|
|
3923
|
+
scatterHeavy2 : vec4f,
|
|
3924
|
+
/// W31's body chroma retention (claims 5.161 section 5, 5.164): how much of
|
|
3925
|
+
/// the blurred backdrop's CHROMATICITY the body restores, at the luma the
|
|
3926
|
+
/// tone solve produced (x). A vec4 of its own on W30's rule \u2014 132 is the next
|
|
3927
|
+
/// vec4 boundary and an operator packed into the block above would read two
|
|
3928
|
+
/// of its neighbour's lanes. (y), (z) and (w) free. At the shipped 0 the mix
|
|
3929
|
+
/// below is multiplied by zero and the composite is bit-identical to the one
|
|
3930
|
+
/// W30 left, which is why the 34 goldens do not move.
|
|
3931
|
+
bodyChroma : vec4f,
|
|
3739
3932
|
};
|
|
3740
3933
|
|
|
3741
3934
|
@group(0) @binding(0) var<uniform> ou : OpticsUniforms;
|
|
@@ -3760,6 +3953,15 @@ var WGSL_OPTICS_PASS = `struct OpticsUniforms {
|
|
|
3760
3953
|
@group(0) @binding(9) var presenceTexture : texture_2d<f32>;
|
|
3761
3954
|
@group(0) @binding(10) var localToneTexture : texture_2d<f32>;
|
|
3762
3955
|
|
|
3956
|
+
/// The SECOND heavy blur (W30 G2) \u2014 the same construction one width along, and
|
|
3957
|
+
/// read only where 'scatterHeavy2.y' says the pyramid built one. A bind group's
|
|
3958
|
+
/// layout is one layout, so the slot exists at every draw and the placeholder
|
|
3959
|
+
/// view stands in it where the material declined the operator; what costs
|
|
3960
|
+
/// nothing at the inert share is the allocation and the two separable passes,
|
|
3961
|
+
/// which is where the price of this mechanism actually is (W26 Decision Log
|
|
3962
|
+
/// 2 (b)).
|
|
3963
|
+
@group(0) @binding(11) var backdropHeavy2 : texture_2d<f32>;
|
|
3964
|
+
|
|
3763
3965
|
/// One encoded sRGB channel from a linear one \u2014 the space the backdrop tone
|
|
3764
3966
|
/// response's anchors live in (W9). Mirrors material.ts's 'linearToSrgbChannel'.
|
|
3765
3967
|
fn srgb_encode(c : f32) -> f32 {
|
|
@@ -3846,9 +4048,47 @@ fn rim_weight(d : f32, width : f32) -> f32 {
|
|
|
3846
4048
|
/// normal CDF \u2014 WGSL has no erf, and this is within 1.8e-4 of it everywhere,
|
|
3847
4049
|
/// which is 0.015 of one 8-bit code at the shipped occlusion. Mirrors
|
|
3848
4050
|
/// material.ts's 'outerShadowFalloff' term for term.
|
|
4051
|
+
///
|
|
4052
|
+
/// THE ARGUMENT IS CLAMPED, AND THE CLAMP IS THE IDENTITY (W30 G3b; claims
|
|
4053
|
+
/// 5.159b, corrected at 5.159b section 10). 'tanh' saturates to exactly 1.0 in
|
|
4054
|
+
/// f32 by |t| = 9.011 and in f64 by |t| = 19.061547465398498 \u2014 measured, not
|
|
4055
|
+
/// 18.2, which the first recording of this comment said and which is the last
|
|
4056
|
+
/// magnitude that still returns 1 - 1e-16. Either way 20 is above both, so
|
|
4057
|
+
/// replacing every |t| > 20 with 20 returns the same bits in both precisions at
|
|
4058
|
+
/// every input the unclamped form evaluates finitely; the bound has 0.94 of
|
|
4059
|
+
/// margin over f64 rather than 1.8, which is what the corrected reading
|
|
4060
|
+
/// changes. What it
|
|
4061
|
+
/// removes is a NaN: a backend that lowers 'tanh' to (exp(2t) - 1)/(exp(2t) + 1)
|
|
4062
|
+
/// \u2014 which Metal's fast-math path does \u2014 overflows f32's 'exp' at 2t > 88.72 and
|
|
4063
|
+
/// hands back Inf/Inf. The cubic makes that threshold reachable at a modest
|
|
4064
|
+
/// distance: t passes 44.36 at x ~ 10.06, so any pixel more than about 10 sigma
|
|
4065
|
+
/// inside the shadow's silhouette returned NaN, and the NaN travelled into the
|
|
4066
|
+
/// composite's alpha through 'shadowAlpha * (1 - coverage)', where a coverage of
|
|
4067
|
+
/// exactly 1 does not stop it (NaN times 0 is NaN). At every sigma the project
|
|
4068
|
+
/// had shipped, 10 sigma was further than any caster is deep and nothing reached
|
|
4069
|
+
/// it; macOS 27's thin regime draws sigma 2.13 at a span-44 caster, where 10
|
|
4070
|
+
/// sigma is 21.4 CSS px and a 44 px capsule's own centre line is 25 CSS px
|
|
4071
|
+
/// inside its silhouette \u2014 which is the strip 5.159 section 6 measured.
|
|
3849
4072
|
fn outer_shadow_falloff(signedDistance : f32, sigma : f32) -> f32 {
|
|
3850
4073
|
let x = -signedDistance / max(sigma, 1e-4);
|
|
3851
|
-
|
|
4074
|
+
let t = clamp(0.7978845608028654 * (x + 0.044715 * x * x * x), -20.0, 20.0);
|
|
4075
|
+
return 0.5 * (1.0 + tanh(t));
|
|
4076
|
+
}
|
|
4077
|
+
|
|
4078
|
+
/// The outer shadow's sigma at a casting span, CSS px (W30 G2; claims 5.156
|
|
4079
|
+
/// section 2). Mirrors material.ts's 'outerShadowSigmaPx' term for term:
|
|
4080
|
+
///
|
|
4081
|
+
/// sigma(span) = shadow.y + max(shadowSigma.z, shadowSigma.x * (span - shadowSigma.y))
|
|
4082
|
+
///
|
|
4083
|
+
/// Read PER PIXEL from the CASTING surface's own span, which the field pass has
|
|
4084
|
+
/// already unioned into the aux target \u2014 the span this shader has been reading
|
|
4085
|
+
/// the thick regime's amplitude from since W14 G1, now read twice. At the
|
|
4086
|
+
/// shipped zeros both arms of the max are zero and this is 'ou.shadow.y'
|
|
4087
|
+
/// exactly, for every span, which makes the law's landing a no-op on every
|
|
4088
|
+
/// existing pixel by construction rather than by measurement.
|
|
4089
|
+
fn outer_shadow_sigma(spanCss : f32) -> f32 {
|
|
4090
|
+
return ou.shadow.y
|
|
4091
|
+
+ max(ou.shadowSigma.z, ou.shadowSigma.x * (spanCss - ou.shadowSigma.y));
|
|
3852
4092
|
}
|
|
3853
4093
|
|
|
3854
4094
|
/// What one pixel's outer shadow is made of: the compositing-space alpha the
|
|
@@ -3971,7 +4211,10 @@ fn outer_shadow(uv : vec2f, upsampled : f32, fieldSize : vec2f) -> ShadowSample
|
|
|
3971
4211
|
// Times the casting surface's presence (W27d): a material that is not there
|
|
3972
4212
|
// occludes nothing. At presence 1 this is the alpha the bed measures.
|
|
3973
4213
|
out.alpha = (1.0 - pow(1.0 - occ, 1.0 / 2.4)) * castMat;
|
|
3974
|
-
out.falloff = outer_shadow_falloff(
|
|
4214
|
+
out.falloff = outer_shadow_falloff(
|
|
4215
|
+
shadowField.x + clampedOffCss - ou.shadow.z,
|
|
4216
|
+
outer_shadow_sigma(shadowAux.z),
|
|
4217
|
+
);
|
|
3975
4218
|
out.castSpanCss = shadowAux.z;
|
|
3976
4219
|
out.castMat = castMat;
|
|
3977
4220
|
return out;
|
|
@@ -4059,6 +4302,54 @@ fn dom_material_output(encodedComposite : vec3f, encodedBackdrop : vec3f, alpha
|
|
|
4059
4302
|
return vec4f(clamp(c - b * (1.0 - a), vec3f(0.0), vec3f(a)), a);
|
|
4060
4303
|
}
|
|
4061
4304
|
|
|
4305
|
+
/// W31 \u2014 the body's chroma retention, at a held linear luma (claims 5.161
|
|
4306
|
+
/// section 5, fitted in 5.164).
|
|
4307
|
+
///
|
|
4308
|
+
/// The body is a neutral plate over the blurred backdrop, so what a
|
|
4309
|
+
/// photograph's hues survive the composite at is '1 - sizedAlpha'. This
|
|
4310
|
+
/// restores the colour's CHROMATICITY toward the blurred backdrop's, carried to
|
|
4311
|
+
/// the colour's OWN linear luma, by the material's retention.
|
|
4312
|
+
///
|
|
4313
|
+
/// **Luma is held by construction rather than by correction.** Both endpoints
|
|
4314
|
+
/// of the mix have linear luma exactly 'Y' \u2014 'colour' by definition and
|
|
4315
|
+
/// 'target' because it is the backdrop scaled to 'Y' \u2014 and linear luma is a
|
|
4316
|
+
/// linear functional, so the mix has luma 'Y' in exact arithmetic. The
|
|
4317
|
+
/// renormalisation afterwards is an f32 rounding guard and nothing else.
|
|
4318
|
+
///
|
|
4319
|
+
/// Gamut by scaling chroma toward the neutral AT that luma, never by clipping
|
|
4320
|
+
/// per channel: a per-channel clamp moves the level, which is the one thing
|
|
4321
|
+
/// this operator may not do.
|
|
4322
|
+
///
|
|
4323
|
+
/// The retention is the identity outside 'Y' in (1e-6, 1], which is a
|
|
4324
|
+
/// finiteness guard rather than a restriction: 'backdrop' and 'adapted' are both
|
|
4325
|
+
/// in [0, 1] and 'presentAlpha' is in [0, 1], so their mix is too. Writing it as
|
|
4326
|
+
/// a branch on the retention as well makes the identity at 0 EXACT \u2014 no
|
|
4327
|
+
/// division, no rounding, the composite left as it arrived.
|
|
4328
|
+
fn gamut_at_luma(c : vec3f, Y : f32) -> vec3f {
|
|
4329
|
+
var t = 1.0;
|
|
4330
|
+
for (var i = 0u; i < 3u; i = i + 1u) {
|
|
4331
|
+
let d = c[i] - Y;
|
|
4332
|
+
if (d > 1e-7) { t = min(t, (1.0 - Y) / d); }
|
|
4333
|
+
else if (d < -1e-7) { t = min(t, -Y / d); }
|
|
4334
|
+
}
|
|
4335
|
+
return mix(vec3f(Y), c, clamp(t, 0.0, 1.0));
|
|
4336
|
+
}
|
|
4337
|
+
|
|
4338
|
+
fn body_chroma_retention(colour : vec3f, backdrop : vec3f, retention : f32) -> vec3f {
|
|
4339
|
+
if (retention <= 0.0) { return colour; }
|
|
4340
|
+
let W = vec3f(0.2126, 0.7152, 0.0722);
|
|
4341
|
+
let Y = dot(colour, W);
|
|
4342
|
+
if (!(Y > 1e-6 && Y <= 1.0)) { return colour; }
|
|
4343
|
+
let Yb = dot(backdrop, W);
|
|
4344
|
+
if (Yb <= 1e-6) { return colour; }
|
|
4345
|
+
// 'toward' and not 'target': WGSL reserves the latter.
|
|
4346
|
+
let toward = backdrop * (Y / Yb);
|
|
4347
|
+
var restored = mix(colour, toward, clamp(retention, 0.0, 1.0));
|
|
4348
|
+
let Yr = dot(restored, W);
|
|
4349
|
+
if (Yr > 1e-6) { restored = restored * (Y / Yr); }
|
|
4350
|
+
return gamut_at_luma(restored, Y);
|
|
4351
|
+
}
|
|
4352
|
+
|
|
4062
4353
|
@fragment
|
|
4063
4354
|
fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
4064
4355
|
// Nominally the field is one texel per device pixel, so the read is an exact
|
|
@@ -4296,7 +4587,24 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4296
4587
|
let rampStart = ou.scatter.y + (ou.shadowSize.z - ou.scatter.y) * sizeThick
|
|
4297
4588
|
+ (ou.shadowThick.w - ou.shadowSize.z) * farS;
|
|
4298
4589
|
let sharpShare = clamp(sDeep + max(rampStart - sDeep, 0.0) * rampT, 0.0, 1.0);
|
|
4299
|
-
let
|
|
4590
|
+
let kScatterSpan = clamp(scatterFloor + ((1.0 - sharpShare) - scatterFloor) * fold, 0.0, 1.0);
|
|
4591
|
+
/*
|
|
4592
|
+
* W30's scale conditioning, candidate (ii) (claims 5.156 section 3): the deep
|
|
4593
|
+
* component's share moves with the BACKDROP's own spatial scale and not only
|
|
4594
|
+
* with the surface's span, which is what a residual that changes sign between
|
|
4595
|
+
* a 4 px pitch and a 16 px one needs. The statistic is the analysis pass's
|
|
4596
|
+
* per-source edge density, a reciprocal length; it arrives by readback, so the
|
|
4597
|
+
* CPU puts it in 'scatterScale.z' and the law is evaluated here.
|
|
4598
|
+
*
|
|
4599
|
+
* At the shipped gain of 0 the added term is a multiplied zero and the clamp
|
|
4600
|
+
* is the identity on a value already clamped to the same interval, so this is
|
|
4601
|
+
* 'kScatterSpan' to the bit.
|
|
4602
|
+
*/
|
|
4603
|
+
let kScatter = clamp(
|
|
4604
|
+
kScatterSpan + ou.scatterScale.x * (ou.scatterScale.z - ou.scatterScale.y),
|
|
4605
|
+
0.0,
|
|
4606
|
+
1.0,
|
|
4607
|
+
);
|
|
4300
4608
|
// The inner shadow's depth and profile: W2's law, byte for byte \u2014 the
|
|
4301
4609
|
// thickness times the size gain (folded through 'sizeK'), clamped to the
|
|
4302
4610
|
// shorter half extent, and a square on it. The lens ran on this until W12 G2;
|
|
@@ -4406,7 +4714,25 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4406
4714
|
// Premultiplied linear in, straight colour out: the material composites over
|
|
4407
4715
|
// whatever is behind it, so a partially transparent backdrop must not darken
|
|
4408
4716
|
// the glass.
|
|
4409
|
-
|
|
4717
|
+
var scatterColour = scatterSample.rgb / max(scatterSample.a, 1e-6);
|
|
4718
|
+
/*
|
|
4719
|
+
* W30's second heavy tap, candidate (i) (claims 5.156 section 3): a second
|
|
4720
|
+
* texture at its own width, mixed into the deep sample by a SIGNED share.
|
|
4721
|
+
* A positive share widens the deep component toward that width; a negative
|
|
4722
|
+
* one subtracts it, which is an unsharp mask on the backdrop and the only
|
|
4723
|
+
* shape on offer that passes the middle pitch LESS than both ends \u2014 a mix of
|
|
4724
|
+
* two positive Gaussians is monotone in frequency and cannot.
|
|
4725
|
+
*
|
|
4726
|
+
* Gated on whether the pyramid built one, which it does only where
|
|
4727
|
+
* 'sizeHeavySecondShare' is non-zero. At the inert share the branch is not
|
|
4728
|
+
* taken, nothing is allocated and nothing is sampled, which is the state the
|
|
4729
|
+
* 34 goldens render.
|
|
4730
|
+
*/
|
|
4731
|
+
if (ou.scatterHeavy2.y > 0.5) {
|
|
4732
|
+
let second = textureSampleLevel(backdropHeavy2, backdropSampler, refractedUv, 0.0);
|
|
4733
|
+
let secondColour = second.rgb / max(second.a, 1e-6);
|
|
4734
|
+
scatterColour = scatterColour + ou.scatterHeavy2.x * (secondColour - scatterColour);
|
|
4735
|
+
}
|
|
4410
4736
|
backdrop = mix(bodySample.rgb / max(bodySample.a, 1e-6), scatterColour, kScatter);
|
|
4411
4737
|
/*
|
|
4412
4738
|
* The body's own half of the presence (W27d): a material at half presence
|
|
@@ -4605,6 +4931,56 @@ fn fs_optics(in : FullscreenOut) -> @location(0) vec4f {
|
|
|
4605
4931
|
*/
|
|
4606
4932
|
let presentAlpha = adaptedAlpha * mat;
|
|
4607
4933
|
var colour = mix(backdrop, adapted, presentAlpha);
|
|
4934
|
+
/*
|
|
4935
|
+
* W31's chroma retention, HERE and not later (claims 5.161 section 5).
|
|
4936
|
+
*
|
|
4937
|
+
* Immediately after the composite, because the composite is where the
|
|
4938
|
+
* chroma is lost \u2014 the plate is neutral and the backdrop's chromaticity
|
|
4939
|
+
* survives it scaled by '1 - presentAlpha'. Before the tint composition
|
|
4940
|
+
* below, so an author's tint still displaces the result per the composition
|
|
4941
|
+
* contract; the tint's shade law reads the untinted material's LUMINANCE,
|
|
4942
|
+
* which this preserves exactly, so 'shade', 'layer' and 'rimTintColour' are
|
|
4943
|
+
* bit-identical whatever the retention holds.
|
|
4944
|
+
*
|
|
4945
|
+
* Before the DOM branch as well, so the secant that solves an unsampled DOM
|
|
4946
|
+
* group's layer alpha solves it from the material the page will actually
|
|
4947
|
+
* show. That branch is NOT luma-transparent \u2014 'dom_material_alpha' clamps per
|
|
4948
|
+
* channel inside a luma computation \u2014 so an unsampled DOM GROUP'S layer alpha
|
|
4949
|
+
* may move with the retention where a sampled composite does not (claims
|
|
4950
|
+
* 5.161 section 11, the second reading carried forward).
|
|
4951
|
+
*
|
|
4952
|
+
* That sentence said "the 'dom' tier", which is a different thing and is the
|
|
4953
|
+
* thing a reader will think of first (W31 G3c review closure; claims 5.164
|
|
4954
|
+
* section 13, finding N7). The 'dom' tier is the CSS tier, the one the
|
|
4955
|
+
* calibration matrix keys under that name, and it does not run this shader at
|
|
4956
|
+
* all; what is meant here is THIS shader's unsampled-material path, where a
|
|
4957
|
+
* group with no sampled backdrop writes a layer for the browser to composite.
|
|
4958
|
+
*
|
|
4959
|
+
* And on that path what the operator restores TOWARD is not the page's
|
|
4960
|
+
* backdrop, because nothing sampled it. 'dom_material_backdrop()' fabricates
|
|
4961
|
+
* one, and it has two modes. Mode 1, which a group with no declared
|
|
4962
|
+
* 'backdropTone' takes, returns 'vec3f(ou.heavyTap.z)' \u2014 a neutral at the
|
|
4963
|
+
* declared reference luminance \u2014 so the mix target is
|
|
4964
|
+
* 'backdrop * (Y / Yb)' = 'vec3f(Y)', the neutral at the colour's own luma.
|
|
4965
|
+
* That reads as a desaturation and is the IDENTITY in effect: on that path
|
|
4966
|
+
* 'adapted' is 'solvedNeutral' and the fabricated backdrop is a grey, so the
|
|
4967
|
+
* composite has no chromaticity for the target to differ from. Measured at
|
|
4968
|
+
* three retentions up to 1: zero bytes moved
|
|
4969
|
+
* ('e2e/gpu/w31-unsampled-dom-chroma.spec.ts').
|
|
4970
|
+
*
|
|
4971
|
+
* Mode 2 hands the DECLARED tone colour, which can be chromatic, and there
|
|
4972
|
+
* the operator runs \u2014 the body takes the hue the page STATED is behind it
|
|
4973
|
+
* rather than the hue that is. That is the residual, recorded in claims 5.164
|
|
4974
|
+
* section 10, and it is a statement about the target rather than about the
|
|
4975
|
+
* amount: the same spec reads the interior's chroma from 0.066 to 0.334 and
|
|
4976
|
+
* finds the gamut clamp binding at the shipped retention already.
|
|
4977
|
+
*
|
|
4978
|
+
* On the unsampled LAYER path ('flags.x <= 0.5' and not 'domMaterial')
|
|
4979
|
+
* 'colour' is overwritten with 'adapted' a few lines below: there is no
|
|
4980
|
+
* backdrop in hand and no chromaticity to restore toward, and the retention is
|
|
4981
|
+
* silently the identity. That is a declared residual, not an oversight.
|
|
4982
|
+
*/
|
|
4983
|
+
colour = body_chroma_retention(colour, backdrop, ou.bodyChroma.x);
|
|
4608
4984
|
/*
|
|
4609
4985
|
* How much of this pixel the SURFACE owns, as the canvas will composite it.
|
|
4610
4986
|
*
|
|
@@ -4978,7 +5354,13 @@ var WGSL_PRELUDE = `// vitrea:wgsl-marker
|
|
|
4978
5354
|
|
|
4979
5355
|
fn srgb_to_linear(c : vec3f) -> vec3f {
|
|
4980
5356
|
let lo = c / 12.92;
|
|
4981
|
-
|
|
5357
|
+
// The floor is the identity at every component the select below KEEPS: it
|
|
5358
|
+
// keeps hi only where c > 0.04045, and there the base is already above 0.0905.
|
|
5359
|
+
// Below zero the base is a pow WGSL leaves undefined, and a clamp in the
|
|
5360
|
+
// source is preferred to a proof of the select's discard (W31 G2 review
|
|
5361
|
+
// closure, claims \xA75.163 \xA78, finding N8). Same shape as linear_to_srgb's own
|
|
5362
|
+
// max, one line down.
|
|
5363
|
+
let hi = pow(max((c + vec3f(0.055)) / 1.055, vec3f(0.0)), vec3f(2.4));
|
|
4982
5364
|
return select(hi, lo, c <= vec3f(0.04045));
|
|
4983
5365
|
}
|
|
4984
5366
|
|
|
@@ -5359,7 +5741,7 @@ function createPassRunner(context) {
|
|
|
5359
5741
|
};
|
|
5360
5742
|
},
|
|
5361
5743
|
opticsPass(encoder, args) {
|
|
5362
|
-
const slot = uniformSlot(`optics:${args.resourceId}`,
|
|
5744
|
+
const slot = uniformSlot(`optics:${args.resourceId}`, 136);
|
|
5363
5745
|
const d = slot.data;
|
|
5364
5746
|
d[0] = args.viewportDevice[0];
|
|
5365
5747
|
d[1] = args.viewportDevice[1];
|
|
@@ -5478,10 +5860,27 @@ function createPassRunner(context) {
|
|
|
5478
5860
|
d[114] = args.backdropToneResponseThick[3] ?? args.backdropToneResponseThick[2];
|
|
5479
5861
|
d[115] = args.backdropToneAnchorX.length === 4 ? 1 : 0;
|
|
5480
5862
|
d[116] = args.localTone === void 0 ? 0 : 1;
|
|
5863
|
+
d[120] = args.outerShadowSigmaLaw[0];
|
|
5864
|
+
d[121] = args.outerShadowSigmaLaw[1];
|
|
5865
|
+
d[122] = args.outerShadowSigmaLaw[2];
|
|
5866
|
+
d[123] = 0;
|
|
5867
|
+
d[124] = args.sizeScatterScaleGain;
|
|
5868
|
+
d[125] = args.sizeScatterScaleRef;
|
|
5869
|
+
d[126] = args.backdropScaleStatistic;
|
|
5870
|
+
d[127] = 0;
|
|
5871
|
+
d[128] = args.sizeHeavySecondShare;
|
|
5872
|
+
d[129] = args.heavySecondEnabled ? 1 : 0;
|
|
5873
|
+
d[130] = 0;
|
|
5874
|
+
d[131] = 0;
|
|
5875
|
+
d[132] = args.bodyChromaRetention;
|
|
5876
|
+
d[133] = 0;
|
|
5877
|
+
d[134] = 0;
|
|
5878
|
+
d[135] = 0;
|
|
5481
5879
|
slot.write();
|
|
5482
5880
|
const chain = args.backdrop?.chain ?? placeholderView;
|
|
5483
5881
|
const body = args.backdrop?.body ?? placeholderView;
|
|
5484
5882
|
const heavy = args.backdrop?.heavy ?? placeholderView;
|
|
5883
|
+
const heavy2 = args.backdrop?.heavy2 ?? placeholderView;
|
|
5485
5884
|
const pipeline = opticsPipeline(args.targetFormat);
|
|
5486
5885
|
const pass = encoder.beginRenderPass({
|
|
5487
5886
|
label: `vitrea:pass:optics:${args.resourceId}`,
|
|
@@ -5505,7 +5904,8 @@ function createPassRunner(context) {
|
|
|
5505
5904
|
{ binding: 7, resource: args.fields.aux2.createView() },
|
|
5506
5905
|
{ binding: 8, resource: heavy },
|
|
5507
5906
|
{ binding: 9, resource: args.fields.presence.createView() },
|
|
5508
|
-
{ binding: 10, resource: args.localTone ?? placeholderView }
|
|
5907
|
+
{ binding: 10, resource: args.localTone ?? placeholderView },
|
|
5908
|
+
{ binding: 11, resource: heavy2 }
|
|
5509
5909
|
]
|
|
5510
5910
|
}));
|
|
5511
5911
|
pass.draw(3);
|
|
@@ -5763,7 +6163,7 @@ var chainUsage = () => GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTU
|
|
|
5763
6163
|
var densityOf = (source, request) => texelsPerCssPx(source.width, source.height, request.placement, request.viewportCss[0], request.viewportCss[1]);
|
|
5764
6164
|
var same = (next, existing) => Math.abs(next - existing) <= 1e-6 * Math.max(1, Math.abs(existing));
|
|
5765
6165
|
var sameHeavySigma = (next, existing) => next > 0 === existing > 0 && same(next, existing);
|
|
5766
|
-
var sameBody = (existing, request) => same(densityOf({ width: existing.sourceWidth, height: existing.sourceHeight }, request), existing.texelsPerCss) && same(request.bodySigmaCss, existing.bodySigmaCss) && sameHeavySigma(request.heavySigmaCss, existing.heavySigmaCss);
|
|
6166
|
+
var sameBody = (existing, request) => same(densityOf({ width: existing.sourceWidth, height: existing.sourceHeight }, request), existing.texelsPerCss) && same(request.bodySigmaCss, existing.bodySigmaCss) && sameHeavySigma(request.heavySigmaCss, existing.heavySigmaCss) && sameHeavySigma(request.heavy2SigmaCss, existing.heavy2SigmaCss);
|
|
5767
6167
|
function createPyramidStore(context) {
|
|
5768
6168
|
const { device, pool, cache } = context;
|
|
5769
6169
|
const resources = /* @__PURE__ */ new Map();
|
|
@@ -5839,10 +6239,13 @@ function createPyramidStore(context) {
|
|
|
5839
6239
|
if (target.heavy !== void 0 && pool.peek(poolKey.backdropHeavy(sourceId)) !== target.heavy) {
|
|
5840
6240
|
return void 0;
|
|
5841
6241
|
}
|
|
6242
|
+
if (target.heavy2 !== void 0 && pool.peek(poolKey.backdropHeavy2(sourceId)) !== target.heavy2) {
|
|
6243
|
+
return void 0;
|
|
6244
|
+
}
|
|
5842
6245
|
return target;
|
|
5843
6246
|
};
|
|
5844
6247
|
const mipView = (texture, level) => texture.createView({ baseMipLevel: level, mipLevelCount: 1, dimension: "2d" });
|
|
5845
|
-
function allocate(sourceId, plan, bodyLevel, sizeEpoch, builtEpoch, bodySigmaTexels, density, bodySigmaCss, heavyLevel, heavySigmaCss) {
|
|
6248
|
+
function allocate(sourceId, plan, bodyLevel, sizeEpoch, builtEpoch, bodySigmaTexels, density, bodySigmaCss, heavyLevel, heavySigmaCss, heavy2Level, heavy2SigmaCss) {
|
|
5846
6249
|
const existing = resources.get(sourceId);
|
|
5847
6250
|
const levelSize = (level) => plan.levels[level] ?? plan.levels[0];
|
|
5848
6251
|
const bodyWidth = levelSize(bodyLevel).width;
|
|
@@ -5875,6 +6278,19 @@ function createPyramidStore(context) {
|
|
|
5875
6278
|
label: `vitrea:pyramid:${sourceId}:heavy`
|
|
5876
6279
|
});
|
|
5877
6280
|
}
|
|
6281
|
+
let heavy2;
|
|
6282
|
+
if (heavy2Level === void 0) {
|
|
6283
|
+
pool.release(poolKey.backdropHeavy2(sourceId));
|
|
6284
|
+
pool.release(poolKey.backdropHeavy2Scratch(sourceId));
|
|
6285
|
+
} else {
|
|
6286
|
+
heavy2 = pool.acquire(poolKey.backdropHeavy2(sourceId), {
|
|
6287
|
+
width: levelSize(heavy2Level).width,
|
|
6288
|
+
height: levelSize(heavy2Level).height,
|
|
6289
|
+
format: WORKING_TEXTURE_FORMAT,
|
|
6290
|
+
usage: chainUsage(),
|
|
6291
|
+
label: `vitrea:pyramid:${sourceId}:heavy2`
|
|
6292
|
+
});
|
|
6293
|
+
}
|
|
5878
6294
|
let stats = existing?.stats;
|
|
5879
6295
|
if (stats === void 0) {
|
|
5880
6296
|
stats = device.createBuffer({
|
|
@@ -5883,7 +6299,7 @@ function createPyramidStore(context) {
|
|
|
5883
6299
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
|
|
5884
6300
|
});
|
|
5885
6301
|
}
|
|
5886
|
-
if (existing === void 0 || existing.chain !== chain || existing.body !== body || existing.heavy !== heavy) {
|
|
6302
|
+
if (existing === void 0 || existing.chain !== chain || existing.body !== body || existing.heavy !== heavy || existing.heavy2 !== heavy2) {
|
|
5887
6303
|
reallocations += 1;
|
|
5888
6304
|
}
|
|
5889
6305
|
const next = {
|
|
@@ -5892,6 +6308,7 @@ function createPyramidStore(context) {
|
|
|
5892
6308
|
chain,
|
|
5893
6309
|
body,
|
|
5894
6310
|
heavy,
|
|
6311
|
+
heavy2,
|
|
5895
6312
|
stats,
|
|
5896
6313
|
sizeEpoch,
|
|
5897
6314
|
builtEpoch,
|
|
@@ -5900,7 +6317,8 @@ function createPyramidStore(context) {
|
|
|
5900
6317
|
sourceWidth: density.sourceWidth,
|
|
5901
6318
|
sourceHeight: density.sourceHeight,
|
|
5902
6319
|
bodySigmaCss,
|
|
5903
|
-
heavySigmaCss
|
|
6320
|
+
heavySigmaCss,
|
|
6321
|
+
heavy2SigmaCss
|
|
5904
6322
|
};
|
|
5905
6323
|
resources.set(sourceId, next);
|
|
5906
6324
|
return next;
|
|
@@ -5984,7 +6402,7 @@ function createPyramidStore(context) {
|
|
|
5984
6402
|
function runSeparableBlur(encoder, sourceId, kind, plan, chain, target, level, residualSigmaTexels) {
|
|
5985
6403
|
const pipeline = chainPipeline("fs_blur");
|
|
5986
6404
|
const size = plan.levels[level] ?? plan.levels[0];
|
|
5987
|
-
const scratchKey = kind === "body" ? poolKey.backdropBodyScratch(sourceId) : poolKey.backdropHeavyScratch(sourceId);
|
|
6405
|
+
const scratchKey = kind === "body" ? poolKey.backdropBodyScratch(sourceId) : kind === "heavy" ? poolKey.backdropHeavyScratch(sourceId) : poolKey.backdropHeavy2Scratch(sourceId);
|
|
5988
6406
|
const scratch = pool.acquire(scratchKey, {
|
|
5989
6407
|
width: size.width,
|
|
5990
6408
|
height: size.height,
|
|
@@ -6112,13 +6530,17 @@ function createPyramidStore(context) {
|
|
|
6112
6530
|
const bodySigmaTexels = request.bodySigmaCss * texelsPerCss * planScale;
|
|
6113
6531
|
const bodyPlan = bodyBlurPlan(bodySigmaTexels, plan);
|
|
6114
6532
|
const heavyPlan = request.heavySigmaCss > 0 ? heavyTapPlan(request.heavySigmaCss * texelsPerCss * planScale, plan) : void 0;
|
|
6115
|
-
const
|
|
6533
|
+
const heavy2Plan = request.heavy2SigmaCss > 0 ? heavyTapPlan(request.heavy2SigmaCss * texelsPerCss * planScale, plan) : void 0;
|
|
6534
|
+
const target = allocate(request.sourceId, plan, bodyPlan.level, frame.sizeEpoch, request.epoch, bodySigmaTexels, { texelsPerCss, sourceWidth: frame.width, sourceHeight: frame.height }, request.bodySigmaCss, heavyPlan?.level, request.heavySigmaCss, heavy2Plan?.level, request.heavy2SigmaCss);
|
|
6116
6535
|
runImport(encoder, request.sourceId, frame, target.chain);
|
|
6117
6536
|
runChain(encoder, request.sourceId, plan, target.chain);
|
|
6118
6537
|
runSeparableBlur(encoder, request.sourceId, "body", plan, target.chain, target.body, bodyPlan.level, bodyPlan.residualSigmaTexels);
|
|
6119
6538
|
if (heavyPlan !== void 0 && target.heavy !== void 0) {
|
|
6120
6539
|
runSeparableBlur(encoder, request.sourceId, "heavy", plan, target.chain, target.heavy, heavyPlan.level, heavyPlan.residualSigmaTexels);
|
|
6121
6540
|
}
|
|
6541
|
+
if (heavy2Plan !== void 0 && target.heavy2 !== void 0) {
|
|
6542
|
+
runSeparableBlur(encoder, request.sourceId, "heavy2", plan, target.chain, target.heavy2, heavy2Plan.level, heavy2Plan.residualSigmaTexels);
|
|
6543
|
+
}
|
|
6122
6544
|
runAnalysis(encoder, request.sourceId, plan, target.chain, target.stats);
|
|
6123
6545
|
provider.markImported();
|
|
6124
6546
|
return { status: "built", resources: target };
|
|
@@ -6615,7 +7037,8 @@ function createWebGPURenderer(options = {}) {
|
|
|
6615
7037
|
const sigmaCss = bodySigmaCssFor(sourceId);
|
|
6616
7038
|
const sameSigma = Math.abs(sigmaCss - existing.bodySigmaCss) <= 1e-6 * Math.max(1, existing.bodySigmaCss);
|
|
6617
7039
|
const sameHeavy = sameHeavySigma(heavySigmaCssFor(sourceId), existing.heavySigmaCss);
|
|
6618
|
-
|
|
7040
|
+
const sameHeavy2 = sameHeavySigma(heavySecondSigmaCssFor(sourceId), existing.heavy2SigmaCss);
|
|
7041
|
+
if (sameDensity && sameSigma && sameHeavy && sameHeavy2)
|
|
6619
7042
|
continue;
|
|
6620
7043
|
requests.push({
|
|
6621
7044
|
sourceId,
|
|
@@ -6641,6 +7064,11 @@ function createWebGPURenderer(options = {}) {
|
|
|
6641
7064
|
return 0;
|
|
6642
7065
|
return heavyTapSigmaAtScale(material, viewport.devicePixelRatio) / Math.max(viewport.devicePixelRatio, 1e-3);
|
|
6643
7066
|
};
|
|
7067
|
+
const heavySecondSigmaCssFor = (sourceId) => {
|
|
7068
|
+
if (bodySigmaCssFor(sourceId) <= 0)
|
|
7069
|
+
return 0;
|
|
7070
|
+
return heavySecondTapSigmaAtScale(material, viewport.devicePixelRatio);
|
|
7071
|
+
};
|
|
6644
7072
|
const groupTintSeed = (input) => input.surfaces.find((surface) => drawsMaterial(surface) && (surface.tint?.strength ?? 0) > 0)?.tint?.color;
|
|
6645
7073
|
const stateOf = (input, resolution) => {
|
|
6646
7074
|
const resolved = resolution?.groups.find((group) => group.groupId === input.groupId);
|
|
@@ -6710,6 +7138,10 @@ function createWebGPURenderer(options = {}) {
|
|
|
6710
7138
|
// The heavy blur's own σ, through the same conversion (W26). At 0 the
|
|
6711
7139
|
// pyramid allocates nothing and encodes nothing.
|
|
6712
7140
|
heavySigmaCss: heavySigmaCssFor(request.sourceId),
|
|
7141
|
+
// The second heavy blur's σ (W30 G2). At 0 — the landed material —
|
|
7142
|
+
// the pyramid allocates nothing and encodes nothing, exactly as for
|
|
7143
|
+
// the first one.
|
|
7144
|
+
heavy2SigmaCss: heavySecondSigmaCssFor(request.sourceId),
|
|
6713
7145
|
viewportCss: [viewport.widthCss, viewport.heightCss],
|
|
6714
7146
|
...isUsablePlacement(placement) ? { placement } : {}
|
|
6715
7147
|
}, provider, encoder);
|
|
@@ -6772,10 +7204,12 @@ function createWebGPURenderer(options = {}) {
|
|
|
6772
7204
|
const shadow = outerShadowUnderPolicy(policy, material);
|
|
6773
7205
|
const shadowBackdropLuminance = input.backdropTone === void 0 ? void 0 : input.backdropToneLevel ?? relativeLuminance(input.backdropTone);
|
|
6774
7206
|
let reachOcclusion = outerShadowThinOcclusion(shadowBackdropLuminance, shadow);
|
|
7207
|
+
let reachSpanPx = 0;
|
|
6775
7208
|
for (const surface of surfaces) {
|
|
6776
7209
|
reachOcclusion = Math.max(reachOcclusion, outerShadowOcclusionAt(shadow, shadowBackdropLuminance, surface.spanPx, surface.sizeThickness, material));
|
|
7210
|
+
reachSpanPx = Math.max(reachSpanPx, surface.spanPx);
|
|
6777
7211
|
}
|
|
6778
|
-
const shadowReachPx = outerShadowReachPx(shadow, reachOcclusion);
|
|
7212
|
+
const shadowReachPx = outerShadowReachPx(shadow, reachOcclusion, reachSpanPx);
|
|
6779
7213
|
const snapped = snapRectToDevicePixels(groupFieldRect(surfaces, union, void 0, shadowReachPx), dpr);
|
|
6780
7214
|
const rectDevice = clipFieldRectToCanvas(snapped, dpr, viewportDevice);
|
|
6781
7215
|
if (rectDevice === void 0) {
|
|
@@ -6955,6 +7389,53 @@ function createWebGPURenderer(options = {}) {
|
|
|
6955
7389
|
// itself is already in the texture, so this pass only chooses which of
|
|
6956
7390
|
// two textures the deep sample comes from.
|
|
6957
7391
|
heavyTapEnabled: pyramid?.heavy !== void 0,
|
|
7392
|
+
/*
|
|
7393
|
+
* W30's two operators (claims §5.156 §2 and §3; §5.158), every word of
|
|
7394
|
+
* them 0 on the landed material.
|
|
7395
|
+
*
|
|
7396
|
+
* The shadow's σ law crosses as three leaves rather than one width,
|
|
7397
|
+
* because the shader reads it per pixel from the casting surface's own
|
|
7398
|
+
* span. The scatter's scale conditioning crosses as the material's gain
|
|
7399
|
+
* and reference plus the SOURCE's own statistic — the analysis pass's
|
|
7400
|
+
* edge density, which arrives by readback and is therefore resolved
|
|
7401
|
+
* here, like `bodyChainLod`. `adapt` is the filtered reading, so the
|
|
7402
|
+
* statistic the shader sees is the one the drivers have settled on
|
|
7403
|
+
* rather than a raw frame's.
|
|
7404
|
+
*
|
|
7405
|
+
* Where nothing has been observed the statistic is the material's own
|
|
7406
|
+
* REFERENCE rather than 0 — the same gate `adaptStrength` takes two
|
|
7407
|
+
* fields above, and for the same reason. The shader evaluates
|
|
7408
|
+
* `gain · (statistic − reference)`, so a reference is the value at which
|
|
7409
|
+
* the operator contributes nothing; passing 0 instead is that identity
|
|
7410
|
+
* only while the reference happens to be 0, and the moment §5.159 fits
|
|
7411
|
+
* one every unobserved frame would evaluate `gain · (0 − ref)` at full
|
|
7412
|
+
* magnitude — a group whose backdrop readback has not landed yet would
|
|
7413
|
+
* draw at the operator's full excursion and then step to its resting
|
|
7414
|
+
* value. The reference says "no evidence", which is what an unobserved
|
|
7415
|
+
* source has (W30 G2 review closure, claims §5.158 §8, finding 3).
|
|
7416
|
+
*/
|
|
7417
|
+
outerShadowSigmaLaw: [
|
|
7418
|
+
shadow.sigmaSlopePerSpan,
|
|
7419
|
+
shadow.sigmaSpanRefPx,
|
|
7420
|
+
shadow.sigmaThinOffsetPx
|
|
7421
|
+
],
|
|
7422
|
+
sizeScatterScaleGain: material.sizeScatterScaleGain,
|
|
7423
|
+
sizeScatterScaleRef: material.sizeScatterScaleRef,
|
|
7424
|
+
backdropScaleStatistic: adapt?.observed === true ? adapt.edgeDensity : material.sizeScatterScaleRef,
|
|
7425
|
+
sizeHeavySecondShare: material.sizeHeavySecondShare,
|
|
7426
|
+
heavySecondEnabled: pyramid?.heavy2 !== void 0,
|
|
7427
|
+
// W31's body chroma retention (claims §5.164): a material constant, per
|
|
7428
|
+
// group, with no source-side half — the chromaticity it restores toward
|
|
7429
|
+
// is the blurred backdrop the optics pass already sampled per pixel.
|
|
7430
|
+
//
|
|
7431
|
+
// Under the accessibility fold it stands down (W31 Decision Log 3 (d);
|
|
7432
|
+
// claims §5.164 §8 (b) and §13): an occlusion lift covers more of the
|
|
7433
|
+
// backdrop, so restoring the nominal fraction of its chromaticity gives
|
|
7434
|
+
// back what the preference asked to have covered — measured at `R` 3.05
|
|
7435
|
+
// and 3.17 against a reference of 1. `bodyChromaRetentionUnderPolicy` is
|
|
7436
|
+
// exactly `material.bodyChromaRetention` where no preference is set,
|
|
7437
|
+
// which is why every standard row is bit-identical across this fold.
|
|
7438
|
+
bodyChromaRetention: bodyChromaRetentionUnderPolicy(material.bodyChromaRetention, policy),
|
|
6958
7439
|
...pyramid === void 0 && input.unsampledMaterial !== void 0 ? { domMaterial: {
|
|
6959
7440
|
...input.unsampledMaterial,
|
|
6960
7441
|
mode: input.backdropTone === void 0 ? 1 : 2
|
|
@@ -7076,7 +7557,8 @@ function createWebGPURenderer(options = {}) {
|
|
|
7076
7557
|
backdrop: pyramid === void 0 || policy.glass === "none" ? void 0 : {
|
|
7077
7558
|
chain: pyramid.chain.createView(),
|
|
7078
7559
|
body: pyramid.body.createView(),
|
|
7079
|
-
heavy: pyramid.heavy?.createView()
|
|
7560
|
+
heavy: pyramid.heavy?.createView(),
|
|
7561
|
+
heavy2: pyramid.heavy2?.createView()
|
|
7080
7562
|
}
|
|
7081
7563
|
});
|
|
7082
7564
|
if (active.highlight !== void 0) {
|
|
@@ -7389,6 +7871,6 @@ function createWebGPURenderer(options = {}) {
|
|
|
7389
7871
|
};
|
|
7390
7872
|
}
|
|
7391
7873
|
|
|
7392
|
-
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 };
|
|
7393
|
-
//# sourceMappingURL=dist-
|
|
7394
|
-
//# sourceMappingURL=dist-
|
|
7874
|
+
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_DIGEST_RULE_VERSION, MATERIAL_IDENTITY_TABLE, 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, heavySecondTapSigmaAtScale, heavyTapSigmaAtScale, highlightModule, importColorMatrix, importModule, importPassSource, isUsablePlacement, lensAmountBasePx, lensDepthPx, lensDirection, lensDisplacementPx, lensExtentPx, lensHeightBasePx, lensMagnitudePx, lensOvalizationAt, lensSizeGain, lensSizeGainFromThickness, linearGradientStops, linearToSrgb, linearToSrgbChannel, materialDigestDroppedLeaves, materialDigestInput, materialLeafAt, occlusionAlphaUnderPolicy, occlusionLiftForPolicy, opticsModule, opticsUnderPolicy, outerShadowAlpha, outerShadowFalloff, outerShadowLiftRise, outerShadowOcclusionAt, outerShadowReachPx, outerShadowSigmaPx, 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 };
|
|
7875
|
+
//# sourceMappingURL=dist-N437MSRG.js.map
|
|
7876
|
+
//# sourceMappingURL=dist-N437MSRG.js.map
|