@vitreajs/vitrea 0.13.0 → 0.15.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-2V7EQHSR.js → dist-PT4PUS4K.js} +343 -33
- package/dist/dist-PT4PUS4K.js.map +1 -0
- package/dist/index.d.ts +314 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/dist-2V7EQHSR.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1812,6 +1812,50 @@ interface MaterialOptics {
|
|
|
1812
1812
|
* not carry this constant renders the W23 material byte for byte.
|
|
1813
1813
|
*/
|
|
1814
1814
|
readonly rimLitExponent: number;
|
|
1815
|
+
/**
|
|
1816
|
+
* **The lit edge's along-side field (W25; claims §5.113, W25 Decision Log 3
|
|
1817
|
+
* (c))** — the slope of the position field the rim's amplitude is graded by
|
|
1818
|
+
* across the surface, riding `sizeThickness`.
|
|
1819
|
+
*
|
|
1820
|
+
* W24 gave the rim a factor of the NORMAL, which is one number on a whole
|
|
1821
|
+
* straight side. W25 G0 read the rim's peak excess by POSITION along each
|
|
1822
|
+
* straight side instead and found it graded on every thick cell of both probe
|
|
1823
|
+
* grids, on flat solid backdrops where a lens has no gradient to refract: the
|
|
1824
|
+
* 1x dark `dark-solid__rrect-md` reads slopes of −0.000192 (top), +0.000192
|
|
1825
|
+
* (bottom), −0.000379 (left) and +0.000379 (right) luma per CSS px, and the
|
|
1826
|
+
* corner-to-corner range 0.0187 / 0.0226 / 0.0345 on `light-solid` /
|
|
1827
|
+
* `dark-solid` / `mid-dark-solid` at span 96 falls to 0.0000 / 0.0016 at spans
|
|
1828
|
+
* 32 and 44 and saturates above 96 — the signature of a term on
|
|
1829
|
+
* `sizeThickness` and not of the lens.
|
|
1830
|
+
*
|
|
1831
|
+
* **The field is the product of the two normalised coordinates, and that is
|
|
1832
|
+
* what the four slopes say.** A field linear in position — `a·x + b·y` — gives
|
|
1833
|
+
* the top and the bottom side the SAME slope in x; the reference's are equal
|
|
1834
|
+
* and opposite. `(x / halfWidth) · (y / halfHeight)` gives exactly the measured
|
|
1835
|
+
* antisymmetry, is +1 at the top-left and bottom-right corners and −1 at the
|
|
1836
|
+
* other two — the same diagonal `rimLitAxis` is symmetric about, which is why
|
|
1837
|
+
* this is the position half of one light and not a second one — and predicts
|
|
1838
|
+
* the two sides' slope ratio as the box's aspect: 160/96 = 1.67 against the
|
|
1839
|
+
* measured 0.000379 / 0.000192 = 1.97, where a metric diagonal would predict
|
|
1840
|
+
* 1.0. Reading the reference's two sides through it gives 0.62 (top) and 0.73
|
|
1841
|
+
* (left) for this constant, which is the agreement a 56 CSS px straight side
|
|
1842
|
+
* on a six-code contrast supports.
|
|
1843
|
+
*
|
|
1844
|
+
* The factor is `1 + rimAlongSideSlope · sizeThickness(span) · field`, applied
|
|
1845
|
+
* beside W24's `lit` factor and outside W23's amplitude bracket. Two
|
|
1846
|
+
* consequences are exact rather than approximate. **The field's mean over every
|
|
1847
|
+
* straight side is zero**, because the product is odd in the coordinate that
|
|
1848
|
+
* runs along the side, so W23's and W24's straight-span amplitudes keep their
|
|
1849
|
+
* fitted meaning and the CSS tier — whose one inset shadow cannot vary around a
|
|
1850
|
+
* contour — is coherent with the GPU tier's side mean without carrying the term
|
|
1851
|
+
* at all. **It is exactly 0 at or below `sizeSpanMin`**, so `rrect-sm` and every
|
|
1852
|
+
* thin control are untouched by construction; the capsule's span of 44 takes
|
|
1853
|
+
* 0.0923 of it, which is the thin end's whole exposure.
|
|
1854
|
+
*
|
|
1855
|
+
* At 0 the factor is exactly 1 everywhere, so a profile that does not carry
|
|
1856
|
+
* this constant renders the W24 material byte for byte.
|
|
1857
|
+
*/
|
|
1858
|
+
readonly rimAlongSideSlope: number;
|
|
1815
1859
|
/** Inner-shadow depth (0..1) and how much of it is applied. */
|
|
1816
1860
|
readonly shadowDepth: number;
|
|
1817
1861
|
readonly shadowAlpha: number;
|
|
@@ -2171,6 +2215,17 @@ interface MaterialProfile {
|
|
|
2171
2215
|
* σ 10 device px against a body σ of 1.25, and the gain sweep has a clear
|
|
2172
2216
|
* minimum at 8 (RMS 0.0164 against 0.0180 at 6 and 0.0191 at 10 on the probe
|
|
2173
2217
|
* bed).
|
|
2218
|
+
*
|
|
2219
|
+
* **INERT on the GPU tier at any material that names a heavy width** (W26;
|
|
2220
|
+
* claims §5.122 §6a). This constant reaches the deep sample only through
|
|
2221
|
+
* `scatterLod`, and where `sizeHeavyTapSigma` is non-zero the optics pass
|
|
2222
|
+
* overwrites that sample with the heavy texture — measured, not argued: fifty
|
|
2223
|
+
* rows byte-identical between `sizeScatterGainFar2x` 9.9 and 4.8 at the landed
|
|
2224
|
+
* width. It is KEPT and not retired because retiring it means deciding what a
|
|
2225
|
+
* profile naming NO heavy width draws, which is a code-removal wave with no
|
|
2226
|
+
* fidelity content (W26 Decision Log 6 (b)); the tracker carries it. The CSS
|
|
2227
|
+
* tier still reads it for the same reason — the collapsed single-`blur()` form
|
|
2228
|
+
* and the sampling-padding projection, where no heavy width applies.
|
|
2174
2229
|
*/
|
|
2175
2230
|
readonly sizeScatterGainMax: number;
|
|
2176
2231
|
/**
|
|
@@ -2290,6 +2345,11 @@ interface MaterialProfile {
|
|
|
2290
2345
|
* **The span top, 256** — the 1x value, unchanged, because a floor of 1
|
|
2291
2346
|
* leaves the deep value nothing to rise to and the top has no work at this
|
|
2292
2347
|
* ratio. Stage 1 swept it against 128 and the bed did not ask for the change.
|
|
2348
|
+
*
|
|
2349
|
+
* **The gain is INERT on the GPU tier at any material that names a heavy
|
|
2350
|
+
* width** (W26; claims §5.122 §6a), for `sizeScatterGainMax`'s reason and with
|
|
2351
|
+
* the same measurement behind it. The floor and the span top above are NOT —
|
|
2352
|
+
* they grade the deep value's SHARE, which the heavy texture does not touch.
|
|
2293
2353
|
*/
|
|
2294
2354
|
readonly sizeScatterGainMax2x: number;
|
|
2295
2355
|
readonly sizeScatterFloor2x: number;
|
|
@@ -2339,6 +2399,19 @@ interface MaterialProfile {
|
|
|
2339
2399
|
* 0.1125 → 0.0993 against native 0.1018 at 9.9, which is the sweep's best on
|
|
2340
2400
|
* its own objective. The confirmation's holdout `rrect-lg` rose 0.9661 →
|
|
2341
2401
|
* 0.9762 with its interior spread 0.0721 against native 0.0810.
|
|
2402
|
+
*
|
|
2403
|
+
* **INERT on the GPU tier at any material that names a heavy width**, and this
|
|
2404
|
+
* is the one of the three whose silence costs something (W26; claims §5.122
|
|
2405
|
+
* §§3, 6a). It is the constant that graded the 2x heavy width with the span,
|
|
2406
|
+
* and the heavy texture is one width per SOURCE, so where a heavy width is
|
|
2407
|
+
* named there is nothing left for it to grade: fifty rows byte-identical
|
|
2408
|
+
* between 9.9 and 4.8 at the landed width. What that gives up is measured on
|
|
2409
|
+
* the instrument of record rather than estimated — the reference wants **1.66
|
|
2410
|
+
* device px more heavy width at span 160 than at span 96 at dpr 2**, 20 % of
|
|
2411
|
+
* the smaller, and W26 lands one number inside 11 % of each instead. That is
|
|
2412
|
+
* W26 Decision Log 2 (f)'s recorded gap, now with a size; the constant is kept
|
|
2413
|
+
* against the profile that names no heavy width and against the wave that
|
|
2414
|
+
* makes the width per surface.
|
|
2342
2415
|
*/
|
|
2343
2416
|
readonly sizeScatterGainFar2x: number;
|
|
2344
2417
|
/**
|
|
@@ -2489,6 +2562,210 @@ interface MaterialProfile {
|
|
|
2489
2562
|
readonly sizeScatterRampStartFar2x: number;
|
|
2490
2563
|
readonly sizeScatterRampReach1xPx: number;
|
|
2491
2564
|
readonly sizeScatterRampReach2xPx: number;
|
|
2565
|
+
/**
|
|
2566
|
+
* **The heavy share's thick end** (W25; claims §5.113, W25 Decision Log 3 (a))
|
|
2567
|
+
* — how much heavier the deep value runs on a thick surface than the span
|
|
2568
|
+
* curve above makes it, riding `sizeThickness` and read once per scale.
|
|
2569
|
+
*
|
|
2570
|
+
* W25 G0 measured the reference's kernel as TWO components and found that what
|
|
2571
|
+
* separates the thick surface from the thin one is neither width: read on the
|
|
2572
|
+
* same cell at 1x the reference's single-Gaussian width is 1.30 device px
|
|
2573
|
+
* against a 16 CSS px checkerboard, 4.75 against 32 and 6.25 against 64, where
|
|
2574
|
+
* one Gaussian returns one number at every pitch. The dot's own two-component
|
|
2575
|
+
* fit on `impulse__rrect-md` reads sharp σ 2.79 and heavy σ 19.52 device px at
|
|
2576
|
+
* 1x and 1.40 / 11.29 at 2x — both components HALVING in device px — with the
|
|
2577
|
+
* heavy SHARE moving 0.47 → 0.69 the other way, and 0.00 on the collapsed
|
|
2578
|
+
* capsule. vitrea's own pair on the landed material reaches 0.69 at 2x and
|
|
2579
|
+
* carries 0.23 at 1x. So the share is the quantity, and this is where the wave
|
|
2580
|
+
* puts it.
|
|
2581
|
+
*
|
|
2582
|
+
* ```
|
|
2583
|
+
* kDeep(span, dpr) = floor(dpr) + (1 − floor(dpr))
|
|
2584
|
+
* · smoothstep(sizeSpanMin, sizeScatterSpanMax(dpr), span)
|
|
2585
|
+
* + heavyShareThick(dpr) · sizeThickness(span) ← this
|
|
2586
|
+
* ```
|
|
2587
|
+
*
|
|
2588
|
+
* **What stays, and why the thin capsule cannot move.** `sizeScatterFloor`,
|
|
2589
|
+
* `sizeScatterSpanMax` and the ramp's start anchors are NOT re-derived: the
|
|
2590
|
+
* W11c curve stays as the law's thin end and this constant is the lift the
|
|
2591
|
+
* thick end takes above it. That is X5 discharged by the form rather than by a
|
|
2592
|
+
* capture — `sizeThickness` is exactly 0 at and below `sizeSpanMin`, so
|
|
2593
|
+
* `rrect-sm` and every smaller control are bit-identical whatever this says,
|
|
2594
|
+
* and the capsule at span 44 takes 0.0923 of it, which is the whole of the
|
|
2595
|
+
* thin end's exposure and is what the ladder's thin-invariance rung reads. The
|
|
2596
|
+
* alternative — re-expressing the whole curve on a thin/thick anchor pair —
|
|
2597
|
+
* would have made the capsule's own share a fitted quantity of this wave, and
|
|
2598
|
+
* the reference does not ask for that: its sharp σ is 2.62 device px on the
|
|
2599
|
+
* collapsed capsule against 2.79 on the thick rrect, span-flat to 6 %.
|
|
2600
|
+
*
|
|
2601
|
+
* **Inert at 0**, which is what ships until G3 declares the fit: the term is
|
|
2602
|
+
* one multiplication by zero added to the curve W11c fitted, so the resolved
|
|
2603
|
+
* material and every golden are byte-identical to the W24 bed.
|
|
2604
|
+
*
|
|
2605
|
+
* At dpr 2 the 2x anchor is additionally inert on the landed material for a
|
|
2606
|
+
* second reason: `sizeScatterFloor2x` is 1, so `kDeep` is already 1 at every
|
|
2607
|
+
* span and the clamp absorbs any lift. The 2x share is therefore not a
|
|
2608
|
+
* quantity this bed can carry, and it waits for G1's 2x probe fixtures.
|
|
2609
|
+
*/
|
|
2610
|
+
readonly sizeScatterHeavyShareThick1x: number;
|
|
2611
|
+
readonly sizeScatterHeavyShareThick2x: number;
|
|
2612
|
+
/**
|
|
2613
|
+
* **The body's level above the thickness knee** (W25; claims §5.113, W25
|
|
2614
|
+
* Decision Log 3 (b)) — an OFFSET on the interior level a surface settles at,
|
|
2615
|
+
* in the tone response's own encoded units, reached at `sizeScatterSpanMax`.
|
|
2616
|
+
*
|
|
2617
|
+
* W25 G0 answered clause 4 in the landed law's favour and found one residual
|
|
2618
|
+
* it cannot carry. `sizeThickness(short side)` at knee 96 scores r 0.95–0.998
|
|
2619
|
+
* against 0.68–0.96 for the long side, the area, √area and the radius, on the
|
|
2620
|
+
* width and on the level, in both probe grids and both schemes — so the
|
|
2621
|
+
* argument and the knee stay. But the reference's body LEVEL keeps grading
|
|
2622
|
+
* above 96: on the W9 light grid over `checkerboard` it reads 0.61484 /
|
|
2623
|
+
* 0.61299 / 0.67915 / 0.69083 / 0.70458 across spans 32 / 44 / 96 / 128 / 160,
|
|
2624
|
+
* where `sizeThickness` has been flat since 96. The width does not grade there
|
|
2625
|
+
* on any pitch; only the level does.
|
|
2626
|
+
*
|
|
2627
|
+
* ```
|
|
2628
|
+
* R(x, span, dpr) = R₀(x, sizeK)
|
|
2629
|
+
* + sizeToneLevelFar · smoothstep(sizeSpanMax,
|
|
2630
|
+
* sizeScatterSpanMax(dpr), span)
|
|
2631
|
+
* ```
|
|
2632
|
+
*
|
|
2633
|
+
* **Where it enters.** On the tone response's OUTPUT — the settled interior
|
|
2634
|
+
* level `backdropToneResponse` returns, which is the law that owns the
|
|
2635
|
+
* interior mean (claims §5.33) — and not in the blur, not on a gain on the
|
|
2636
|
+
* mix, and not (this is the correction) on the response's own thin-to-thick
|
|
2637
|
+
* blend.
|
|
2638
|
+
*
|
|
2639
|
+
* **Why not on the blend, which is what the wave chartered.** G0's reading
|
|
2640
|
+
* that the residual's "sign follows the backdrop" is a reading of the
|
|
2641
|
+
* REFERENCE's absolute grading, and the quantity a term has to close is the
|
|
2642
|
+
* residual AGAINST vitrea, whose own deep value keeps rising to
|
|
2643
|
+
* `sizeScatterSpanMax` over the same spans. G2's ladder measured both shapes
|
|
2644
|
+
* on the same rows (`fit-level.txt`): carrying the blend past the thick row
|
|
2645
|
+
* explains 0.3 % of the above-knee residual and its per-row gains run
|
|
2646
|
+
* −1.13 … +0.24 with the two grids disagreeing in sign, because the blend's
|
|
2647
|
+
* direction is different at every backdrop level and the residual's is not. An
|
|
2648
|
+
* offset explains 11 % of it and the light grid's rows agree: `resid(160) −
|
|
2649
|
+
* resid(96)` is +2.2 … +4.2 codes over `checkerboard` at four pitches,
|
|
2650
|
+
* `dark-solid`, `mid-dark-solid`, `hc-text` at two pitches and `photo`, over
|
|
2651
|
+
* backdrops spanning 0.012 to 0.89 linear. Backdrop-independent is what the
|
|
2652
|
+
* rows say, so backdrop-independent is the shape.
|
|
2653
|
+
*
|
|
2654
|
+
* The curve is the one the ramp's far anchor declines along and the 2x heavy
|
|
2655
|
+
* gain rises along, so no new span statistic enters the material, and it is
|
|
2656
|
+
* **exactly 0 at and below `sizeSpanMax`** — nothing at or under span 96 moves
|
|
2657
|
+
* at any value of this constant, which is what let G2 probe it against the
|
|
2658
|
+
* frozen bed with 77 control rows reading a lever of 0.000000 codes per unit.
|
|
2659
|
+
*
|
|
2660
|
+
* Folded with `sizeK`, like the response it offsets: under reduced
|
|
2661
|
+
* transparency the material has stopped transmitting and the level it settles
|
|
2662
|
+
* at is the preference's, not the size law's.
|
|
2663
|
+
*
|
|
2664
|
+
* **Inert at 0**, which is what ships until G3 declares the fit. What G2's
|
|
2665
|
+
* ladder read is in `fit-level.txt`; the constant is weakly conditioned on the
|
|
2666
|
+
* bed as it stands and G1's probe set at both scales is what would condition
|
|
2667
|
+
* it (G0 §6: 118 level rows on the 1x grids, 202–238 with the 2x captures).
|
|
2668
|
+
*/
|
|
2669
|
+
readonly sizeToneLevelFar: number;
|
|
2670
|
+
/**
|
|
2671
|
+
* **The heavy blur's width, in device px per scale** (W26; W26 Decision Log 1
|
|
2672
|
+
* and 2, from the measured cause in claims §5.116 §2) — the constant that makes
|
|
2673
|
+
* the deep sample's width a continuous parameter instead of a chain level.
|
|
2674
|
+
*
|
|
2675
|
+
* W25 could not raise the heavy share because vitrea's heavy component is
|
|
2676
|
+
* 13.3 device px at 1x against the reference's 19.5, and raising the share at
|
|
2677
|
+
* the wrong width adds narrow structure the reference does not have. The width
|
|
2678
|
+
* was not a lever: `sizeScatterGainMax` 8 → 10.3 left reader A at 13.29. W26 G0
|
|
2679
|
+
* measured why, and it is arithmetic rather than material
|
|
2680
|
+
* (`results/2026-09-10-w26-heavy-width/g0/tap-today.txt`). The body's deep
|
|
2681
|
+
* sample is
|
|
2682
|
+
*
|
|
2683
|
+
* ```
|
|
2684
|
+
* scatterLod = clamp(bodyChainLod + log2(gain), 0, chainMaxLod)
|
|
2685
|
+
* ```
|
|
2686
|
+
*
|
|
2687
|
+
* `chainMaxLod` is `planPyramid`'s `levelCount − 1`, and the chain stops when
|
|
2688
|
+
* the shorter side would fall below `MIN_LEVEL_EXTENT` = 8. On the bed's
|
|
2689
|
+
* 320 × 200 backdrop raster the chain is five levels, so `chainMaxLod` is **4**
|
|
2690
|
+
* at dpr 1, and `bodyChainLod + log2(8)` is 4.06 — **already past the clamp**.
|
|
2691
|
+
* Every gain at or above 7.5 draws the same level 4, whose own kernel is
|
|
2692
|
+
* 13.4 level-0 texels wide (`CHAIN_LEVEL_SIGMA`) — which is the 13.3 the ledger
|
|
2693
|
+
* recorded. G0 rendered the three impulse rows at gains 8, 10.3, 16 and 32 and
|
|
2694
|
+
* read them identical to the last digit, moving only at gain 4, which asks for
|
|
2695
|
+
* level 3.06 and gets it. So `sizeScatterGainMax`, `sizeScatterGainMax2x` and
|
|
2696
|
+
* `sizeScatterGainFar2x` grade a quantity the clamp then discards, and a
|
|
2697
|
+
* fractional level or a blend of two levels cannot widen anything at dpr 1 —
|
|
2698
|
+
* G0 measured both **inert to the bit** there and removed them again (W26
|
|
2699
|
+
* Decision Log 2 (a); the branch and `results/…/g0/` are their record).
|
|
2700
|
+
*
|
|
2701
|
+
* What widens is a Gaussian, and it is built where the chain is built. The
|
|
2702
|
+
* pyramid takes the chain level whose own blur is nearest below this σ and runs
|
|
2703
|
+
* the two separable passes it already runs for the body until the total is this
|
|
2704
|
+
* σ exactly (`heavyTapPlan`, `PyramidResources.heavy`), so the width is
|
|
2705
|
+
* continuous and is bounded by nothing the chain's depth decides — the residual
|
|
2706
|
+
* carries whatever octave the chain lacks. The optics pass then reads that
|
|
2707
|
+
* texture in place of the chain tap.
|
|
2708
|
+
*
|
|
2709
|
+
* **Per scale**, resolved by `rampAtScale` on the pattern `sizeScatterGainMax2x`
|
|
2710
|
+
* established, because the reference's heavy component is a device-px quantity
|
|
2711
|
+
* that does not simply halve between the scales (19.52 at 1x, 11.29 at 2x;
|
|
2712
|
+
* claims §5.113 §2) — so a profile naming only the 1x end drags the 2x end
|
|
2713
|
+
* toward the 2x constant's own default, and a document that means both names
|
|
2714
|
+
* both.
|
|
2715
|
+
*
|
|
2716
|
+
* **At 0 the mechanism does not exist**: no texture is allocated, no pass is
|
|
2717
|
+
* encoded, and the optics pass takes the single `textureSampleLevel` of the
|
|
2718
|
+
* chain the material has always taken. That is what makes the landed 0.14.0
|
|
2719
|
+
* goldens byte-identical.
|
|
2720
|
+
*
|
|
2721
|
+
* **What it costs, and what it gives up.** One texture and two passes per
|
|
2722
|
+
* source per frame — 0.070 ms on the mobile bench row, against +1.1 ms for the
|
|
2723
|
+
* in-shader grid G0 measured (W26 Decision Log 2 (b)). The width is then one
|
|
2724
|
+
* per SOURCE rather than one per pixel, so the span grading `sizeScatterGainFar2x`
|
|
2725
|
+
* carried does not reach the deep sample where this is on. The reference's heavy
|
|
2726
|
+
* width does not grade with the span at 1x (claims §5.113 §4), which is what
|
|
2727
|
+
* says the material can afford that; at 2x it does (the `-lg` row reads 16.92
|
|
2728
|
+
* against `-md`'s 11.29), and that is a recorded gap rather than an answered
|
|
2729
|
+
* one (W26 Decision Log 2 (f)).
|
|
2730
|
+
*
|
|
2731
|
+
* ---
|
|
2732
|
+
*
|
|
2733
|
+
* **WHAT WAS THEN MEASURED, and it moved the target as well as the width**
|
|
2734
|
+
* (W26 G1b and G1c; claims §5.121 and §5.122; W26 Decision Log 5 and 6 (a)).
|
|
2735
|
+
* The readings quoted above — 19.52 at 1x, 11.29 and 16.92 at 2x — are
|
|
2736
|
+
* two-Gaussian fits to ONE backdrop each, and the same reference reads 8.4
|
|
2737
|
+
* through `checkerboard-64` where it reads 19.5 through the impulse tile. They
|
|
2738
|
+
* stand as recorded, with these beside them.
|
|
2739
|
+
*
|
|
2740
|
+
* The instrument of record is the family reader: the composite this renderer
|
|
2741
|
+
* actually computes, fitted to the pixels jointly across every thick untinted
|
|
2742
|
+
* backdrop of one surface, with a per-backdrop gain. It is the only reader in
|
|
2743
|
+
* this wave that was held against a control — it returns vitrea's OWN drawn
|
|
2744
|
+
* width to 0.6 % — and on it **Apple's heavy width is 8.6–9.2 device px at
|
|
2745
|
+
* dpr 1 and 8.7–9.6 at dpr 2**, on both surfaces and in both schemes, with the
|
|
2746
|
+
* share already right to 0.07. So the 13.418 the clamped tap drew at dpr 1 was
|
|
2747
|
+
* half again too wide, and the reason two waves could not raise the share is
|
|
2748
|
+
* that more of a too-wide heavy component is more of the wrong thing.
|
|
2749
|
+
*
|
|
2750
|
+
* **The landed 9 and 9**, fitted through a ladder the reader sees one for one
|
|
2751
|
+
* (slope 0.995–1.111, rms 0.03–0.06 device px over seven rungs from 8 to
|
|
2752
|
+
* 13.418), inverted per cell: 9.48 / 8.63 / 9.19 at dpr 1 and 8.13 / 9.79 /
|
|
2753
|
+
* 8.37 at dpr 2. At dpr 1 the spread is 9.8 % and one number serves both spans;
|
|
2754
|
+
* at dpr 2 it is 20.4 % and one number does not, which is the span grading of
|
|
2755
|
+
* the paragraph above, now measured at 1.66 device px.
|
|
2756
|
+
*
|
|
2757
|
+
* **The mechanism has no small values** (W26 Decision Log 6 (c)). The paragraph
|
|
2758
|
+
* above says the mechanism does not exist at 0; the counterpart is that it does
|
|
2759
|
+
* exist at 0.001, where `heavyTapPlan` selects chain level 0 with a residual of
|
|
2760
|
+
* a thousandth of a texel and the deep sample becomes the UNBLURRED backdrop.
|
|
2761
|
+
* A near-zero σ is therefore the opposite of "almost off" — it is the widest
|
|
2762
|
+
* possible departure from the material — and a profile must name 0 or a real
|
|
2763
|
+
* width and nothing between. The domain is 0 or at least the chain's level-1
|
|
2764
|
+
* width; a floor in `heavyTapPlan` would make it continuous, and the tracker
|
|
2765
|
+
* carries it.
|
|
2766
|
+
*/
|
|
2767
|
+
readonly sizeHeavyTapSigma: number;
|
|
2768
|
+
readonly sizeHeavyTapSigma2x: number;
|
|
2492
2769
|
/**
|
|
2493
2770
|
* The occlusion gain — "a larger size is more opaque. A smaller size is
|
|
2494
2771
|
* clearer" (S284). The fraction of the *remaining* transparency the size law
|
|
@@ -2952,6 +3229,11 @@ interface MaterialProfilePatch {
|
|
|
2952
3229
|
readonly sizeScatterRampStartFar2x?: number;
|
|
2953
3230
|
readonly sizeScatterRampReach1xPx?: number;
|
|
2954
3231
|
readonly sizeScatterRampReach2xPx?: number;
|
|
3232
|
+
readonly sizeScatterHeavyShareThick1x?: number;
|
|
3233
|
+
readonly sizeScatterHeavyShareThick2x?: number;
|
|
3234
|
+
readonly sizeToneLevelFar?: number;
|
|
3235
|
+
readonly sizeHeavyTapSigma?: number;
|
|
3236
|
+
readonly sizeHeavyTapSigma2x?: number;
|
|
2955
3237
|
readonly sizeOcclusionGain?: number;
|
|
2956
3238
|
readonly sizeShadowGainMax?: number;
|
|
2957
3239
|
readonly lensRefractionGain?: number;
|
|
@@ -3736,6 +4018,7 @@ interface RebuildLedger {
|
|
|
3736
4018
|
* import provider frame -> chain mip 0 (premultiplied linear, X5)
|
|
3737
4019
|
* downsample mip n-1 -> chain mip n (13-tap, one pass per level)
|
|
3738
4020
|
* blur x2 chain[bodyLvl] -> body (separable, residual sigma)
|
|
4021
|
+
* blur x2 chain[heavyLvl] -> heavy (separable, residual sigma; W26)
|
|
3739
4022
|
* analysis chain[anaLvl] -> stats buffer (compute, one workgroup)
|
|
3740
4023
|
* ```
|
|
3741
4024
|
*
|
|
@@ -3750,6 +4033,23 @@ interface PyramidResources {
|
|
|
3750
4033
|
readonly plan: PyramidPlan;
|
|
3751
4034
|
readonly chain: GPUTexture;
|
|
3752
4035
|
readonly body: GPUTexture;
|
|
4036
|
+
/**
|
|
4037
|
+
* The **heavy** blur (W26; `MaterialProfile.sizeHeavyTapSigma`) — one more
|
|
4038
|
+
* texture beside the body, built by the same two separable passes from
|
|
4039
|
+
* whichever chain level `heavyTapPlan` names, and `undefined` where the
|
|
4040
|
+
* profile asked for no width.
|
|
4041
|
+
*
|
|
4042
|
+
* It is here rather than in the optics pass because the optics pass is a
|
|
4043
|
+
* fragment shader over the glass's own area: W26 G0 measured a 9 × 9 in-shader
|
|
4044
|
+
* grid at +1.1 ms on the mobile bench row against 0.070 ms for the two
|
|
4045
|
+
* separable passes the chain already runs (W26 Decision Log 2 (b)). The price
|
|
4046
|
+
* of building it here is that the width is **one per source** rather than one
|
|
4047
|
+
* per pixel — every group sampling this source gets the same heavy width,
|
|
4048
|
+
* because the texture is built before any group is drawn. The reference's heavy
|
|
4049
|
+
* width does not grade with the span at 1x (claims §5.113 §4), which is what
|
|
4050
|
+
* says the material can afford that.
|
|
4051
|
+
*/
|
|
4052
|
+
readonly heavy: GPUTexture | undefined;
|
|
3753
4053
|
readonly stats: GPUBuffer;
|
|
3754
4054
|
/** Source size epoch this allocation was made for. */
|
|
3755
4055
|
readonly sizeEpoch: number;
|
|
@@ -3787,6 +4087,14 @@ interface PyramidResources {
|
|
|
3787
4087
|
* chain's body and `bodyChainLod` belong to the previous scale.
|
|
3788
4088
|
*/
|
|
3789
4089
|
readonly bodySigmaCss: number;
|
|
4090
|
+
/**
|
|
4091
|
+
* The heavy blur's σ in **CSS px** the build converted with, for `sameBody`'s
|
|
4092
|
+
* reason and by the same rule: the heavy width is a device-px quantity
|
|
4093
|
+
* (claims §5.113 §2), so `sizeHeavyTapSigma / dpr` is what reaches the source's
|
|
4094
|
+
* texels, and a window dragged between displays asks for a different heavy
|
|
4095
|
+
* texture from the same clean source.
|
|
4096
|
+
*/
|
|
4097
|
+
readonly heavySigmaCss: number;
|
|
3790
4098
|
}
|
|
3791
4099
|
interface PyramidInstrumentation {
|
|
3792
4100
|
/** Successful rebuilds since the store was created. */
|
|
@@ -3816,6 +4124,12 @@ interface PyramidBuildRequest {
|
|
|
3816
4124
|
* The build resolves it once the frame's real extent is known.
|
|
3817
4125
|
*/
|
|
3818
4126
|
readonly bodySigmaCss: number;
|
|
4127
|
+
/**
|
|
4128
|
+
* The heavy blur's σ in **CSS px** (W26), 0 where the profile declines the
|
|
4129
|
+
* width — at which point nothing is allocated and nothing is drawn, so a
|
|
4130
|
+
* material that names no heavy width pays for none of this.
|
|
4131
|
+
*/
|
|
4132
|
+
readonly heavySigmaCss: number;
|
|
3819
4133
|
readonly viewportCss: readonly [number, number];
|
|
3820
4134
|
/**
|
|
3821
4135
|
* Where the source sits on the plane, in CSS px relative to the viewport, if
|
package/dist/index.js
CHANGED
|
@@ -1092,7 +1092,7 @@ function isHealthy(state) {
|
|
|
1092
1092
|
|
|
1093
1093
|
// src/renderer-seam.ts
|
|
1094
1094
|
async function loadWebGPURendererModule() {
|
|
1095
|
-
return import('./dist-
|
|
1095
|
+
return import('./dist-PT4PUS4K.js');
|
|
1096
1096
|
}
|
|
1097
1097
|
async function loadWebGPURenderer() {
|
|
1098
1098
|
const { createWebGPURenderer } = await loadWebGPURendererModule();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitreajs/vitrea",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Framework-agnostic Liquid Glass material runtime: scene model, capability resolution, material policy, accessibility policy.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/SSFSKIM/designer",
|