framefields 2.13.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/dist/audio/index.d.mts +5 -5
- package/dist/audio/index.mjs +10 -10
- package/dist/{audio-CHV33Od9.d.mts → audio-CdCuGK5d.d.mts} +3 -3
- package/dist/{audio-CHV33Od9.d.mts.map → audio-CdCuGK5d.d.mts.map} +1 -1
- package/dist/{audio-DHzLQ_RG.mjs → audio-DFwRbID_.mjs} +3 -3
- package/dist/{audio-DHzLQ_RG.mjs.map → audio-DFwRbID_.mjs.map} +1 -1
- package/dist/cli/check-worker.mjs +43 -43
- package/dist/cloud/index.d.mts.map +1 -1
- package/dist/components/index.d.mts +13 -13
- package/dist/components/index.mjs +42 -42
- package/dist/{dist-D3BeAZ7X.mjs → dist--Uu5bQ_6.mjs} +870 -348
- package/dist/dist--Uu5bQ_6.mjs.map +1 -0
- package/dist/{dist-CUNvNDS3.mjs → dist-B8Nby2CU.mjs} +18 -4
- package/dist/dist-B8Nby2CU.mjs.map +1 -0
- package/dist/effects/index.d.mts +5 -5
- package/dist/effects/index.mjs +34 -34
- package/dist/{effects-BiDgCK1L.mjs → effects-WMgv8ZaD.mjs} +2 -2
- package/dist/{effects-BiDgCK1L.mjs.map → effects-WMgv8ZaD.mjs.map} +1 -1
- package/dist/fonts/index.mjs +2 -2
- package/dist/{fonts-DeDPWdvJ.mjs → fonts-OW3yAfO5.mjs} +2 -2
- package/dist/{fonts-DeDPWdvJ.mjs.map → fonts-OW3yAfO5.mjs.map} +1 -1
- package/dist/{gpu-CWjgql4C.mjs → gpu-R4T2Tndu.mjs} +2 -2
- package/dist/{gpu-CWjgql4C.mjs.map → gpu-R4T2Tndu.mjs.map} +1 -1
- package/dist/{index-E2IXX0Cz.d.mts → index-9xte4JgL.d.mts} +110 -61
- package/dist/index-9xte4JgL.d.mts.map +1 -0
- package/dist/{index-YB9j9KUx.d.mts → index-B0Vq8Bwf.d.mts} +3 -3
- package/dist/{index-YB9j9KUx.d.mts.map → index-B0Vq8Bwf.d.mts.map} +1 -1
- package/dist/{index-BFTtXosj.d.mts → index-BVd6nXd5.d.mts} +2 -2
- package/dist/index-BVd6nXd5.d.mts.map +1 -0
- package/dist/{index-CnZhBlob.d.mts → index-Bv7gxGK1.d.mts} +2 -2
- package/dist/{index-CnZhBlob.d.mts.map → index-Bv7gxGK1.d.mts.map} +1 -1
- package/dist/{index-a6JrbAK0.d.mts → index-C-V6CAhP.d.mts} +32 -2
- package/dist/index-C-V6CAhP.d.mts.map +1 -0
- package/dist/{index-DQ1U3HC3.d.mts → index-C7-p9zwU.d.mts} +3 -3
- package/dist/{index-DQ1U3HC3.d.mts.map → index-C7-p9zwU.d.mts.map} +1 -1
- package/dist/{index-rtCXNxGO.d.mts → index-CEKxvGY-.d.mts} +2 -2
- package/dist/{index-rtCXNxGO.d.mts.map → index-CEKxvGY-.d.mts.map} +1 -1
- package/dist/{index-X2u96TEo.d.mts → index-CRaydvLi.d.mts} +29 -11
- package/dist/index-CRaydvLi.d.mts.map +1 -0
- package/dist/{index-DBh3WphX.d.mts → index-D1FqV1eu.d.mts} +2 -2
- package/dist/{index-DBh3WphX.d.mts.map → index-D1FqV1eu.d.mts.map} +1 -1
- package/dist/{index-Dibc_xpC.d.mts → index-DoP6EiHj.d.mts} +5 -5
- package/dist/{index-Dibc_xpC.d.mts.map → index-DoP6EiHj.d.mts.map} +1 -1
- package/dist/{index-D68eGFNE.d.mts → index-GA9_Z8Fn.d.mts} +2 -2
- package/dist/{index-D68eGFNE.d.mts.map → index-GA9_Z8Fn.d.mts.map} +1 -1
- package/dist/index.d.mts +14 -14
- package/dist/index.mjs +50 -50
- package/dist/preview/index.d.mts +5 -5
- package/dist/preview/index.mjs +10 -10
- package/dist/{preview-PDz7o2xg.mjs → preview-D7BGmE1E.mjs} +3 -3
- package/dist/{preview-PDz7o2xg.mjs.map → preview-D7BGmE1E.mjs.map} +1 -1
- package/dist/preview-engine/audio.mjs +1 -1
- package/dist/preview-engine/{chunk-IEEV5RB3.mjs → chunk-3C2XT64C.mjs} +1 -1
- package/dist/preview-engine/chunk-52X7SURQ.mjs +494 -0
- package/dist/preview-engine/{chunk-XYCR3STG.mjs → chunk-5DZTPUMH.mjs} +198 -92
- package/dist/preview-engine/{chunk-4P3MMJWD.mjs → chunk-FZ4RD7HV.mjs} +1 -1
- package/dist/preview-engine/chunk-GNDE3OXQ.mjs +5 -0
- package/dist/preview-engine/chunk-OBIJIQCZ.mjs +1 -0
- package/dist/preview-engine/{chunk-SMHEMYCV.mjs → chunk-UBY2UYEL.mjs} +1 -1
- package/dist/preview-engine/{chunk-UFPA36D2.mjs → chunk-UPZURPJY.mjs} +31 -31
- package/dist/preview-engine/components.mjs +1 -1
- package/dist/preview-engine/effects.mjs +1 -1
- package/dist/preview-engine/framefields.mjs +1 -1
- package/dist/preview-engine/player.mjs +1 -1
- package/dist/preview-engine/renderers-DLJOA3BM.mjs +228 -0
- package/dist/preview-engine/signals.mjs +1 -1
- package/dist/{program-Bn6ko_I4.mjs → program-tFKCWU2j.mjs} +109 -12
- package/dist/program-tFKCWU2j.mjs.map +1 -0
- package/dist/renderer/index.d.mts +4 -4
- package/dist/renderer/index.mjs +2 -2
- package/dist/{renderer-BCTUqJG7.mjs → renderer-03mYJLgX.mjs} +3 -3
- package/dist/{renderer-BCTUqJG7.mjs.map → renderer-03mYJLgX.mjs.map} +1 -1
- package/dist/{renderer-CyUiXLRa.mjs → renderer-0rveCDm-.mjs} +3 -3
- package/dist/{renderer-CyUiXLRa.mjs.map → renderer-0rveCDm-.mjs.map} +1 -1
- package/dist/{renderer-BUj7jE6t.mjs → renderer-2PjR3w-q.mjs} +3 -3
- package/dist/{renderer-BUj7jE6t.mjs.map → renderer-2PjR3w-q.mjs.map} +1 -1
- package/dist/{renderer-BqUAyzCZ.mjs → renderer-47y12Z37.mjs} +2 -2
- package/dist/{renderer-BqUAyzCZ.mjs.map → renderer-47y12Z37.mjs.map} +1 -1
- package/dist/renderer-6_bzbbXt.mjs +5 -0
- package/dist/renderer-8M-9G6F_.mjs +5 -0
- package/dist/{renderer-CwlY8Tb-.mjs → renderer-B0yVUOPP.mjs} +2 -2
- package/dist/{renderer-CwlY8Tb-.mjs.map → renderer-B0yVUOPP.mjs.map} +1 -1
- package/dist/renderer-B5OzKvF8.mjs +5 -0
- package/dist/{renderer-CgK7Q1G8.mjs → renderer-B7G1KohJ.mjs} +2 -2
- package/dist/renderer-BBCZ2qbE.mjs +5 -0
- package/dist/{renderer-CuPAQjDK.mjs → renderer-BBMtmxks.mjs} +3 -3
- package/dist/{renderer-CuPAQjDK.mjs.map → renderer-BBMtmxks.mjs.map} +1 -1
- package/dist/renderer-BChbxCux.mjs +5 -0
- package/dist/{renderer-C-GTxnfv.mjs → renderer-BDzn1AKF.mjs} +2 -2
- package/dist/{renderer-C-GTxnfv.mjs.map → renderer-BDzn1AKF.mjs.map} +1 -1
- package/dist/renderer-BGeMPr8C.mjs +5 -0
- package/dist/{renderer-RzkU_O1i.mjs → renderer-BGp0An5A.mjs} +3 -3
- package/dist/{renderer-RzkU_O1i.mjs.map → renderer-BGp0An5A.mjs.map} +1 -1
- package/dist/{renderer-BZgJj8Cl.mjs → renderer-BH7UCMPQ.mjs} +2 -2
- package/dist/{renderer-BZgJj8Cl.mjs.map → renderer-BH7UCMPQ.mjs.map} +1 -1
- package/dist/{renderer-aRk849b3.d.mts → renderer-BHYJlK6H.d.mts} +2 -2
- package/dist/{renderer-aRk849b3.d.mts.map → renderer-BHYJlK6H.d.mts.map} +1 -1
- package/dist/{renderer-Cu3iKMSJ.mjs → renderer-BJ8ea92W.mjs} +3 -3
- package/dist/{renderer-Cu3iKMSJ.mjs.map → renderer-BJ8ea92W.mjs.map} +1 -1
- package/dist/{renderer-Dp5ChuOs.mjs → renderer-BOSZAdgF.mjs} +2 -2
- package/dist/{renderer-Dp5ChuOs.mjs.map → renderer-BOSZAdgF.mjs.map} +1 -1
- package/dist/renderer-BPQ8Pkjb.mjs +5 -0
- package/dist/renderer-BTRpA3HD.mjs +5 -0
- package/dist/{renderer-vll8LX0I.mjs → renderer-BVIXKfbC.mjs} +132 -116
- package/dist/renderer-BVIXKfbC.mjs.map +1 -0
- package/dist/{renderer-DpZballM.mjs → renderer-BVU22lBS.mjs} +2 -2
- package/dist/{renderer-DpZballM.mjs.map → renderer-BVU22lBS.mjs.map} +1 -1
- package/dist/renderer-BVsECSn-.mjs +5 -0
- package/dist/{renderer-DwGlDNOV.mjs → renderer-BWSRryIA.mjs} +2 -2
- package/dist/{renderer-DwGlDNOV.mjs.map → renderer-BWSRryIA.mjs.map} +1 -1
- package/dist/{renderer-BMpmmYOq.mjs → renderer-BacY4nh8.mjs} +2 -2
- package/dist/{renderer-BMpmmYOq.mjs.map → renderer-BacY4nh8.mjs.map} +1 -1
- package/dist/{renderer-CZ5mwBW1.mjs → renderer-Baw6Utxi.mjs} +2 -2
- package/dist/{renderer-CZ5mwBW1.mjs.map → renderer-Baw6Utxi.mjs.map} +1 -1
- package/dist/{renderer-NBMmvqWl.mjs → renderer-Bcu3UrI-.mjs} +3 -3
- package/dist/{renderer-NBMmvqWl.mjs.map → renderer-Bcu3UrI-.mjs.map} +1 -1
- package/dist/{renderer-DxB_OfLs.mjs → renderer-BeNl_6EG.mjs} +2 -2
- package/dist/{renderer-DxB_OfLs.mjs.map → renderer-BeNl_6EG.mjs.map} +1 -1
- package/dist/{renderer-BHPgkoEL.mjs → renderer-BfZNIiSv.mjs} +2 -2
- package/dist/{renderer-BHPgkoEL.mjs.map → renderer-BfZNIiSv.mjs.map} +1 -1
- package/dist/renderer-Bgos68gc.mjs +6 -0
- package/dist/{renderer-CnL8Cmmr.mjs → renderer-BjDddtw9.mjs} +2 -2
- package/dist/renderer-BjHOvoqO.mjs +5 -0
- package/dist/renderer-BjXMPPlV.mjs +5 -0
- package/dist/{renderer-FPiLBwj5.mjs → renderer-BpVOk9ux.mjs} +2 -2
- package/dist/{renderer-FPiLBwj5.mjs.map → renderer-BpVOk9ux.mjs.map} +1 -1
- package/dist/{renderer-DJPZs_zV.mjs → renderer-Bpm145BW.mjs} +3 -3
- package/dist/{renderer-DJPZs_zV.mjs.map → renderer-Bpm145BW.mjs.map} +1 -1
- package/dist/{renderer-45ifiDkn.mjs → renderer-Brmbl12Y.mjs} +3 -3
- package/dist/{renderer-45ifiDkn.mjs.map → renderer-Brmbl12Y.mjs.map} +1 -1
- package/dist/renderer-Byobxqkv.mjs +5 -0
- package/dist/{renderer-DOZPZTxe.mjs → renderer-C20efMI0.mjs} +3 -3
- package/dist/{renderer-DOZPZTxe.mjs.map → renderer-C20efMI0.mjs.map} +1 -1
- package/dist/{renderer-puQhVfDS.mjs → renderer-C5AoaymD.mjs} +3 -3
- package/dist/{renderer-puQhVfDS.mjs.map → renderer-C5AoaymD.mjs.map} +1 -1
- package/dist/{renderer-B-LUGB9h.mjs → renderer-CCxk-RJR.mjs} +2 -2
- package/dist/{renderer-B-LUGB9h.mjs.map → renderer-CCxk-RJR.mjs.map} +1 -1
- package/dist/{renderer-BKi6jDi_.mjs → renderer-CKo7VR8x.mjs} +3 -3
- package/dist/{renderer-BKi6jDi_.mjs.map → renderer-CKo7VR8x.mjs.map} +1 -1
- package/dist/renderer-CKrsg3EG.mjs +5 -0
- package/dist/{renderer--Q0pM9Vh.mjs → renderer-COgwYqev.mjs} +3 -3
- package/dist/{renderer--Q0pM9Vh.mjs.map → renderer-COgwYqev.mjs.map} +1 -1
- package/dist/{renderer-B5b-ehRb.mjs → renderer-CP108ABB.mjs} +2 -2
- package/dist/{renderer-B5b-ehRb.mjs.map → renderer-CP108ABB.mjs.map} +1 -1
- package/dist/{renderer-BPOh9x5X.mjs → renderer-CP8wLzTU.mjs} +2 -2
- package/dist/{renderer-BPOh9x5X.mjs.map → renderer-CP8wLzTU.mjs.map} +1 -1
- package/dist/{renderer-BPiWsrC2.mjs → renderer-CT3zkfbf.mjs} +2 -2
- package/dist/{renderer-BPiWsrC2.mjs.map → renderer-CT3zkfbf.mjs.map} +1 -1
- package/dist/{renderer-CQFMyC_c.mjs → renderer-Ca1KjNCO.mjs} +2 -2
- package/dist/{renderer-CQFMyC_c.mjs.map → renderer-Ca1KjNCO.mjs.map} +1 -1
- package/dist/renderer-Cj875NuH.mjs +5 -0
- package/dist/{renderer-CMnlgAGs.mjs → renderer-Cm0tsbQH.mjs} +2 -2
- package/dist/{renderer-CMnlgAGs.mjs.map → renderer-Cm0tsbQH.mjs.map} +1 -1
- package/dist/renderer-CnmzJoMv.mjs +5 -0
- package/dist/{renderer-BtgqTg2K.mjs → renderer-Cqb7PGrI.mjs} +2 -2
- package/dist/{renderer-C9dqx3U7.mjs → renderer-CrxwW6VQ.mjs} +3 -3
- package/dist/{renderer-C9dqx3U7.mjs.map → renderer-CrxwW6VQ.mjs.map} +1 -1
- package/dist/renderer-CtklDaMg.mjs +5 -0
- package/dist/{renderer-dRXP2dJU.mjs → renderer-Cw6_NL2i.mjs} +3 -3
- package/dist/{renderer-dRXP2dJU.mjs.map → renderer-Cw6_NL2i.mjs.map} +1 -1
- package/dist/{renderer-C_1eqfI0.mjs → renderer-D-KHHWQD.mjs} +3 -3
- package/dist/{renderer-C_1eqfI0.mjs.map → renderer-D-KHHWQD.mjs.map} +1 -1
- package/dist/{renderer-CxSFvKd1.mjs → renderer-D-RhYvVl.mjs} +2 -2
- package/dist/{renderer-CxSFvKd1.mjs.map → renderer-D-RhYvVl.mjs.map} +1 -1
- package/dist/renderer-D1tK3in_.mjs +5 -0
- package/dist/{renderer-Nnu32rqg.mjs → renderer-D2wNFNRf.mjs} +2 -2
- package/dist/{renderer-Nnu32rqg.mjs.map → renderer-D2wNFNRf.mjs.map} +1 -1
- package/dist/renderer-D2yc9P61.mjs +5 -0
- package/dist/renderer-D4v-JvSr.mjs +5 -0
- package/dist/renderer-D7WRWDwB.mjs +5 -0
- package/dist/{renderer-DXFJv_e6.mjs → renderer-DA8YEo_d.mjs} +3 -3
- package/dist/{renderer-DXFJv_e6.mjs.map → renderer-DA8YEo_d.mjs.map} +1 -1
- package/dist/{renderer-CYwVNbUh.mjs → renderer-DEjo6dw_.mjs} +2 -2
- package/dist/{renderer-CYwVNbUh.mjs.map → renderer-DEjo6dw_.mjs.map} +1 -1
- package/dist/renderer-DGvA0tdB.mjs +5 -0
- package/dist/{renderer-Br8km655.mjs → renderer-DIEeHiQA.mjs} +2 -2
- package/dist/{renderer-Br8km655.mjs.map → renderer-DIEeHiQA.mjs.map} +1 -1
- package/dist/{renderer-SJyp9-62.mjs → renderer-DNxWOz8Q.mjs} +2 -2
- package/dist/{renderer-SJyp9-62.mjs.map → renderer-DNxWOz8Q.mjs.map} +1 -1
- package/dist/renderer-DO7v5Sdm.mjs +5 -0
- package/dist/renderer-DRVvt7-V.mjs +5 -0
- package/dist/{renderer-DGb_wgTW.mjs → renderer-DVPgWHZw.mjs} +3 -3
- package/dist/{renderer-DGb_wgTW.mjs.map → renderer-DVPgWHZw.mjs.map} +1 -1
- package/dist/{renderer-BjgFpwVK.mjs → renderer-DWq9gYRw.mjs} +3 -3
- package/dist/{renderer-BjgFpwVK.mjs.map → renderer-DWq9gYRw.mjs.map} +1 -1
- package/dist/renderer-DYMCd3jL.mjs +5 -0
- package/dist/{renderer-C1ctHdXl.mjs → renderer-D_j1WKMD.mjs} +3 -3
- package/dist/{renderer-C1ctHdXl.mjs.map → renderer-D_j1WKMD.mjs.map} +1 -1
- package/dist/{renderer-BsMZ5Iaq.mjs → renderer-DcAKDAnS.mjs} +3 -3
- package/dist/{renderer-BsMZ5Iaq.mjs.map → renderer-DcAKDAnS.mjs.map} +1 -1
- package/dist/{renderer-g9SstkTz.mjs → renderer-Dgj46uEU.mjs} +2 -2
- package/dist/{renderer-DRal7Goa.mjs → renderer-DhyMfG1v.mjs} +3 -3
- package/dist/{renderer-DRal7Goa.mjs.map → renderer-DhyMfG1v.mjs.map} +1 -1
- package/dist/{renderer-BO_wuUKA.mjs → renderer-Dj2H5JPR.mjs} +3 -3
- package/dist/{renderer-BO_wuUKA.mjs.map → renderer-Dj2H5JPR.mjs.map} +1 -1
- package/dist/{renderer-BlZgyBSo.mjs → renderer-DkOuQi84.mjs} +3 -3
- package/dist/{renderer-BlZgyBSo.mjs.map → renderer-DkOuQi84.mjs.map} +1 -1
- package/dist/renderer-DmHKw-MM.mjs +5 -0
- package/dist/renderer-DoDsuZ6G.mjs +5 -0
- package/dist/{renderer-BgjPbgbn.mjs → renderer-Dr0tXA4k.mjs} +3 -3
- package/dist/{renderer-BgjPbgbn.mjs.map → renderer-Dr0tXA4k.mjs.map} +1 -1
- package/dist/{renderer-opVuiAQR.mjs → renderer-DtMVitEF.mjs} +2 -2
- package/dist/{renderer-opVuiAQR.mjs.map → renderer-DtMVitEF.mjs.map} +1 -1
- package/dist/{renderer-D-fzEZfX.mjs → renderer-Dwwnx7Dk.mjs} +2 -2
- package/dist/{renderer-D-fzEZfX.mjs.map → renderer-Dwwnx7Dk.mjs.map} +1 -1
- package/dist/{renderer-dGEMVaZ3.mjs → renderer-DzLrvCB2.mjs} +2 -2
- package/dist/{renderer-dGEMVaZ3.mjs.map → renderer-DzLrvCB2.mjs.map} +1 -1
- package/dist/renderer-EpgclS70.mjs +5 -0
- package/dist/{renderer-549d94qG.mjs → renderer-FYOL5Za6.mjs} +3 -3
- package/dist/{renderer-549d94qG.mjs.map → renderer-FYOL5Za6.mjs.map} +1 -1
- package/dist/renderer-GroKiYyK.mjs +5 -0
- package/dist/{renderer-CciiDHuU.mjs → renderer-I0Hh9cLK.mjs} +3 -3
- package/dist/{renderer-CciiDHuU.mjs.map → renderer-I0Hh9cLK.mjs.map} +1 -1
- package/dist/renderer-MQ5K_xIS.mjs +5 -0
- package/dist/{renderer-C7m7Yxgc.mjs → renderer-NRMlYkX6.mjs} +3 -3
- package/dist/{renderer-C7m7Yxgc.mjs.map → renderer-NRMlYkX6.mjs.map} +1 -1
- package/dist/{renderer-BIieU9pY.mjs → renderer-Nnmi8Gt6.mjs} +3 -3
- package/dist/{renderer-BIieU9pY.mjs.map → renderer-Nnmi8Gt6.mjs.map} +1 -1
- package/dist/renderer-U43SflML.mjs +5 -0
- package/dist/renderer-UqOmBgCv.mjs +5 -0
- package/dist/{renderer-KgsVk9c6.mjs → renderer-W1bVNVR6.mjs} +3 -3
- package/dist/{renderer-KgsVk9c6.mjs.map → renderer-W1bVNVR6.mjs.map} +1 -1
- package/dist/renderer-XLULgJM0.mjs +5 -0
- package/dist/{renderer-CE4535aW.mjs → renderer-ZnrEfkYh.mjs} +2 -2
- package/dist/{renderer-CE4535aW.mjs.map → renderer-ZnrEfkYh.mjs.map} +1 -1
- package/dist/{renderer-RAq3LnNy.mjs → renderer-_pC-jB9O.mjs} +2 -2
- package/dist/{renderer-RAq3LnNy.mjs.map → renderer-_pC-jB9O.mjs.map} +1 -1
- package/dist/{renderer-Dz6P-rPI.mjs → renderer-iMiYStcW.mjs} +2 -2
- package/dist/{renderer-Dz6P-rPI.mjs.map → renderer-iMiYStcW.mjs.map} +1 -1
- package/dist/{renderer-S9tVGneU.mjs → renderer-jUKdkmG5.mjs} +69 -69
- package/dist/{renderer-S9tVGneU.mjs.map → renderer-jUKdkmG5.mjs.map} +1 -1
- package/dist/{renderer-_54hiCq0.mjs → renderer-k5d7JSbs.mjs} +3 -3
- package/dist/{renderer-_54hiCq0.mjs.map → renderer-k5d7JSbs.mjs.map} +1 -1
- package/dist/renderer-lNjxY1GG.mjs +5 -0
- package/dist/{renderer-CL-vyXgX.mjs → renderer-nHS3Sius.mjs} +3 -3
- package/dist/{renderer-CL-vyXgX.mjs.map → renderer-nHS3Sius.mjs.map} +1 -1
- package/dist/{renderer-Cp_HOmp7.mjs → renderer-ngmYIIob.mjs} +3 -3
- package/dist/{renderer-Cp_HOmp7.mjs.map → renderer-ngmYIIob.mjs.map} +1 -1
- package/dist/{renderer-LXhEPCmy.mjs → renderer-raxwsiGI.mjs} +3 -3
- package/dist/{renderer-LXhEPCmy.mjs.map → renderer-raxwsiGI.mjs.map} +1 -1
- package/dist/renderer-ukufL7pl.mjs +5 -0
- package/dist/renderer-wb0NCKdF.mjs +5 -0
- package/dist/{renderer-D8gN7aqk.mjs → renderer-zRq0j6Xy.mjs} +3 -3
- package/dist/{renderer-D8gN7aqk.mjs.map → renderer-zRq0j6Xy.mjs.map} +1 -1
- package/dist/{renderers-CP8CFWDs-BRQyvcut.mjs → renderers-CP8CFWDs-CshljORp.mjs} +2 -2
- package/dist/{renderers-CP8CFWDs-BRQyvcut.mjs.map → renderers-CP8CFWDs-CshljORp.mjs.map} +1 -1
- package/dist/sam/index.d.mts +3 -3
- package/dist/signals/index.d.mts +5 -5
- package/dist/signals/index.mjs +4 -4
- package/dist/{src-BzFGotRc.mjs → src-Dy4gnc6w.mjs} +43 -13
- package/dist/src-Dy4gnc6w.mjs.map +1 -0
- package/package.json +60 -60
- package/dist/dist-CUNvNDS3.mjs.map +0 -1
- package/dist/dist-D3BeAZ7X.mjs.map +0 -1
- package/dist/index-BFTtXosj.d.mts.map +0 -1
- package/dist/index-E2IXX0Cz.d.mts.map +0 -1
- package/dist/index-X2u96TEo.d.mts.map +0 -1
- package/dist/index-a6JrbAK0.d.mts.map +0 -1
- package/dist/preview-engine/chunk-77WWW75O.mjs +0 -5
- package/dist/preview-engine/chunk-7M5LE6EM.mjs +0 -483
- package/dist/preview-engine/chunk-FRJPXWAG.mjs +0 -1
- package/dist/preview-engine/renderers-TTXTV4PC.mjs +0 -228
- package/dist/program-Bn6ko_I4.mjs.map +0 -1
- package/dist/renderer-1aSF5BmY.mjs +0 -5
- package/dist/renderer-B2e4Gr9u.mjs +0 -5
- package/dist/renderer-B6fz4j50.mjs +0 -5
- package/dist/renderer-BEftIYw-.mjs +0 -5
- package/dist/renderer-BHTnO-7e.mjs +0 -5
- package/dist/renderer-BMlnQqTO.mjs +0 -5
- package/dist/renderer-BOzcFezY.mjs +0 -5
- package/dist/renderer-BVbjJIKJ.mjs +0 -5
- package/dist/renderer-BXsHKf4k.mjs +0 -5
- package/dist/renderer-Bks49NVl.mjs +0 -5
- package/dist/renderer-C-t7qFKr.mjs +0 -5
- package/dist/renderer-C24n-6CX.mjs +0 -6
- package/dist/renderer-CCReX-7M.mjs +0 -5
- package/dist/renderer-CIxFQrAm.mjs +0 -5
- package/dist/renderer-CLHBMIqJ.mjs +0 -5
- package/dist/renderer-CMJKi-Ye.mjs +0 -5
- package/dist/renderer-C_H3mHZa.mjs +0 -5
- package/dist/renderer-CfkTdR5B.mjs +0 -5
- package/dist/renderer-CnhkXJ0R.mjs +0 -5
- package/dist/renderer-CqpyVsq_.mjs +0 -5
- package/dist/renderer-CtWgIpTE.mjs +0 -5
- package/dist/renderer-CyuKr5ca.mjs +0 -5
- package/dist/renderer-D9ON_1Hf.mjs +0 -5
- package/dist/renderer-DAnTgh4o.mjs +0 -5
- package/dist/renderer-DWgpivA3.mjs +0 -5
- package/dist/renderer-Dh_qNNwR.mjs +0 -5
- package/dist/renderer-DkCpXPMP.mjs +0 -5
- package/dist/renderer-Dre-6cDR.mjs +0 -5
- package/dist/renderer-Ds5z4_HX.mjs +0 -5
- package/dist/renderer-HGSCOMyP.mjs +0 -5
- package/dist/renderer-KMY8W-cJ.mjs +0 -5
- package/dist/renderer-R21YvXz3.mjs +0 -5
- package/dist/renderer-RtzCz37W.mjs +0 -5
- package/dist/renderer-iMrqAjix.mjs +0 -5
- package/dist/renderer-sMed1u1O.mjs +0 -5
- package/dist/renderer-tsAuo46l.mjs +0 -5
- package/dist/renderer-vll8LX0I.mjs.map +0 -1
- package/dist/src-BzFGotRc.mjs.map +0 -1
|
@@ -1537,15 +1537,15 @@ var SignalRegistry = class {
|
|
|
1537
1537
|
res.lastProcessedFrame = cacheFrame;
|
|
1538
1538
|
res.lastFingerprint = fingerprint;
|
|
1539
1539
|
if (isSamplesArray(rawSamples) && rawSamples.length > 0) {
|
|
1540
|
-
const flat = new Float32Array(numSamples);
|
|
1540
|
+
const flat$1 = new Float32Array(numSamples);
|
|
1541
1541
|
const total = rawSamples.length;
|
|
1542
1542
|
const srcFps = Number(normalizedSd?.fps) || 24;
|
|
1543
1543
|
for (let i = 0; i < numSamples; i++) {
|
|
1544
1544
|
const t = elapsedTime + i / sampleRate;
|
|
1545
1545
|
const sIdx = Math.min(total - 1, Math.max(0, Math.round(t * srcFps)));
|
|
1546
|
-
flat[i] = Number(rawSamples[sIdx]) || 0;
|
|
1546
|
+
flat$1[i] = Number(rawSamples[sIdx]) || 0;
|
|
1547
1547
|
}
|
|
1548
|
-
device.queue.writeBuffer(res.buffer, 0, flat);
|
|
1548
|
+
device.queue.writeBuffer(res.buffer, 0, flat$1);
|
|
1549
1549
|
} else if (normalizedSd?.type === "generator" && (normalizedSd.customWGSL || normalizedSd.fnBody)) {
|
|
1550
1550
|
const signalEncoder = device.createCommandEncoder({ label: `signal_1d_encoder_${nodeId}` });
|
|
1551
1551
|
this.dispatch1DGenerator(device, signalEncoder, res, elapsedTime, duration$2, normalizedSd, numSamples, sampleRate, frame, fps);
|
|
@@ -1560,8 +1560,8 @@ var SignalRegistry = class {
|
|
|
1560
1560
|
device.queue.submit([signalEncoder.finish()]);
|
|
1561
1561
|
} else {
|
|
1562
1562
|
const val = Number(normalizedSd?.offset ?? 0);
|
|
1563
|
-
const flat = new Float32Array(numSamples).fill(val);
|
|
1564
|
-
device.queue.writeBuffer(res.buffer, 0, flat);
|
|
1563
|
+
const flat$1 = new Float32Array(numSamples).fill(val);
|
|
1564
|
+
device.queue.writeBuffer(res.buffer, 0, flat$1);
|
|
1565
1565
|
}
|
|
1566
1566
|
} else if (normalizedSd?.type === "signal_math") {
|
|
1567
1567
|
const sigAId = normalizedSd.signalA?.nodeId ?? `${nodeId}_a`;
|
|
@@ -1582,8 +1582,8 @@ var SignalRegistry = class {
|
|
|
1582
1582
|
device.queue.submit([signalEncoder.finish()]);
|
|
1583
1583
|
} else {
|
|
1584
1584
|
const val = Number(normalizedSd?.offset ?? 0);
|
|
1585
|
-
const flat = new Float32Array(numSamples).fill(val);
|
|
1586
|
-
device.queue.writeBuffer(res.buffer, 0, flat);
|
|
1585
|
+
const flat$1 = new Float32Array(numSamples).fill(val);
|
|
1586
|
+
device.queue.writeBuffer(res.buffer, 0, flat$1);
|
|
1587
1587
|
}
|
|
1588
1588
|
return res.buffer;
|
|
1589
1589
|
}
|
|
@@ -1649,7 +1649,7 @@ var SignalRegistry = class {
|
|
|
1649
1649
|
device.queue.submit([signalEncoder.finish()]);
|
|
1650
1650
|
return res.textureView;
|
|
1651
1651
|
} else if (isSamplesArray(rawSamples) && rawSamples.length > 0) {
|
|
1652
|
-
const flat = new Float32Array(targetWidth * targetHeight * 4);
|
|
1652
|
+
const flat$1 = new Float32Array(targetWidth * targetHeight * 4);
|
|
1653
1653
|
const total = rawSamples.length;
|
|
1654
1654
|
const baseTime = frame !== void 0 && fps !== void 0 && fps > 0 ? frame / fps : elapsedTime;
|
|
1655
1655
|
for (let i = 0; i < targetWidth; i++) {
|
|
@@ -1659,13 +1659,13 @@ var SignalRegistry = class {
|
|
|
1659
1659
|
const val = Number(rawSamples[sIdx]) || 0;
|
|
1660
1660
|
for (let row = 0; row < targetHeight; row++) {
|
|
1661
1661
|
const idx = (row * targetWidth + i) * 4;
|
|
1662
|
-
flat[idx] = val;
|
|
1663
|
-
flat[idx + 1] = val;
|
|
1664
|
-
flat[idx + 2] = val;
|
|
1665
|
-
flat[idx + 3] = val;
|
|
1662
|
+
flat$1[idx] = val;
|
|
1663
|
+
flat$1[idx + 1] = val;
|
|
1664
|
+
flat$1[idx + 2] = val;
|
|
1665
|
+
flat$1[idx + 3] = val;
|
|
1666
1666
|
}
|
|
1667
1667
|
}
|
|
1668
|
-
const halfFlat = encodeFloat32ToFloat16(flat);
|
|
1668
|
+
const halfFlat = encodeFloat32ToFloat16(flat$1);
|
|
1669
1669
|
device.queue.writeTexture({ texture: res.texture }, halfFlat, {
|
|
1670
1670
|
bytesPerRow: targetWidth * 8,
|
|
1671
1671
|
rowsPerImage: targetHeight
|
|
@@ -1691,14 +1691,14 @@ var SignalRegistry = class {
|
|
|
1691
1691
|
device.queue.submit([signalEncoder.finish()]);
|
|
1692
1692
|
} else {
|
|
1693
1693
|
const val = Number(normalizedSd?.offset ?? 0);
|
|
1694
|
-
const flat = new Float32Array(targetWidth * targetHeight * 4);
|
|
1694
|
+
const flat$1 = new Float32Array(targetWidth * targetHeight * 4);
|
|
1695
1695
|
for (let i = 0; i < targetWidth * targetHeight; i++) {
|
|
1696
|
-
flat[i * 4] = val;
|
|
1697
|
-
flat[i * 4 + 1] = val;
|
|
1698
|
-
flat[i * 4 + 2] = val;
|
|
1699
|
-
flat[i * 4 + 3] = 1;
|
|
1696
|
+
flat$1[i * 4] = val;
|
|
1697
|
+
flat$1[i * 4 + 1] = val;
|
|
1698
|
+
flat$1[i * 4 + 2] = val;
|
|
1699
|
+
flat$1[i * 4 + 3] = 1;
|
|
1700
1700
|
}
|
|
1701
|
-
const halfFlat = encodeFloat32ToFloat16(flat);
|
|
1701
|
+
const halfFlat = encodeFloat32ToFloat16(flat$1);
|
|
1702
1702
|
device.queue.writeTexture({ texture: res.texture }, halfFlat, {
|
|
1703
1703
|
bytesPerRow: targetWidth * 8,
|
|
1704
1704
|
rowsPerImage: targetHeight
|
|
@@ -16151,9 +16151,9 @@ var ShaderStore = class {
|
|
|
16151
16151
|
getCacheKey(nodeId, renderId) {
|
|
16152
16152
|
return `${renderId ?? "global"}:${nodeId}`;
|
|
16153
16153
|
}
|
|
16154
|
-
register(nodeId, shader, renderId) {
|
|
16155
|
-
this.store.set(this.getCacheKey(nodeId, renderId), shader);
|
|
16156
|
-
if (renderId) this.store.set(this.getCacheKey(nodeId, void 0), shader);
|
|
16154
|
+
register(nodeId, shader$1, renderId) {
|
|
16155
|
+
this.store.set(this.getCacheKey(nodeId, renderId), shader$1);
|
|
16156
|
+
if (renderId) this.store.set(this.getCacheKey(nodeId, void 0), shader$1);
|
|
16157
16157
|
}
|
|
16158
16158
|
get(nodeId, renderId) {
|
|
16159
16159
|
const res = this.store.get(this.getCacheKey(nodeId, renderId));
|
|
@@ -24530,9 +24530,11 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
24530
24530
|
scale = effect.scale;
|
|
24531
24531
|
if (blurOverride === void 0) blurAmount = effect.blurAmount;
|
|
24532
24532
|
}
|
|
24533
|
+
const isHighlighted = props.highlightWordIndex !== void 0 && glyph.wordIndex === props.highlightWordIndex;
|
|
24534
|
+
const spanColor = glyph.fill ? parseColor(glyph.fill) : void 0;
|
|
24535
|
+
let fillColor = isHighlighted ? highlightColor : spanColor ?? baseColor;
|
|
24533
24536
|
let customScaleX = 1;
|
|
24534
24537
|
let customScaleY = 1;
|
|
24535
|
-
let animatorColor;
|
|
24536
24538
|
let transZ = 0;
|
|
24537
24539
|
let chromaticShift = 0;
|
|
24538
24540
|
let dissolveProgress = 0;
|
|
@@ -24551,7 +24553,7 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
24551
24553
|
scaleY: customScaleY,
|
|
24552
24554
|
opacity,
|
|
24553
24555
|
blurAmount,
|
|
24554
|
-
color:
|
|
24556
|
+
color: fillColor
|
|
24555
24557
|
}, false, props.frame ?? 0, props.fps ?? 24, props.signals);
|
|
24556
24558
|
transX = kResult.transX;
|
|
24557
24559
|
transY = kResult.transY;
|
|
@@ -24561,7 +24563,7 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
24561
24563
|
customScaleY = kResult.scaleY;
|
|
24562
24564
|
opacity = kResult.opacity;
|
|
24563
24565
|
if (blurOverride === void 0) blurAmount = kResult.blurAmount;
|
|
24564
|
-
if (kResult.color)
|
|
24566
|
+
if (kResult.color) fillColor = kResult.color;
|
|
24565
24567
|
if (kResult.lineSpacing !== void 0) transY += computeLineLeadingDisplacement(glyph.lineIndex, layout.linesCount, kResult.lineSpacing, kResult.lineAnchor ?? 0);
|
|
24566
24568
|
transZ = kResult.transZ ?? 0;
|
|
24567
24569
|
chromaticShift = kResult.chromaticShift ?? 0;
|
|
@@ -24579,9 +24581,7 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
24579
24581
|
const contentWidth = layout.glyphs.length > 0 ? layout.glyphs[layout.glyphs.length - 1].x + fontSize : props.dstRect.width;
|
|
24580
24582
|
glyphX = evaluateMarqueeOffset(glyph.x, props.dstRect.width, contentWidth, props.marquee, elapsedSec);
|
|
24581
24583
|
}
|
|
24582
|
-
const
|
|
24583
|
-
const spanColor = glyph.fill ? parseColor(glyph.fill) : void 0;
|
|
24584
|
-
const col = animatorColor ?? colorOverride ?? (isHighlighted ? highlightColor : spanColor ?? baseColor);
|
|
24584
|
+
const col = colorOverride ?? fillColor;
|
|
24585
24585
|
const writeInstance = (boldShift) => {
|
|
24586
24586
|
const offset = visibleCount * 24;
|
|
24587
24587
|
const fontScale = glyph.fontScale ?? fontSize / targetFont.unitsPerEm;
|
|
@@ -27990,6 +27990,118 @@ var ClipStack = class {
|
|
|
27990
27990
|
}
|
|
27991
27991
|
};
|
|
27992
27992
|
/**
|
|
27993
|
+
* Filling compound paths: every subpath is a contour, contours nest, and a
|
|
27994
|
+
* region is filled by SVG's nonzero rule (the windings of the contours
|
|
27995
|
+
* around it, summed, are not zero). Each filled contour is triangulated with
|
|
27996
|
+
* its direct children as holes, so a map's coastlines and islands, a
|
|
27997
|
+
* letter's counter or a ring fill as drawn instead of being bridged into
|
|
27998
|
+
* one polygon.
|
|
27999
|
+
*
|
|
28000
|
+
* Contours are taken not to cross each other (each pair is nested or
|
|
28001
|
+
* apart), which holds for maps, glyphs and icons; a contour that crosses
|
|
28002
|
+
* itself is still triangulated as well as earcut can.
|
|
28003
|
+
*/
|
|
28004
|
+
function signedArea(points) {
|
|
28005
|
+
let area = 0;
|
|
28006
|
+
for (let i = 0; i < points.length; i++) {
|
|
28007
|
+
const a = points[i];
|
|
28008
|
+
const b = points[(i + 1) % points.length];
|
|
28009
|
+
area += a.x * b.y - b.x * a.y;
|
|
28010
|
+
}
|
|
28011
|
+
return area / 2;
|
|
28012
|
+
}
|
|
28013
|
+
function flat(points) {
|
|
28014
|
+
const out = [];
|
|
28015
|
+
for (const p of points) out.push(p.x, p.y);
|
|
28016
|
+
return out;
|
|
28017
|
+
}
|
|
28018
|
+
function boxOf(points) {
|
|
28019
|
+
const box = {
|
|
28020
|
+
x0: Infinity,
|
|
28021
|
+
y0: Infinity,
|
|
28022
|
+
x1: -Infinity,
|
|
28023
|
+
y1: -Infinity
|
|
28024
|
+
};
|
|
28025
|
+
for (const p of points) {
|
|
28026
|
+
box.x0 = Math.min(box.x0, p.x);
|
|
28027
|
+
box.y0 = Math.min(box.y0, p.y);
|
|
28028
|
+
box.x1 = Math.max(box.x1, p.x);
|
|
28029
|
+
box.y1 = Math.max(box.y1, p.y);
|
|
28030
|
+
}
|
|
28031
|
+
return box;
|
|
28032
|
+
}
|
|
28033
|
+
/** The centroid of the contour's largest triangle: inside it, away from its edges. */
|
|
28034
|
+
function insidePoint(points) {
|
|
28035
|
+
const coords = flat(points);
|
|
28036
|
+
const tris = earcut(coords);
|
|
28037
|
+
const at = (k) => ({
|
|
28038
|
+
x: coords[k * 2],
|
|
28039
|
+
y: coords[k * 2 + 1]
|
|
28040
|
+
});
|
|
28041
|
+
let best = -1;
|
|
28042
|
+
let inside = points[0];
|
|
28043
|
+
for (let i = 0; i < tris.length; i += 3) {
|
|
28044
|
+
const a = at(tris[i]);
|
|
28045
|
+
const b = at(tris[i + 1]);
|
|
28046
|
+
const c = at(tris[i + 2]);
|
|
28047
|
+
const size = Math.abs((b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y));
|
|
28048
|
+
if (size > best) {
|
|
28049
|
+
best = size;
|
|
28050
|
+
inside = {
|
|
28051
|
+
x: (a.x + b.x + c.x) / 3,
|
|
28052
|
+
y: (a.y + b.y + c.y) / 3
|
|
28053
|
+
};
|
|
28054
|
+
}
|
|
28055
|
+
}
|
|
28056
|
+
return inside;
|
|
28057
|
+
}
|
|
28058
|
+
function contains(points, p) {
|
|
28059
|
+
let inside = false;
|
|
28060
|
+
for (let i = 0, j = points.length - 1; i < points.length; j = i++) {
|
|
28061
|
+
const a = points[i];
|
|
28062
|
+
const b = points[j];
|
|
28063
|
+
if (a.y > p.y !== b.y > p.y && p.x < (b.x - a.x) * (p.y - a.y) / (b.y - a.y) + a.x) inside = !inside;
|
|
28064
|
+
}
|
|
28065
|
+
return inside;
|
|
28066
|
+
}
|
|
28067
|
+
const encloses = (p, c) => p.box.x0 <= c.box.x0 && p.box.y0 <= c.box.y0 && p.box.x1 >= c.box.x1 && p.box.y1 >= c.box.y1 && contains(p.points, c.inside);
|
|
28068
|
+
/** Triangles filling closed `contours` by the nonzero rule, as flat [x, y, …] vertices. */
|
|
28069
|
+
function fillContours(contours) {
|
|
28070
|
+
const all = contours.map((points) => ({
|
|
28071
|
+
points,
|
|
28072
|
+
area: signedArea(points),
|
|
28073
|
+
box: boxOf(points),
|
|
28074
|
+
inside: insidePoint(points),
|
|
28075
|
+
parent: -1,
|
|
28076
|
+
winding: 0
|
|
28077
|
+
}));
|
|
28078
|
+
const order = all.map((_, i) => i).sort((a, b) => Math.abs(all[b].area) - Math.abs(all[a].area));
|
|
28079
|
+
order.forEach((ci, rank) => {
|
|
28080
|
+
const c = all[ci];
|
|
28081
|
+
for (let r = rank - 1; r >= 0; r--) {
|
|
28082
|
+
const pi = order[r];
|
|
28083
|
+
if (encloses(all[pi], c)) {
|
|
28084
|
+
c.parent = pi;
|
|
28085
|
+
break;
|
|
28086
|
+
}
|
|
28087
|
+
}
|
|
28088
|
+
c.winding = (c.parent >= 0 ? all[c.parent].winding : 0) + Math.sign(c.area);
|
|
28089
|
+
});
|
|
28090
|
+
const out = [];
|
|
28091
|
+
all.forEach((c, ci) => {
|
|
28092
|
+
if (c.winding === 0) return;
|
|
28093
|
+
const coords = flat(c.points);
|
|
28094
|
+
const holeStarts = [];
|
|
28095
|
+
for (const h of all) {
|
|
28096
|
+
if (h.parent !== ci) continue;
|
|
28097
|
+
holeStarts.push(coords.length / 2);
|
|
28098
|
+
for (const p of h.points) coords.push(p.x, p.y);
|
|
28099
|
+
}
|
|
28100
|
+
for (const k of earcut(coords, holeStarts)) out.push(coords[k * 2], coords[k * 2 + 1]);
|
|
28101
|
+
});
|
|
28102
|
+
return new Float32Array(out);
|
|
28103
|
+
}
|
|
28104
|
+
/**
|
|
27993
28105
|
* Sample a cubic bezier curve into linear segments.
|
|
27994
28106
|
*/
|
|
27995
28107
|
function sampleCubicBezier(p0, p1, p2, p3, steps = 24) {
|
|
@@ -28097,8 +28209,26 @@ function sampleSvgArc(p0, rxIn, ryIn, rotationDeg, largeArc, sweep, p1) {
|
|
|
28097
28209
|
* Parse an SVG path string (M, L, H, V, C, S, Q, T, A, Z) into line segments.
|
|
28098
28210
|
*/
|
|
28099
28211
|
function parseSvgPathToSegments(d) {
|
|
28212
|
+
return parseSvgPath(d).segments;
|
|
28213
|
+
}
|
|
28214
|
+
/**
|
|
28215
|
+
* The path's segments, and for each the subpath it belongs to (every M
|
|
28216
|
+
* starts one): fills need to know where each subpath begins.
|
|
28217
|
+
*/
|
|
28218
|
+
function parseSvgPath(d) {
|
|
28100
28219
|
const segments = [];
|
|
28101
|
-
|
|
28220
|
+
const subpaths = [];
|
|
28221
|
+
if (!d || typeof d !== "string") return {
|
|
28222
|
+
segments,
|
|
28223
|
+
subpaths
|
|
28224
|
+
};
|
|
28225
|
+
let subpath = -1;
|
|
28226
|
+
const emit = (...added) => {
|
|
28227
|
+
for (const seg of added) {
|
|
28228
|
+
segments.push(seg);
|
|
28229
|
+
subpaths.push(subpath);
|
|
28230
|
+
}
|
|
28231
|
+
};
|
|
28102
28232
|
const tokens = [];
|
|
28103
28233
|
const regex = /([a-df-z])|([-+]?(?:\d*\.\d+|\d+)(?:[eE][-+]?\d+)?)/gi;
|
|
28104
28234
|
let match;
|
|
@@ -28144,9 +28274,10 @@ function parseSvgPathToSegments(d) {
|
|
|
28144
28274
|
x,
|
|
28145
28275
|
y
|
|
28146
28276
|
};
|
|
28277
|
+
subpath++;
|
|
28147
28278
|
first = false;
|
|
28148
28279
|
} else {
|
|
28149
|
-
|
|
28280
|
+
emit({
|
|
28150
28281
|
p0: current,
|
|
28151
28282
|
p1: {
|
|
28152
28283
|
x,
|
|
@@ -28171,7 +28302,7 @@ function parseSvgPathToSegments(d) {
|
|
|
28171
28302
|
x += current.x;
|
|
28172
28303
|
y += current.y;
|
|
28173
28304
|
}
|
|
28174
|
-
|
|
28305
|
+
emit({
|
|
28175
28306
|
p0: current,
|
|
28176
28307
|
p1: {
|
|
28177
28308
|
x,
|
|
@@ -28194,7 +28325,7 @@ function parseSvgPathToSegments(d) {
|
|
|
28194
28325
|
x,
|
|
28195
28326
|
y: current.y
|
|
28196
28327
|
};
|
|
28197
|
-
|
|
28328
|
+
emit({
|
|
28198
28329
|
p0: current,
|
|
28199
28330
|
p1: next
|
|
28200
28331
|
});
|
|
@@ -28211,7 +28342,7 @@ function parseSvgPathToSegments(d) {
|
|
|
28211
28342
|
x: current.x,
|
|
28212
28343
|
y
|
|
28213
28344
|
};
|
|
28214
|
-
|
|
28345
|
+
emit({
|
|
28215
28346
|
p0: current,
|
|
28216
28347
|
p1: next
|
|
28217
28348
|
});
|
|
@@ -28248,7 +28379,7 @@ function parseSvgPathToSegments(d) {
|
|
|
28248
28379
|
x,
|
|
28249
28380
|
y
|
|
28250
28381
|
};
|
|
28251
|
-
|
|
28382
|
+
emit(...sampleCubicBezier(current, p1, p2, end));
|
|
28252
28383
|
current = end;
|
|
28253
28384
|
lastCubicControl = p2;
|
|
28254
28385
|
}
|
|
@@ -28283,7 +28414,7 @@ function parseSvgPathToSegments(d) {
|
|
|
28283
28414
|
x,
|
|
28284
28415
|
y
|
|
28285
28416
|
};
|
|
28286
|
-
|
|
28417
|
+
emit(...sampleCubicBezier(current, p1, p2, end));
|
|
28287
28418
|
current = end;
|
|
28288
28419
|
lastCubicControl = p2;
|
|
28289
28420
|
}
|
|
@@ -28309,7 +28440,7 @@ function parseSvgPathToSegments(d) {
|
|
|
28309
28440
|
x,
|
|
28310
28441
|
y
|
|
28311
28442
|
};
|
|
28312
|
-
|
|
28443
|
+
emit(...sampleQuadraticBezier(current, p1, end));
|
|
28313
28444
|
current = end;
|
|
28314
28445
|
lastQuadControl = p1;
|
|
28315
28446
|
}
|
|
@@ -28336,7 +28467,7 @@ function parseSvgPathToSegments(d) {
|
|
|
28336
28467
|
x,
|
|
28337
28468
|
y
|
|
28338
28469
|
};
|
|
28339
|
-
|
|
28470
|
+
emit(...sampleQuadraticBezier(current, p1, end));
|
|
28340
28471
|
current = end;
|
|
28341
28472
|
lastQuadControl = p1;
|
|
28342
28473
|
}
|
|
@@ -28359,14 +28490,14 @@ function parseSvgPathToSegments(d) {
|
|
|
28359
28490
|
x,
|
|
28360
28491
|
y
|
|
28361
28492
|
};
|
|
28362
|
-
|
|
28493
|
+
emit(...sampleSvgArc(current, rx, ry, rotation, largeArc, sweep, end));
|
|
28363
28494
|
current = end;
|
|
28364
28495
|
}
|
|
28365
28496
|
lastCubicControl = null;
|
|
28366
28497
|
lastQuadControl = null;
|
|
28367
28498
|
break;
|
|
28368
28499
|
case "Z":
|
|
28369
|
-
if (Math.hypot(current.x - subpathStart.x, current.y - subpathStart.y) > 1e-5)
|
|
28500
|
+
if (Math.hypot(current.x - subpathStart.x, current.y - subpathStart.y) > 1e-5) emit({
|
|
28370
28501
|
p0: current,
|
|
28371
28502
|
p1: subpathStart
|
|
28372
28503
|
});
|
|
@@ -28377,7 +28508,10 @@ function parseSvgPathToSegments(d) {
|
|
|
28377
28508
|
default: break;
|
|
28378
28509
|
}
|
|
28379
28510
|
}
|
|
28380
|
-
return
|
|
28511
|
+
return {
|
|
28512
|
+
segments,
|
|
28513
|
+
subpaths
|
|
28514
|
+
};
|
|
28381
28515
|
}
|
|
28382
28516
|
/**
|
|
28383
28517
|
* Trim linear path segments using arc-length parameterization.
|
|
@@ -28438,6 +28572,19 @@ function trimPathSegments(segments, trimStart, trimEnd, trimOffset = 0) {
|
|
|
28438
28572
|
}
|
|
28439
28573
|
}
|
|
28440
28574
|
/**
|
|
28575
|
+
* A dash pattern as SVG's `stroke-dasharray` writes it ("16 12", "4,8") or as
|
|
28576
|
+
* numbers, ready for {@link dashPathSegments}. Following SVG, an odd list is
|
|
28577
|
+
* repeated to make it even, and a negative or unreadable entry, or a pattern
|
|
28578
|
+
* of zero length, means a solid stroke (`undefined`).
|
|
28579
|
+
*/
|
|
28580
|
+
function parseDashArray(value) {
|
|
28581
|
+
if (value === void 0) return void 0;
|
|
28582
|
+
const parts = typeof value === "string" ? value.trim().split(/[\s,]+/).filter(Boolean).map(Number) : [...value];
|
|
28583
|
+
if (parts.length === 0 || parts.some((n) => !Number.isFinite(n) || n < 0)) return void 0;
|
|
28584
|
+
if (parts.reduce((sum, n) => sum + n, 0) <= 0) return void 0;
|
|
28585
|
+
return parts.length % 2 === 1 ? [...parts, ...parts] : parts;
|
|
28586
|
+
}
|
|
28587
|
+
/**
|
|
28441
28588
|
* Apply dash patterns along linear path segments.
|
|
28442
28589
|
*/
|
|
28443
28590
|
function dashPathSegments(segments, dashArray, dashOffset = 0) {
|
|
@@ -28649,6 +28796,44 @@ function triangulatePolygon(contour) {
|
|
|
28649
28796
|
if (rem.length === 3) triangles.push(rem[0], rem[1], rem[2]);
|
|
28650
28797
|
return triangles;
|
|
28651
28798
|
}
|
|
28799
|
+
/** A path's subpaths as closed point lists, degenerate ones dropped. */
|
|
28800
|
+
function pathContours(d) {
|
|
28801
|
+
const bySubpath = /* @__PURE__ */ new Map();
|
|
28802
|
+
const { segments, subpaths } = parseSvgPath(d);
|
|
28803
|
+
segments.forEach((seg, i) => {
|
|
28804
|
+
const id = subpaths[i] ?? 0;
|
|
28805
|
+
let points = bySubpath.get(id);
|
|
28806
|
+
if (!points) {
|
|
28807
|
+
points = [seg.p0];
|
|
28808
|
+
bySubpath.set(id, points);
|
|
28809
|
+
}
|
|
28810
|
+
points.push(seg.p1);
|
|
28811
|
+
});
|
|
28812
|
+
const contours = [];
|
|
28813
|
+
for (const points of bySubpath.values()) {
|
|
28814
|
+
const first = points[0];
|
|
28815
|
+
const last = points[points.length - 1];
|
|
28816
|
+
if (Math.hypot(last.x - first.x, last.y - first.y) < 1e-5) points.pop();
|
|
28817
|
+
if (points.length >= 3 && Math.abs(signedArea(points)) > 1e-6) contours.push(points);
|
|
28818
|
+
}
|
|
28819
|
+
return contours;
|
|
28820
|
+
}
|
|
28821
|
+
/** Path fills are redrawn every frame from the same data: keep the last few. */
|
|
28822
|
+
const PATH_FILL_CACHE = 64;
|
|
28823
|
+
const pathFills = /* @__PURE__ */ new Map();
|
|
28824
|
+
/** Triangles filling path `d` by the nonzero rule (see {@link fillContours}). */
|
|
28825
|
+
function cachedPathFill(d) {
|
|
28826
|
+
const hit = pathFills.get(d);
|
|
28827
|
+
if (hit) {
|
|
28828
|
+
pathFills.delete(d);
|
|
28829
|
+
pathFills.set(d, hit);
|
|
28830
|
+
return hit;
|
|
28831
|
+
}
|
|
28832
|
+
const tris = fillContours(pathContours(d));
|
|
28833
|
+
pathFills.set(d, tris);
|
|
28834
|
+
if (pathFills.size > PATH_FILL_CACHE) pathFills.delete(pathFills.keys().next().value);
|
|
28835
|
+
return tris;
|
|
28836
|
+
}
|
|
28652
28837
|
/**
|
|
28653
28838
|
* Triangulate a shape geometry into a flat Float32Array of 2D vertex pairs [x, y, x, y, ...].
|
|
28654
28839
|
*/
|
|
@@ -28773,19 +28958,16 @@ function triangulateShape(config$1) {
|
|
|
28773
28958
|
yBotHead
|
|
28774
28959
|
]);
|
|
28775
28960
|
}
|
|
28776
|
-
if (shapeType === "path" && config$1.path)
|
|
28777
|
-
const segments = parseSvgPathToSegments(config$1.path);
|
|
28778
|
-
if (segments.length === 0) return new Float32Array(0);
|
|
28779
|
-
const tris = triangulatePolygon(segments.map((s) => s.p0));
|
|
28780
|
-
const out = new Float32Array(tris.length * 2);
|
|
28781
|
-
for (let i = 0; i < tris.length; i++) {
|
|
28782
|
-
out[i * 2] = tris[i].x;
|
|
28783
|
-
out[i * 2 + 1] = tris[i].y;
|
|
28784
|
-
}
|
|
28785
|
-
return out;
|
|
28786
|
-
}
|
|
28961
|
+
if (shapeType === "path" && config$1.path) return cachedPathFill(config$1.path);
|
|
28787
28962
|
return new Float32Array(0);
|
|
28788
28963
|
}
|
|
28964
|
+
/**
|
|
28965
|
+
* Strokes a path in one instanced draw: each instance is one straight
|
|
28966
|
+
* segment (p0, p1), expanded by the vertex shader into a quad that covers it
|
|
28967
|
+
* plus half the stroke width and 2 px of antialiasing; the fragment shader
|
|
28968
|
+
* shades the segment's capped distance field. Everything shared by the
|
|
28969
|
+
* path (transform, colour, width, cap) is in the uniforms.
|
|
28970
|
+
*/
|
|
28789
28971
|
const pathWgsl = `
|
|
28790
28972
|
struct Uniforms {
|
|
28791
28973
|
transformCol0 : vec4<f32>,
|
|
@@ -28794,8 +28976,6 @@ struct Uniforms {
|
|
|
28794
28976
|
params : vec4<f32>, // x = opacity, y = surfaceWidth, z = surfaceHeight, w = strokeWidth
|
|
28795
28977
|
color : vec4<f32>,
|
|
28796
28978
|
style : vec4<f32>, // x = capType (0 = round, 1 = butt, 2 = square)
|
|
28797
|
-
p0 : vec2<f32>,
|
|
28798
|
-
p1 : vec2<f32>,
|
|
28799
28979
|
};
|
|
28800
28980
|
|
|
28801
28981
|
@group(0) @binding(0) var<uniform> u : Uniforms;
|
|
@@ -28803,17 +28983,30 @@ struct Uniforms {
|
|
|
28803
28983
|
struct VSOut {
|
|
28804
28984
|
@builtin(position) pos : vec4<f32>,
|
|
28805
28985
|
@location(0) localPos : vec2<f32>,
|
|
28986
|
+
@location(1) @interpolate(flat) p0 : vec2<f32>,
|
|
28987
|
+
@location(2) @interpolate(flat) p1 : vec2<f32>,
|
|
28806
28988
|
};
|
|
28807
28989
|
|
|
28808
|
-
@vertex fn vs(@location(0)
|
|
28990
|
+
@vertex fn vs(@builtin(vertex_index) corner : u32, @location(0) seg : vec4<f32>) -> VSOut {
|
|
28991
|
+
let p0 = seg.xy;
|
|
28992
|
+
let p1 = seg.zw;
|
|
28993
|
+
let d = p1 - p0;
|
|
28994
|
+
let len = max(length(d), 1e-6);
|
|
28995
|
+
let padding = u.params.w * 0.5 + 2.0;
|
|
28996
|
+
let along = (d / len) * padding;
|
|
28997
|
+
let across = vec2<f32>(-along.y, along.x);
|
|
28998
|
+
// Triangle strip: p0 −along ∓across, then p1 +along ∓across.
|
|
28999
|
+
let atEnd = corner >= 2u;
|
|
29000
|
+
let side = select(-1.0, 1.0, (corner & 1u) == 1u);
|
|
29001
|
+
let xy = select(p0 - along, p1 + along, atEnd) + across * side;
|
|
29002
|
+
|
|
28809
29003
|
let transform = mat3x3<f32>(u.transformCol0.xyz, u.transformCol1.xyz, u.transformCol2.xyz);
|
|
28810
29004
|
let p = transform * vec3<f32>(xy, 1.0);
|
|
28811
|
-
|
|
28812
29005
|
let surfaceSize = u.params.yz;
|
|
28813
29006
|
let clipX = (p.x / surfaceSize.x) * 2.0 - 1.0;
|
|
28814
29007
|
let clipY = 1.0 - (p.y / surfaceSize.y) * 2.0;
|
|
28815
29008
|
|
|
28816
|
-
return VSOut(vec4<f32>(clipX, clipY, 0.0, 1.0), xy);
|
|
29009
|
+
return VSOut(vec4<f32>(clipX, clipY, 0.0, 1.0), xy, p0, p1);
|
|
28817
29010
|
}
|
|
28818
29011
|
|
|
28819
29012
|
fn sdSegmentWithCap(p: vec2<f32>, a: vec2<f32>, b: vec2<f32>, radius: f32, capType: f32) -> f32 {
|
|
@@ -28825,10 +29018,10 @@ fn sdSegmentWithCap(p: vec2<f32>, a: vec2<f32>, b: vec2<f32>, radius: f32, capTy
|
|
|
28825
29018
|
let dir = ba / len;
|
|
28826
29019
|
let normal = vec2<f32>(-dir.y, dir.x);
|
|
28827
29020
|
let pa = p - a;
|
|
28828
|
-
|
|
29021
|
+
|
|
28829
29022
|
let proj = dot(pa, dir);
|
|
28830
29023
|
let perp = abs(dot(pa, normal));
|
|
28831
|
-
|
|
29024
|
+
|
|
28832
29025
|
if (capType > 0.5 && capType < 1.5) {
|
|
28833
29026
|
// Butt cap: terminates strictly at endpoints a and b
|
|
28834
29027
|
let dx = max(-proj, proj - len);
|
|
@@ -28852,15 +29045,15 @@ fn sdSegmentWithCap(p: vec2<f32>, a: vec2<f32>, b: vec2<f32>, radius: f32, capTy
|
|
|
28852
29045
|
|
|
28853
29046
|
@fragment fn fs(in : VSOut) -> @location(0) vec4<f32> {
|
|
28854
29047
|
let radius = u.params.w * 0.5;
|
|
28855
|
-
let d = sdSegmentWithCap(in.localPos,
|
|
28856
|
-
|
|
29048
|
+
let d = sdSegmentWithCap(in.localPos, in.p0, in.p1, radius, u.style.x);
|
|
29049
|
+
|
|
28857
29050
|
let fw = max(fwidth(d), 1e-5);
|
|
28858
29051
|
let edgeAlpha = clamp(0.5 - d / fw, 0.0, 1.0);
|
|
28859
29052
|
let alpha = u.color.a * u.params.x * edgeAlpha;
|
|
28860
29053
|
if (alpha <= 0.0) {
|
|
28861
29054
|
discard;
|
|
28862
29055
|
}
|
|
28863
|
-
|
|
29056
|
+
|
|
28864
29057
|
return vec4<f32>(u.color.rgb * alpha, alpha);
|
|
28865
29058
|
}
|
|
28866
29059
|
`;
|
|
@@ -28917,127 +29110,111 @@ function createVec2Pipeline(device, options) {
|
|
|
28917
29110
|
primitive: { topology: options.topology }
|
|
28918
29111
|
});
|
|
28919
29112
|
}
|
|
29113
|
+
/** A straight segment's two ends, the instance the stroke shader expands into a quad. */
|
|
29114
|
+
const SEGMENT_FLOATS = 4;
|
|
28920
29115
|
var PathPipeline = class {
|
|
28921
29116
|
device;
|
|
28922
29117
|
pipeline;
|
|
28923
29118
|
maxPipeline;
|
|
28924
29119
|
uniformLayout;
|
|
28925
29120
|
uniformPool;
|
|
28926
|
-
|
|
29121
|
+
segmentPool;
|
|
28927
29122
|
uniformBindGroupCache = new UniformBindGroupCache();
|
|
28928
|
-
scratchData = new Float32Array(
|
|
29123
|
+
scratchData = new Float32Array(24);
|
|
28929
29124
|
constructor(device, format) {
|
|
28930
29125
|
this.device = device;
|
|
28931
29126
|
this.uniformPool = new BufferPool(4096, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
|
|
28932
|
-
this.
|
|
29127
|
+
this.segmentPool = new BufferPool(4096, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST);
|
|
28933
29128
|
const module$1 = device.createShaderModule({
|
|
28934
29129
|
label: "path.wgsl",
|
|
28935
29130
|
code: pathWgsl
|
|
28936
29131
|
});
|
|
28937
29132
|
this.uniformLayout = createUniformLayout(device);
|
|
28938
|
-
|
|
28939
|
-
label
|
|
28940
|
-
|
|
28941
|
-
|
|
28942
|
-
|
|
28943
|
-
|
|
29133
|
+
const create = (label, blend) => device.createRenderPipeline({
|
|
29134
|
+
label,
|
|
29135
|
+
layout: device.createPipelineLayout({ bindGroupLayouts: [this.uniformLayout] }),
|
|
29136
|
+
vertex: {
|
|
29137
|
+
module: module$1,
|
|
29138
|
+
entryPoint: "vs",
|
|
29139
|
+
buffers: [{
|
|
29140
|
+
arrayStride: SEGMENT_FLOATS * 4,
|
|
29141
|
+
stepMode: "instance",
|
|
29142
|
+
attributes: [{
|
|
29143
|
+
shaderLocation: 0,
|
|
29144
|
+
offset: 0,
|
|
29145
|
+
format: "float32x4"
|
|
29146
|
+
}]
|
|
29147
|
+
}]
|
|
29148
|
+
},
|
|
29149
|
+
fragment: {
|
|
29150
|
+
module: module$1,
|
|
29151
|
+
entryPoint: "fs",
|
|
29152
|
+
targets: [{
|
|
29153
|
+
format,
|
|
29154
|
+
blend
|
|
29155
|
+
}]
|
|
29156
|
+
},
|
|
29157
|
+
primitive: { topology: "triangle-strip" }
|
|
28944
29158
|
});
|
|
28945
|
-
this.
|
|
28946
|
-
|
|
28947
|
-
|
|
28948
|
-
|
|
28949
|
-
|
|
28950
|
-
|
|
28951
|
-
|
|
28952
|
-
|
|
28953
|
-
|
|
28954
|
-
|
|
28955
|
-
|
|
28956
|
-
},
|
|
28957
|
-
alpha: {
|
|
28958
|
-
srcFactor: "one",
|
|
28959
|
-
dstFactor: "one",
|
|
28960
|
-
operation: "max"
|
|
28961
|
-
}
|
|
29159
|
+
this.pipeline = create("PathPipeline", PREMULTIPLIED_OVER);
|
|
29160
|
+
this.maxPipeline = create("PathPipeline.max", {
|
|
29161
|
+
color: {
|
|
29162
|
+
srcFactor: "one",
|
|
29163
|
+
dstFactor: "one",
|
|
29164
|
+
operation: "max"
|
|
29165
|
+
},
|
|
29166
|
+
alpha: {
|
|
29167
|
+
srcFactor: "one",
|
|
29168
|
+
dstFactor: "one",
|
|
29169
|
+
operation: "max"
|
|
28962
29170
|
}
|
|
28963
29171
|
});
|
|
28964
29172
|
}
|
|
28965
29173
|
resetPools() {
|
|
28966
29174
|
this.uniformPool.reset();
|
|
28967
|
-
this.
|
|
29175
|
+
this.segmentPool.reset();
|
|
28968
29176
|
}
|
|
28969
29177
|
drawPath(pass, transformStack, pathStr, color, strokeWidth, surfaceWidth, surfaceHeight, opts) {
|
|
28970
|
-
|
|
28971
|
-
if (segments.length === 0) return;
|
|
28972
|
-
if (opts?.trimStart !== void 0 || opts?.trimEnd !== void 0 || opts?.trimOffset !== void 0) segments = trimPathSegments(segments, opts.trimStart ?? 0, opts.trimEnd ?? 1, opts.trimOffset ?? 0);
|
|
28973
|
-
if (opts?.strokeDashArray && opts.strokeDashArray.length > 0) segments = dashPathSegments(segments, opts.strokeDashArray, opts.strokeDashOffset ?? 0);
|
|
28974
|
-
if (segments.length === 0) return;
|
|
28975
|
-
const c = parseColor(color);
|
|
28976
|
-
const opacity = opts?.opacity ?? 1;
|
|
28977
|
-
let capType = 0;
|
|
28978
|
-
if (opts?.strokeLineCap === "butt") capType = 1;
|
|
28979
|
-
else if (opts?.strokeLineCap === "square") capType = 2;
|
|
28980
|
-
for (const segment of segments) this.drawSegment(pass, transformStack, segment.p0, segment.p1, c, strokeWidth, capType, surfaceWidth, surfaceHeight, opacity, opts);
|
|
29178
|
+
this.drawSegments(pass, transformStack, parseSvgPathToSegments(pathStr), color, strokeWidth, surfaceWidth, surfaceHeight, opts);
|
|
28981
29179
|
}
|
|
28982
29180
|
drawSegments(pass, transformStack, segments, color, strokeWidth, surfaceWidth, surfaceHeight, opts) {
|
|
28983
29181
|
let activeSegments = segments;
|
|
28984
29182
|
if (opts?.trimStart !== void 0 || opts?.trimEnd !== void 0 || opts?.trimOffset !== void 0) activeSegments = trimPathSegments(activeSegments, opts.trimStart ?? 0, opts.trimEnd ?? 1, opts.trimOffset ?? 0);
|
|
28985
29183
|
if (opts?.strokeDashArray && opts.strokeDashArray.length > 0) activeSegments = dashPathSegments(activeSegments, opts.strokeDashArray, opts.strokeDashOffset ?? 0);
|
|
28986
|
-
|
|
29184
|
+
const ends = new Float32Array(activeSegments.length * SEGMENT_FLOATS);
|
|
29185
|
+
let count = 0;
|
|
29186
|
+
for (const { p0, p1 } of activeSegments) {
|
|
29187
|
+
if (Math.hypot(p1.x - p0.x, p1.y - p0.y) < 1e-6) continue;
|
|
29188
|
+
const at = count++ * SEGMENT_FLOATS;
|
|
29189
|
+
ends[at] = p0.x;
|
|
29190
|
+
ends[at + 1] = p0.y;
|
|
29191
|
+
ends[at + 2] = p1.x;
|
|
29192
|
+
ends[at + 3] = p1.y;
|
|
29193
|
+
}
|
|
29194
|
+
if (count === 0) return;
|
|
28987
29195
|
const c = parseColor(color);
|
|
28988
|
-
const opacity = opts?.opacity ?? 1;
|
|
28989
|
-
let capType = 0;
|
|
28990
|
-
if (opts?.strokeLineCap === "butt") capType = 1;
|
|
28991
|
-
else if (opts?.strokeLineCap === "square") capType = 2;
|
|
28992
|
-
for (const segment of activeSegments) this.drawSegment(pass, transformStack, segment.p0, segment.p1, c, strokeWidth, capType, surfaceWidth, surfaceHeight, opacity, opts);
|
|
28993
|
-
}
|
|
28994
|
-
drawSegment(pass, transformStack, p0, p1, color, strokeWidth, capType, surfaceWidth, surfaceHeight, opacity, opts) {
|
|
28995
29196
|
const data = this.scratchData;
|
|
28996
|
-
transformStack.packIntoBuffer(data, opacity, surfaceWidth, surfaceHeight, opts?.transform);
|
|
29197
|
+
transformStack.packIntoBuffer(data, opts?.opacity ?? 1, surfaceWidth, surfaceHeight, opts?.transform);
|
|
28997
29198
|
data[15] = strokeWidth;
|
|
28998
|
-
data[16] =
|
|
28999
|
-
data[17] =
|
|
29000
|
-
data[18] =
|
|
29001
|
-
data[19] =
|
|
29002
|
-
data[20] =
|
|
29199
|
+
data[16] = c.r;
|
|
29200
|
+
data[17] = c.g;
|
|
29201
|
+
data[18] = c.b;
|
|
29202
|
+
data[19] = c.a;
|
|
29203
|
+
data[20] = opts?.strokeLineCap === "butt" ? 1 : opts?.strokeLineCap === "square" ? 2 : 0;
|
|
29003
29204
|
data[21] = 0;
|
|
29004
29205
|
data[22] = 0;
|
|
29005
29206
|
data[23] = 0;
|
|
29006
|
-
data[24] = p0.x;
|
|
29007
|
-
data[25] = p0.y;
|
|
29008
|
-
data[26] = p1.x;
|
|
29009
|
-
data[27] = p1.y;
|
|
29010
29207
|
const uniformBuffer = this.uniformPool.getBuffer(this.device, data);
|
|
29011
|
-
const
|
|
29012
|
-
const
|
|
29013
|
-
|
|
29014
|
-
|
|
29015
|
-
|
|
29016
|
-
|
|
29017
|
-
const ny = dy / len * padding;
|
|
29018
|
-
const px = -ny;
|
|
29019
|
-
const py = nx;
|
|
29020
|
-
const vertexData = new Float32Array([
|
|
29021
|
-
p0.x - nx - px,
|
|
29022
|
-
p0.y - ny - py,
|
|
29023
|
-
p0.x - nx + px,
|
|
29024
|
-
p0.y - ny + py,
|
|
29025
|
-
p1.x + nx - px,
|
|
29026
|
-
p1.y + ny - py,
|
|
29027
|
-
p1.x + nx + px,
|
|
29028
|
-
p1.y + ny + py
|
|
29029
|
-
]);
|
|
29030
|
-
const vertexBuffer = this.vertexPool.getBuffer(this.device, vertexData);
|
|
29031
|
-
const pipeline = opts?.blendMode === "max" ? this.maxPipeline : this.pipeline;
|
|
29032
|
-
pass.setPipeline(pipeline);
|
|
29033
|
-
const uniformBindGroup = this.uniformBindGroupCache.getBindGroup(this.device, this.uniformLayout, uniformBuffer);
|
|
29034
|
-
pass.setBindGroup(0, uniformBindGroup);
|
|
29035
|
-
pass.setVertexBuffer(0, vertexBuffer);
|
|
29036
|
-
pass.draw(4);
|
|
29208
|
+
const segmentBuffer = this.segmentPool.getBuffer(this.device, ends.subarray(0, count * SEGMENT_FLOATS));
|
|
29209
|
+
const useMax = opts?.blendMode === "max";
|
|
29210
|
+
pass.setPipeline(useMax ? this.maxPipeline : this.pipeline);
|
|
29211
|
+
pass.setBindGroup(0, this.uniformBindGroupCache.getBindGroup(this.device, this.uniformLayout, uniformBuffer));
|
|
29212
|
+
pass.setVertexBuffer(0, segmentBuffer);
|
|
29213
|
+
pass.draw(4, count);
|
|
29037
29214
|
}
|
|
29038
29215
|
destroy() {
|
|
29039
29216
|
this.uniformPool.destroy();
|
|
29040
|
-
this.
|
|
29217
|
+
this.segmentPool.destroy();
|
|
29041
29218
|
this.uniformBindGroupCache.destroy();
|
|
29042
29219
|
}
|
|
29043
29220
|
};
|
|
@@ -30806,8 +30983,13 @@ var BloomPipeline = class {
|
|
|
30806
30983
|
module;
|
|
30807
30984
|
pipelineLayout;
|
|
30808
30985
|
sampler;
|
|
30809
|
-
|
|
30810
|
-
|
|
30986
|
+
/**
|
|
30987
|
+
* Mip chains by size and depth. Scenes with different bloom share a frame
|
|
30988
|
+
* (one command buffer), so a chain stays alive until the frame is done:
|
|
30989
|
+
* chains not used in a frame are destroyed at the next `resetPools`.
|
|
30990
|
+
*/
|
|
30991
|
+
chains = /* @__PURE__ */ new Map();
|
|
30992
|
+
usedThisFrame = /* @__PURE__ */ new Set();
|
|
30811
30993
|
placeholder;
|
|
30812
30994
|
uniformPool = new BufferPool(48, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
|
|
30813
30995
|
constructor(device) {
|
|
@@ -30910,17 +31092,18 @@ var BloomPipeline = class {
|
|
|
30910
31092
|
}
|
|
30911
31093
|
return pipe$1;
|
|
30912
31094
|
}
|
|
30913
|
-
|
|
31095
|
+
mipChain(width, height, levels) {
|
|
30914
31096
|
const key = `${width}x${height}x${levels}`;
|
|
30915
|
-
|
|
30916
|
-
|
|
30917
|
-
|
|
31097
|
+
this.usedThisFrame.add(key);
|
|
31098
|
+
const cached$1 = this.chains.get(key);
|
|
31099
|
+
if (cached$1) return cached$1;
|
|
31100
|
+
const chain = [];
|
|
30918
31101
|
let w = width;
|
|
30919
31102
|
let h = height;
|
|
30920
31103
|
for (let i = 0; i < levels; i++) {
|
|
30921
31104
|
w = Math.max(1, Math.floor(w / 2));
|
|
30922
31105
|
h = Math.max(1, Math.floor(h / 2));
|
|
30923
|
-
|
|
31106
|
+
chain.push(this.device.createTexture({
|
|
30924
31107
|
label: `BloomMip${i}`,
|
|
30925
31108
|
size: {
|
|
30926
31109
|
width: w,
|
|
@@ -30931,7 +31114,8 @@ var BloomPipeline = class {
|
|
|
30931
31114
|
}));
|
|
30932
31115
|
if (w === 1 && h === 1) break;
|
|
30933
31116
|
}
|
|
30934
|
-
this.
|
|
31117
|
+
this.chains.set(key, chain);
|
|
31118
|
+
return chain;
|
|
30935
31119
|
}
|
|
30936
31120
|
uniforms(texelW, texelH, opts) {
|
|
30937
31121
|
const data = new Float32Array([
|
|
@@ -31009,8 +31193,7 @@ var BloomPipeline = class {
|
|
|
31009
31193
|
mode: display ? 1 : 0
|
|
31010
31194
|
};
|
|
31011
31195
|
const levels = Math.max(1, Math.min(8, Math.round(options.radius ?? 6)));
|
|
31012
|
-
this.
|
|
31013
|
-
const mips = this.mips;
|
|
31196
|
+
const mips = this.mipChain(source.width, source.height, levels);
|
|
31014
31197
|
const u = (w, h) => this.uniforms(1 / w, 1 / h, opts);
|
|
31015
31198
|
const glowSource = hdrSource ?? source;
|
|
31016
31199
|
this.pass(encoder, this.prefilterPipe, mips[0].createView(), glowSource, this.placeholder, u(glowSource.width, glowSource.height), "clear");
|
|
@@ -31024,12 +31207,22 @@ var BloomPipeline = class {
|
|
|
31024
31207
|
}
|
|
31025
31208
|
this.pass(encoder, this.compositePipe(dest.format), dest.createView(), mips[0], source, u(mips[0].width, mips[0].height), "clear");
|
|
31026
31209
|
}
|
|
31027
|
-
/**
|
|
31210
|
+
/**
|
|
31211
|
+
* Call once per frame before `apply`: recycles the per-pass uniforms and
|
|
31212
|
+
* frees the mip chains the last frame did not use.
|
|
31213
|
+
*/
|
|
31028
31214
|
resetPools() {
|
|
31029
31215
|
this.uniformPool.reset();
|
|
31216
|
+
for (const [key, chain] of this.chains) {
|
|
31217
|
+
if (this.usedThisFrame.has(key)) continue;
|
|
31218
|
+
for (const t of chain) t.destroy();
|
|
31219
|
+
this.chains.delete(key);
|
|
31220
|
+
}
|
|
31221
|
+
this.usedThisFrame.clear();
|
|
31030
31222
|
}
|
|
31031
31223
|
destroy() {
|
|
31032
|
-
for (const
|
|
31224
|
+
for (const chain of this.chains.values()) for (const t of chain) t.destroy();
|
|
31225
|
+
this.chains.clear();
|
|
31033
31226
|
this.placeholder.destroy();
|
|
31034
31227
|
this.uniformPool.destroy();
|
|
31035
31228
|
}
|
|
@@ -31418,15 +31611,56 @@ struct Shaded {
|
|
|
31418
31611
|
hdr : vec3<f32>,
|
|
31419
31612
|
};
|
|
31420
31613
|
|
|
31614
|
+
// Two-sided, art-directed diffuse lighting. Shares the full direct-light
|
|
31615
|
+
// storage, range/spot attenuation and PCF shadows with the physical renderer.
|
|
31616
|
+
fn shadeToon(worldPos: vec3<f32>, worldNormal: vec3<f32>, base: vec3<f32>, ambient: f32, shade: vec4<f32>, lightTint: vec4<f32>, params: vec4<f32>) -> vec3<f32> {
|
|
31617
|
+
if (lights.params.y < 0.5) { return base; }
|
|
31618
|
+
var N = normalize(worldNormal);
|
|
31619
|
+
let V = normalize(cam.cameraPos.xyz - worldPos);
|
|
31620
|
+
if (dot(N, V) < 0.0) { N = -N; }
|
|
31621
|
+
var illumination = lights.ambientColor.rgb * ambient * lightTint.rgb;
|
|
31622
|
+
var visibility = clamp(max(illumination.r, max(illumination.g, illumination.b)), 0.0, 1.0);
|
|
31623
|
+
for (var i = 0; i < i32(lights.params.x); i++) {
|
|
31624
|
+
let ls = sampleLight(i, worldPos);
|
|
31625
|
+
if (!ls.valid) { continue; }
|
|
31626
|
+
let cosine = dot(N, ls.L);
|
|
31627
|
+
let softness = max(params.x, 0.0001);
|
|
31628
|
+
let band = smoothstep(lightTint.w - softness * 0.5, lightTint.w + softness * 0.5, cosine);
|
|
31629
|
+
let light = directLights[i];
|
|
31630
|
+
let strength = band * ls.attenuation * light.colorIntensity.w * shadowFactor(worldPos, N, i);
|
|
31631
|
+
let contribution = light.colorIntensity.rgb * lightTint.rgb * strength * mix(1.0, max(cosine, 0.0), shade.w);
|
|
31632
|
+
// Remove the shadow floor only as actual modeled light arrives.
|
|
31633
|
+
// Using the pre-diffuse band here creates a dark ring between the
|
|
31634
|
+
// shadow floor and the lit region, which slides as a surface turns.
|
|
31635
|
+
let energy = max(contribution.r, max(contribution.g, contribution.b));
|
|
31636
|
+
visibility = max(visibility, clamp(energy, 0.0, 1.0));
|
|
31637
|
+
illumination += contribution;
|
|
31638
|
+
}
|
|
31639
|
+
return base * (shade.rgb * (1.0 - visibility) + illumination);
|
|
31640
|
+
}
|
|
31641
|
+
|
|
31642
|
+
// The existing linear-depth attachment doubles as a geometry buffer:
|
|
31643
|
+
// r = optical depth, gb = octahedral world normal, a = outline participation.
|
|
31644
|
+
// Geometric normals deliberately ignore normal maps and texture seams.
|
|
31645
|
+
fn geometryPixel(depth: f32, normal: vec3<f32>, outlined: f32) -> vec4<f32> {
|
|
31646
|
+
let n = normalize(normal);
|
|
31647
|
+
let p = n.xy / max(abs(n.x) + abs(n.y) + abs(n.z), 1e-6);
|
|
31648
|
+
let signs = select(vec2<f32>(-1.0), vec2<f32>(1.0), p >= vec2<f32>(0.0));
|
|
31649
|
+
let oct = select((1.0 - abs(p.yx)) * signs, p, n.z >= 0.0);
|
|
31650
|
+
return vec4<f32>(depth, oct * 0.5 + 0.5, outlined);
|
|
31651
|
+
}
|
|
31652
|
+
|
|
31421
31653
|
/// Shades a surface for the scene's mode.
|
|
31422
31654
|
/// material: x shininess, y specularIntensity, z ambientIntensity, w mode (0 unlit).
|
|
31423
31655
|
/// pbr: x roughness (<0 = default), y metallic, z/w unused.
|
|
31424
31656
|
/// emissive: rgb sRGB color, w strength.
|
|
31425
|
-
fn shadeSurfaceFull(worldPos: vec3<f32>, worldNormal: vec3<f32>, baseColor: vec3<f32>, material: vec4<f32>, pbr: vec4<f32>, emissive: vec4<f32>) -> Shaded {
|
|
31657
|
+
fn shadeSurfaceFull(worldPos: vec3<f32>, worldNormal: vec3<f32>, baseColor: vec3<f32>, material: vec4<f32>, pbr: vec4<f32>, emissive: vec4<f32>, toonShadow: vec4<f32>, toonLight: vec4<f32>, toonParams: vec4<f32>) -> Shaded {
|
|
31426
31658
|
var out: Shaded;
|
|
31427
31659
|
if (lights.params.z < 0.5) {
|
|
31428
31660
|
var c = baseColor;
|
|
31429
|
-
if (material.w
|
|
31661
|
+
if (material.w > 1.5) {
|
|
31662
|
+
c = shadeToon(worldPos, worldNormal, baseColor, material.z, toonShadow, toonLight, toonParams);
|
|
31663
|
+
} else if (material.w >= 0.5) {
|
|
31430
31664
|
c = applyLighting3D(worldPos, worldNormal, baseColor, material);
|
|
31431
31665
|
}
|
|
31432
31666
|
c += emissive.rgb * emissive.w;
|
|
@@ -31437,6 +31671,8 @@ fn shadeSurfaceFull(worldPos: vec3<f32>, worldNormal: vec3<f32>, baseColor: vec3
|
|
|
31437
31671
|
var radiance: vec3<f32>;
|
|
31438
31672
|
if (material.w < 0.5) {
|
|
31439
31673
|
radiance = srgbToLinear(baseColor);
|
|
31674
|
+
} else if (material.w > 1.5) {
|
|
31675
|
+
radiance = srgbToLinear(shadeToon(worldPos, worldNormal, baseColor, material.z, toonShadow, toonLight, toonParams));
|
|
31440
31676
|
} else {
|
|
31441
31677
|
let rough = select(pbr.x, 0.5, pbr.x < 0.0);
|
|
31442
31678
|
radiance = shadePhysical(worldPos, worldNormal, srgbToLinear(baseColor), rough, clamp(pbr.y, 0.0, 1.0), material.z);
|
|
@@ -31472,9 +31708,6 @@ fn shadeSurfaceFull(worldPos: vec3<f32>, worldNormal: vec3<f32>, baseColor: vec3
|
|
|
31472
31708
|
return out;
|
|
31473
31709
|
}
|
|
31474
31710
|
|
|
31475
|
-
fn shadeSurface(worldPos: vec3<f32>, worldNormal: vec3<f32>, baseColor: vec3<f32>, material: vec4<f32>, pbr: vec4<f32>, emissive: vec4<f32>) -> vec3<f32> {
|
|
31476
|
-
return shadeSurfaceFull(worldPos, worldNormal, baseColor, material, pbr, emissive).display;
|
|
31477
|
-
}
|
|
31478
31711
|
`;
|
|
31479
31712
|
/** Group-3 bindings every lit 3D shader declares. */
|
|
31480
31713
|
const lightsBindingsWgsl = `
|
|
@@ -31785,7 +32018,7 @@ fn fs_mrt(in: VsOut) -> FsOutputMrt {
|
|
|
31785
32018
|
var out: FsOutputMrt;
|
|
31786
32019
|
let s = shadeFloor(in);
|
|
31787
32020
|
out.color = vec4<f32>(s.display * s.alpha, s.alpha);
|
|
31788
|
-
out.linearDepth =
|
|
32021
|
+
out.linearDepth = geometryPixel(s.linearDepth, vec3<f32>(0.0, -1.0, 0.0), 1.0);
|
|
31789
32022
|
out.depth = s.depth;
|
|
31790
32023
|
return out;
|
|
31791
32024
|
}
|
|
@@ -31805,7 +32038,7 @@ fn fs_mrt_bloom(in: VsOut) -> FsOutputMrtBloom {
|
|
|
31805
32038
|
var out: FsOutputMrtBloom;
|
|
31806
32039
|
let s = shadeFloor(in);
|
|
31807
32040
|
out.color = vec4<f32>(s.display * s.alpha, s.alpha);
|
|
31808
|
-
out.linearDepth =
|
|
32041
|
+
out.linearDepth = geometryPixel(s.linearDepth, vec3<f32>(0.0, -1.0, 0.0), 1.0);
|
|
31809
32042
|
out.hdr = vec4<f32>(s.hdr * s.alpha, 1.0);
|
|
31810
32043
|
out.depth = s.depth;
|
|
31811
32044
|
return out;
|
|
@@ -32525,6 +32758,9 @@ struct ModelUniforms {
|
|
|
32525
32758
|
shade : vec4<f32>, // rgb = toon shadow-side color multiplier, a = alpha cutoff (0 = none)
|
|
32526
32759
|
pbr : vec4<f32>, // x = roughness (<0 = default), y = metallic
|
|
32527
32760
|
emissive : vec4<f32>, // rgb = sRGB emissive color, w = strength
|
|
32761
|
+
toonShadow : vec4<f32>, // rgb shadow-side multiplier, w diffuse modelling
|
|
32762
|
+
toonLight : vec4<f32>, // rgb lit-side multiplier, w terminator threshold
|
|
32763
|
+
toonParams : vec4<f32>, // x terminator softness, y outline participation
|
|
32528
32764
|
maps : vec4<f32>, // x = normal scale (0 = no map), y = occlusion strength, z = has metallic-roughness map, w = has emissive map
|
|
32529
32765
|
};
|
|
32530
32766
|
|
|
@@ -32665,37 +32901,6 @@ fn vs_main(
|
|
|
32665
32901
|
return out;
|
|
32666
32902
|
}
|
|
32667
32903
|
|
|
32668
|
-
// Toon (MToon-style): the base color as authored where the light reaches,
|
|
32669
|
-
// the shade color past a soft terminator. Highlights stay out: the texture
|
|
32670
|
-
// already paints them.
|
|
32671
|
-
fn toonLighting(in: VertexOutput, baseColor: vec3<f32>) -> vec3<f32> {
|
|
32672
|
-
var N = normalize(in.worldNormal);
|
|
32673
|
-
let V = normalize(cam.cameraPos.xyz - in.worldPos);
|
|
32674
|
-
if (dot(N, V) < 0.0) {
|
|
32675
|
-
N = -N;
|
|
32676
|
-
}
|
|
32677
|
-
var lit = 0.0;
|
|
32678
|
-
let numLights = i32(lights.params.x);
|
|
32679
|
-
for (var i = 0; i < 8; i++) {
|
|
32680
|
-
if (i >= numLights) {
|
|
32681
|
-
break;
|
|
32682
|
-
}
|
|
32683
|
-
let light = lights.lights[i];
|
|
32684
|
-
let lightType = light.posType.w;
|
|
32685
|
-
var L = vec3<f32>(0.0, 0.0, 1.0);
|
|
32686
|
-
if (lightType > 0.5 && lightType < 1.5) {
|
|
32687
|
-
L = normalize(-light.dirRadius.xyz);
|
|
32688
|
-
} else if (lightType >= 1.5) {
|
|
32689
|
-
L = normalize(light.posType.xyz - in.worldPos);
|
|
32690
|
-
} else {
|
|
32691
|
-
continue;
|
|
32692
|
-
}
|
|
32693
|
-
let terminator = smoothstep(-0.05, 0.2, dot(N, L));
|
|
32694
|
-
lit = max(lit, terminator * min(light.colorIntensity.w, 1.0));
|
|
32695
|
-
}
|
|
32696
|
-
return baseColor * mix(model.shade.rgb, vec3<f32>(1.0), lit);
|
|
32697
|
-
}
|
|
32698
|
-
|
|
32699
32904
|
struct MeshFragment {
|
|
32700
32905
|
color : vec4<f32>, // premultiplied display color
|
|
32701
32906
|
hdr : vec4<f32>, // premultiplied scene radiance (bloom source)
|
|
@@ -32763,7 +32968,7 @@ fn shadeGlass(in: VertexOutput, Nin: vec3<f32>, tint: vec3<f32>, alpha: f32, rim
|
|
|
32763
32968
|
let transmitted = col * depthTint * (1.0 - 0.45 * rim * rim);
|
|
32764
32969
|
let f0 = pow((ior - 1.0) / (ior + 1.0), 2.0);
|
|
32765
32970
|
let F = f0 + (1.0 - f0) * pow(rim, 5.0);
|
|
32766
|
-
let lit = shadeSurfaceFull(in.worldPos, N, vec3<f32>(0.0), model.materialParams, vec4<f32>(model.pbr.x, 0.0, 0.0, 0.0), vec4<f32>(0.0));
|
|
32971
|
+
let lit = shadeSurfaceFull(in.worldPos, N, vec3<f32>(0.0), model.materialParams, vec4<f32>(model.pbr.x, 0.0, 0.0, 0.0), vec4<f32>(0.0), model.toonShadow, model.toonLight, model.toonParams);
|
|
32767
32972
|
// Grazing faces mirror the room; keep that faint so dark scenes stay dark
|
|
32768
32973
|
// and the studio highlights below carry the shape.
|
|
32769
32974
|
let sheen = vec3<f32>(0.9, 0.94, 1.0) * F * 0.22 + tint * 0.05 * (0.4 + rim);
|
|
@@ -32811,19 +33016,6 @@ fn shadeMesh(in: VertexOutput, isFront: bool) -> MeshFragment {
|
|
|
32811
33016
|
|
|
32812
33017
|
let baseRgb = texColor.rgb * in.color.rgb * model.colorTint.rgb;
|
|
32813
33018
|
var out: MeshFragment;
|
|
32814
|
-
if (model.materialParams.w > 1.5) {
|
|
32815
|
-
var toon = baseRgb;
|
|
32816
|
-
if (lights.params.y >= 0.5) {
|
|
32817
|
-
toon = toonLighting(in, baseRgb);
|
|
32818
|
-
}
|
|
32819
|
-
if (model.params.w > 0.5 && (in.emissive.w > 0.0 || dot(in.emissive.rgb, in.emissive.rgb) > 0.0)) {
|
|
32820
|
-
toon += in.emissive.rgb * in.emissive.w;
|
|
32821
|
-
}
|
|
32822
|
-
out.color = vec4<f32>(toon * alpha, alpha);
|
|
32823
|
-
out.hdr = vec4<f32>(srgbToLinear(toon) * alpha, alpha);
|
|
32824
|
-
return out;
|
|
32825
|
-
}
|
|
32826
|
-
|
|
32827
33019
|
var N = normalize(in.worldNormal);
|
|
32828
33020
|
if (model.maps.x > 0.0) {
|
|
32829
33021
|
var tn = normalSample * 2.0 - 1.0;
|
|
@@ -32853,7 +33045,7 @@ fn shadeMesh(in: VertexOutput, isFront: bool) -> MeshFragment {
|
|
|
32853
33045
|
if (model.params.w > 0.5 && (in.emissive.w > 0.0 || dot(in.emissive.rgb, in.emissive.rgb) > 0.0)) {
|
|
32854
33046
|
emissive = in.emissive;
|
|
32855
33047
|
}
|
|
32856
|
-
let shaded = shadeSurfaceFull(in.worldPos, N, baseRgb, material, pbr, emissive);
|
|
33048
|
+
let shaded = shadeSurfaceFull(in.worldPos, N, baseRgb, material, pbr, emissive, model.toonShadow, model.toonLight, model.toonParams);
|
|
32857
33049
|
out.color = vec4<f32>(shaded.display * alpha, alpha);
|
|
32858
33050
|
out.hdr = vec4<f32>(shaded.hdr * alpha, alpha);
|
|
32859
33051
|
return out;
|
|
@@ -32884,7 +33076,7 @@ fn fs_single(in: VertexOutput, @builtin(front_facing) isFront: bool) -> @locatio
|
|
|
32884
33076
|
fn fs_mrt(in: VertexOutput, @builtin(front_facing) isFront: bool) -> MrtOutput {
|
|
32885
33077
|
var out: MrtOutput;
|
|
32886
33078
|
out.color = shadeMesh(in, isFront).color;
|
|
32887
|
-
out.depth =
|
|
33079
|
+
out.depth = geometryPixel(in.linearDepth, in.worldNormal, model.toonParams.y);
|
|
32888
33080
|
return out;
|
|
32889
33081
|
}
|
|
32890
33082
|
|
|
@@ -32902,7 +33094,7 @@ fn fs_mrt_bloom(in: VertexOutput, @builtin(front_facing) isFront: bool) -> MrtBl
|
|
|
32902
33094
|
let f = shadeMesh(in, isFront);
|
|
32903
33095
|
var out: MrtBloomOutput;
|
|
32904
33096
|
out.color = f.color;
|
|
32905
|
-
out.depth =
|
|
33097
|
+
out.depth = geometryPixel(in.linearDepth, in.worldNormal, model.toonParams.y);
|
|
32906
33098
|
out.hdr = f.hdr;
|
|
32907
33099
|
return out;
|
|
32908
33100
|
}
|
|
@@ -32927,6 +33119,9 @@ struct ModelUniforms {
|
|
|
32927
33119
|
materialParams : vec4<f32>, // x = shininess, y = specularIntensity, z = ambientIntensity, w = materialMode (0=unlit, 1=lit)
|
|
32928
33120
|
pbr : vec4<f32>, // x = roughness (<0 = default), y = metallic
|
|
32929
33121
|
emissive : vec4<f32>, // rgb = sRGB emissive color, w = strength
|
|
33122
|
+
toonShadow : vec4<f32>, // rgb shadow-side multiplier, w diffuse modelling
|
|
33123
|
+
toonLight : vec4<f32>, // rgb lit-side multiplier, w terminator threshold
|
|
33124
|
+
toonParams : vec4<f32>, // x terminator softness, y outline participation
|
|
32930
33125
|
relief : vec4<f32>, // x = amount (px), y = on, w = grid cells per side
|
|
32931
33126
|
reliefRect : vec4<f32>, // xy = where the layer's box starts in reliefTex (0..1), zw = its size
|
|
32932
33127
|
reliefEye : vec4<f32>, // xyz = the eye the surface keeps its look from (the default camera)
|
|
@@ -33121,7 +33316,7 @@ fn shadeQuad(in: VertexOutput, isFront: bool) -> QuadFragment {
|
|
|
33121
33316
|
discard;
|
|
33122
33317
|
}
|
|
33123
33318
|
|
|
33124
|
-
let shaded = shadeSurfaceFull(in.worldPos, in.worldNormal, baseRgb, model.materialParams, model.pbr, model.emissive);
|
|
33319
|
+
let shaded = shadeSurfaceFull(in.worldPos, in.worldNormal, baseRgb, model.materialParams, model.pbr, model.emissive, model.toonShadow, model.toonLight, model.toonParams);
|
|
33125
33320
|
var out: QuadFragment;
|
|
33126
33321
|
out.color = vec4<f32>(shaded.display * alpha, alpha);
|
|
33127
33322
|
out.hdr = vec4<f32>(shaded.hdr * alpha, alpha);
|
|
@@ -33153,7 +33348,7 @@ fn fs_single(in: VertexOutput, @builtin(front_facing) isFront: bool) -> @locatio
|
|
|
33153
33348
|
fn fs_mrt(in: VertexOutput, @builtin(front_facing) isFront: bool) -> MrtOutput {
|
|
33154
33349
|
var out: MrtOutput;
|
|
33155
33350
|
out.color = shadeQuad(in, isFront).color;
|
|
33156
|
-
out.depth =
|
|
33351
|
+
out.depth = geometryPixel(in.linearDepth, in.worldNormal, model.toonParams.y);
|
|
33157
33352
|
return out;
|
|
33158
33353
|
}
|
|
33159
33354
|
|
|
@@ -33171,7 +33366,7 @@ fn fs_mrt_bloom(in: VertexOutput, @builtin(front_facing) isFront: bool) -> MrtBl
|
|
|
33171
33366
|
let f = shadeQuad(in, isFront);
|
|
33172
33367
|
var out: MrtBloomOutput;
|
|
33173
33368
|
out.color = f.color;
|
|
33174
|
-
out.depth =
|
|
33369
|
+
out.depth = geometryPixel(in.linearDepth, in.worldNormal, model.toonParams.y);
|
|
33175
33370
|
out.hdr = f.hdr;
|
|
33176
33371
|
return out;
|
|
33177
33372
|
}
|
|
@@ -33197,13 +33392,37 @@ const SHADOW_DEPTH_STENCIL = {
|
|
|
33197
33392
|
depthBiasSlopeScale: 2.5,
|
|
33198
33393
|
depthBiasClamp: .01
|
|
33199
33394
|
};
|
|
33200
|
-
/**
|
|
33201
|
-
const SURFACE_PARAMS_FLOATS =
|
|
33202
|
-
function packSurfaceParams(data, out, offset) {
|
|
33395
|
+
/** Shared model uniforms: PBR, emissive, and three art-direction vec4s. */
|
|
33396
|
+
const SURFACE_PARAMS_FLOATS = 20;
|
|
33397
|
+
function packSurfaceParams(data, out, offset, modelShade) {
|
|
33203
33398
|
out[offset] = data.roughness ?? -1;
|
|
33204
33399
|
out[offset + 1] = data.metallic ?? 0;
|
|
33205
33400
|
out[offset + 2] = 0;
|
|
33206
33401
|
out[offset + 3] = 0;
|
|
33402
|
+
const shadow = data.toon?.shadowColor ? parseColor(data.toon.shadowColor) : null;
|
|
33403
|
+
out.set(shadow ? [
|
|
33404
|
+
shadow.r,
|
|
33405
|
+
shadow.g,
|
|
33406
|
+
shadow.b
|
|
33407
|
+
] : modelShade ?? [
|
|
33408
|
+
.5,
|
|
33409
|
+
.5,
|
|
33410
|
+
.55
|
|
33411
|
+
], offset + 8);
|
|
33412
|
+
out[offset + 11] = data.toon?.diffuse ?? 0;
|
|
33413
|
+
const light = parseColor(data.toon?.lightColor ?? "#ffffff");
|
|
33414
|
+
out.set([
|
|
33415
|
+
light.r,
|
|
33416
|
+
light.g,
|
|
33417
|
+
light.b,
|
|
33418
|
+
data.toon?.threshold ?? .075
|
|
33419
|
+
], offset + 12);
|
|
33420
|
+
out.set([
|
|
33421
|
+
data.toon?.softness ?? .25,
|
|
33422
|
+
data.outline === false ? 0 : 1,
|
|
33423
|
+
0,
|
|
33424
|
+
0
|
|
33425
|
+
], offset + 16);
|
|
33207
33426
|
const e = data.emissive;
|
|
33208
33427
|
if (e === void 0 || e === null) {
|
|
33209
33428
|
out.fill(0, offset + 4, offset + 8);
|
|
@@ -33272,7 +33491,7 @@ function packMaterialParams(data) {
|
|
|
33272
33491
|
data.roughness !== void 0 ? Math.max(1, (1 - data.roughness) * 128) : data.shininess ?? 32,
|
|
33273
33492
|
data.metallic !== void 0 ? data.metallic : data.specularIntensity ?? .5,
|
|
33274
33493
|
data.ambientIntensity ?? 1,
|
|
33275
|
-
data.material === "unlit" ? 0 : 1
|
|
33494
|
+
data.material === "unlit" ? 0 : data.material === "toon" ? 2 : 1
|
|
33276
33495
|
];
|
|
33277
33496
|
}
|
|
33278
33497
|
var Quad3DPipeline = class {
|
|
@@ -34002,12 +34221,13 @@ var Mesh3DPipeline = class {
|
|
|
34002
34221
|
this.modelData[45] = shade[1];
|
|
34003
34222
|
this.modelData[46] = shade[2];
|
|
34004
34223
|
this.modelData[47] = data.alphaCutoff ?? 0;
|
|
34005
|
-
packSurfaceParams(data, this.modelData, 48);
|
|
34224
|
+
packSurfaceParams(data, this.modelData, 48, data.shadeColor);
|
|
34006
34225
|
const maps = data.maps;
|
|
34007
|
-
|
|
34008
|
-
this.modelData[
|
|
34009
|
-
this.modelData[
|
|
34010
|
-
this.modelData[
|
|
34226
|
+
const mapsOffset = 48 + SURFACE_PARAMS_FLOATS;
|
|
34227
|
+
this.modelData[mapsOffset] = maps?.normal ? maps.normalScale ?? 1 : 0;
|
|
34228
|
+
this.modelData[mapsOffset + 1] = maps?.occlusion ? maps.occlusionStrength ?? 1 : 0;
|
|
34229
|
+
this.modelData[mapsOffset + 2] = maps?.metallicRoughness ? 1 : 0;
|
|
34230
|
+
this.modelData[mapsOffset + 3] = maps?.emissive ? 1 : 0;
|
|
34011
34231
|
const glass = data.glass;
|
|
34012
34232
|
if (glass) {
|
|
34013
34233
|
this.modelData[44] = glass.dispersion;
|
|
@@ -37786,6 +38006,309 @@ fn fs_dof(in: VSOut) -> @location(0) vec4<f32> {
|
|
|
37786
38006
|
return accumColor / totalWeight;
|
|
37787
38007
|
}
|
|
37788
38008
|
`;
|
|
38009
|
+
function outlineShader(sampleCount) {
|
|
38010
|
+
const multisampled = sampleCount > 1;
|
|
38011
|
+
const textureType = multisampled ? "texture_multisampled_2d<f32>" : "texture_2d<f32>";
|
|
38012
|
+
return `
|
|
38013
|
+
struct Uniforms {
|
|
38014
|
+
params : vec4<f32>, // width, cosine(crease angle), relative depth threshold, opacity
|
|
38015
|
+
ink : vec4<f32>,
|
|
38016
|
+
fog : vec4<f32>,
|
|
38017
|
+
fogRange : vec4<f32>,
|
|
38018
|
+
projection : vec4<f32>, // inverse projection x/y scale, far depth
|
|
38019
|
+
};
|
|
38020
|
+
@group(0) @binding(0) var<uniform> u : Uniforms;
|
|
38021
|
+
@group(0) @binding(1) var colorTex : ${textureType};
|
|
38022
|
+
@group(0) @binding(2) var geometryTex : ${textureType};
|
|
38023
|
+
|
|
38024
|
+
@vertex fn vs(@builtin(vertex_index) i : u32) -> @builtin(position) vec4<f32> {
|
|
38025
|
+
let p = vec2<f32>(f32((i << 1u) & 2u), f32(i & 2u));
|
|
38026
|
+
return vec4<f32>(p * 2.0 - 1.0, 0.0, 1.0);
|
|
38027
|
+
}
|
|
38028
|
+
|
|
38029
|
+
fn geometry(p : vec2<i32>, sample : i32) -> vec4<f32> {
|
|
38030
|
+
let size = vec2<i32>(textureDimensions(geometryTex));
|
|
38031
|
+
// Beyond the viewport is the same surface: never ink the canvas border.
|
|
38032
|
+
return textureLoad(geometryTex, clamp(p, vec2<i32>(0), size - 1), sample);
|
|
38033
|
+
}
|
|
38034
|
+
|
|
38035
|
+
fn normal(oct : vec2<f32>) -> vec3<f32> {
|
|
38036
|
+
let p = oct * 2.0 - 1.0;
|
|
38037
|
+
var n = vec3<f32>(p, 1.0 - abs(p.x) - abs(p.y));
|
|
38038
|
+
let t = max(-n.z, 0.0);
|
|
38039
|
+
n = vec3<f32>(n.xy + select(vec2<f32>(t), vec2<f32>(-t), n.xy >= vec2<f32>(0.0)), n.z);
|
|
38040
|
+
return normalize(n);
|
|
38041
|
+
}
|
|
38042
|
+
|
|
38043
|
+
fn srgbToLinear(c : vec3<f32>) -> vec3<f32> {
|
|
38044
|
+
return select(pow((max(c, vec3<f32>(0.0)) + 0.055) / 1.055, vec3<f32>(2.4)), c / 12.92, c <= vec3<f32>(0.04045));
|
|
38045
|
+
}
|
|
38046
|
+
fn linearToSrgb(c : vec3<f32>) -> vec3<f32> {
|
|
38047
|
+
let x = max(c, vec3<f32>(0.0));
|
|
38048
|
+
return select(1.055 * pow(x, vec3<f32>(1.0 / 2.4)) - 0.055, x * 12.92, x <= vec3<f32>(0.0031308));
|
|
38049
|
+
}
|
|
38050
|
+
|
|
38051
|
+
fn edge(center : vec4<f32>, next : vec4<f32>, previous : vec4<f32>) -> f32 {
|
|
38052
|
+
let z = 1.0 / max(center.r, 0.0001);
|
|
38053
|
+
let a = 1.0 / max(next.r, 0.0001);
|
|
38054
|
+
let b = 1.0 / max(previous.r, 0.0001);
|
|
38055
|
+
// Inverse depth is affine on a perspective-projected plane. Its signed
|
|
38056
|
+
// second difference suppresses grazing surfaces and inks only the near
|
|
38057
|
+
// side of an occlusion, including thin geometry with background both sides.
|
|
38058
|
+
let curvature = (2.0 * z - a - b) / z;
|
|
38059
|
+
let depthEdge = smoothstep(u.params.z, u.params.z * 2.0, curvature);
|
|
38060
|
+
let sameDepth = abs(center.r - next.r) / max(center.r, 0.0001) < 0.03;
|
|
38061
|
+
let crease = select(0.0, 1.0, next.a > 0.5 && sameDepth && dot(normal(center.gb), normal(next.gb)) < u.params.y);
|
|
38062
|
+
return max(depthEdge, crease);
|
|
38063
|
+
}
|
|
38064
|
+
|
|
38065
|
+
@fragment fn fs(@builtin(position) pos : vec4<f32>${multisampled ? ", @builtin(sample_index) sampleIndex : u32" : ""}) -> @location(0) vec4<f32> {
|
|
38066
|
+
let sample = ${multisampled ? "i32(sampleIndex)" : "0"};
|
|
38067
|
+
let pixel = vec2<i32>(pos.xy);
|
|
38068
|
+
let source = textureLoad(colorTex, pixel, sample);
|
|
38069
|
+
let c = geometry(pixel, sample);
|
|
38070
|
+
if (c.a <= 0.0 || u.params.x <= 0.0 || u.params.w <= 0.0) { return source; }
|
|
38071
|
+
var coverage = 0.0;
|
|
38072
|
+
let directions = array<vec2<f32>, 8>(
|
|
38073
|
+
vec2<f32>(1.0, 0.0), vec2<f32>(-1.0, 0.0), vec2<f32>(0.0, 1.0), vec2<f32>(0.0, -1.0),
|
|
38074
|
+
vec2<f32>(0.707107, 0.707107), vec2<f32>(-0.707107, 0.707107), vec2<f32>(0.707107, -0.707107), vec2<f32>(-0.707107, -0.707107));
|
|
38075
|
+
for (var r = 1; r <= i32(ceil(u.params.x)); r++) {
|
|
38076
|
+
let weight = clamp(u.params.x - f32(r) + 1.0, 0.0, 1.0);
|
|
38077
|
+
for (var d = 0; d < 8; d++) {
|
|
38078
|
+
let offset = vec2<i32>(round(directions[d] * f32(r)));
|
|
38079
|
+
coverage = max(coverage, edge(c, geometry(pixel + offset, sample), geometry(pixel - offset, sample)) * weight);
|
|
38080
|
+
}
|
|
38081
|
+
}
|
|
38082
|
+
var ink = u.ink.rgb;
|
|
38083
|
+
if (u.fog.w > 0.5) {
|
|
38084
|
+
let uv = pos.xy / vec2<f32>(textureDimensions(colorTex));
|
|
38085
|
+
let ray = vec3<f32>((uv * 2.0 - 1.0) * u.projection.xy, 1.0);
|
|
38086
|
+
let distance = c.r * length(ray);
|
|
38087
|
+
let fog = smoothstep(u.fogRange.x, max(u.fogRange.y, u.fogRange.x + 1.0), distance) * u.fogRange.z;
|
|
38088
|
+
// Match surface fog's linear-light blend; display-space interpolation
|
|
38089
|
+
// would darken outlines halfway into a light-colored atmosphere.
|
|
38090
|
+
ink = linearToSrgb(mix(srgbToLinear(ink), srgbToLinear(u.fog.rgb), fog));
|
|
38091
|
+
}
|
|
38092
|
+
let visibleCoverage = min(c.a / max(source.a, 0.0001), 1.0);
|
|
38093
|
+
return vec4<f32>(mix(source.rgb, ink * source.a, coverage * visibleCoverage * u.params.w * u.ink.a), source.a);
|
|
38094
|
+
}
|
|
38095
|
+
`;
|
|
38096
|
+
}
|
|
38097
|
+
/** Ink shades original color/depth/normal samples, then resolves color with MSAA. */
|
|
38098
|
+
var GeometryOutlinePipeline = class {
|
|
38099
|
+
layout;
|
|
38100
|
+
pipeline;
|
|
38101
|
+
multisampledOutput = null;
|
|
38102
|
+
pool = new BufferPool(80, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
|
|
38103
|
+
constructor(device, format, sampleCount = 1) {
|
|
38104
|
+
this.device = device;
|
|
38105
|
+
this.format = format;
|
|
38106
|
+
this.sampleCount = sampleCount;
|
|
38107
|
+
this.layout = device.createBindGroupLayout({
|
|
38108
|
+
label: "GeometryOutlineLayout",
|
|
38109
|
+
entries: [{
|
|
38110
|
+
binding: 0,
|
|
38111
|
+
visibility: GPUShaderStage.FRAGMENT,
|
|
38112
|
+
buffer: { type: "uniform" }
|
|
38113
|
+
}, ...[1, 2].map((binding) => ({
|
|
38114
|
+
binding,
|
|
38115
|
+
visibility: GPUShaderStage.FRAGMENT,
|
|
38116
|
+
texture: {
|
|
38117
|
+
sampleType: "unfilterable-float",
|
|
38118
|
+
multisampled: sampleCount > 1
|
|
38119
|
+
}
|
|
38120
|
+
}))]
|
|
38121
|
+
});
|
|
38122
|
+
const module$1 = device.createShaderModule({
|
|
38123
|
+
label: "geometry-outlines.wgsl",
|
|
38124
|
+
code: outlineShader(sampleCount)
|
|
38125
|
+
});
|
|
38126
|
+
this.pipeline = device.createRenderPipeline({
|
|
38127
|
+
label: "GeometryOutlines",
|
|
38128
|
+
layout: device.createPipelineLayout({ bindGroupLayouts: [this.layout] }),
|
|
38129
|
+
vertex: {
|
|
38130
|
+
module: module$1,
|
|
38131
|
+
entryPoint: "vs"
|
|
38132
|
+
},
|
|
38133
|
+
fragment: {
|
|
38134
|
+
module: module$1,
|
|
38135
|
+
entryPoint: "fs",
|
|
38136
|
+
targets: [{ format }]
|
|
38137
|
+
},
|
|
38138
|
+
primitive: { topology: "triangle-list" },
|
|
38139
|
+
multisample: { count: sampleCount }
|
|
38140
|
+
});
|
|
38141
|
+
}
|
|
38142
|
+
reset() {
|
|
38143
|
+
this.pool.reset();
|
|
38144
|
+
}
|
|
38145
|
+
destroy() {
|
|
38146
|
+
this.pool.destroy();
|
|
38147
|
+
this.multisampledOutput?.destroy();
|
|
38148
|
+
}
|
|
38149
|
+
attachment(source, dest) {
|
|
38150
|
+
if (this.sampleCount <= 1) return {
|
|
38151
|
+
view: dest,
|
|
38152
|
+
loadOp: "clear",
|
|
38153
|
+
storeOp: "store"
|
|
38154
|
+
};
|
|
38155
|
+
if (!this.multisampledOutput || this.multisampledOutput.width !== source.width || this.multisampledOutput.height !== source.height) {
|
|
38156
|
+
this.multisampledOutput?.destroy();
|
|
38157
|
+
this.multisampledOutput = this.device.createTexture({
|
|
38158
|
+
label: "GeometryOutlineMsaaOutput",
|
|
38159
|
+
size: {
|
|
38160
|
+
width: source.width,
|
|
38161
|
+
height: source.height
|
|
38162
|
+
},
|
|
38163
|
+
format: this.format,
|
|
38164
|
+
sampleCount: this.sampleCount,
|
|
38165
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
38166
|
+
});
|
|
38167
|
+
}
|
|
38168
|
+
return {
|
|
38169
|
+
view: this.multisampledOutput.createView(),
|
|
38170
|
+
resolveTarget: dest,
|
|
38171
|
+
loadOp: "clear",
|
|
38172
|
+
storeOp: "discard"
|
|
38173
|
+
};
|
|
38174
|
+
}
|
|
38175
|
+
render(encoder, source, geometry, dest, camera, options, fog) {
|
|
38176
|
+
const data = new Float32Array(20);
|
|
38177
|
+
data.set([
|
|
38178
|
+
(options.width ?? 1.5) * source.height / (options.referenceHeight ?? 1080),
|
|
38179
|
+
Math.cos((options.creaseAngle ?? 45) * Math.PI / 180),
|
|
38180
|
+
options.depthThreshold ?? .01,
|
|
38181
|
+
options.opacity ?? 1
|
|
38182
|
+
]);
|
|
38183
|
+
const color = parseColor(options.color ?? "#16131c");
|
|
38184
|
+
data.set([
|
|
38185
|
+
color.r,
|
|
38186
|
+
color.g,
|
|
38187
|
+
color.b,
|
|
38188
|
+
color.a
|
|
38189
|
+
], 4);
|
|
38190
|
+
if (fog) {
|
|
38191
|
+
const tint = parseColor(fog.color);
|
|
38192
|
+
data.set([
|
|
38193
|
+
tint.r,
|
|
38194
|
+
tint.g,
|
|
38195
|
+
tint.b,
|
|
38196
|
+
1
|
|
38197
|
+
], 8);
|
|
38198
|
+
data.set([
|
|
38199
|
+
fog.start,
|
|
38200
|
+
fog.end,
|
|
38201
|
+
fog.opacity ?? 1,
|
|
38202
|
+
0
|
|
38203
|
+
], 12);
|
|
38204
|
+
}
|
|
38205
|
+
const projection = Camera3D.computeProjectionMatrix(camera);
|
|
38206
|
+
data.set([
|
|
38207
|
+
1 / projection[0],
|
|
38208
|
+
1 / projection[5],
|
|
38209
|
+
camera.far,
|
|
38210
|
+
0
|
|
38211
|
+
], 16);
|
|
38212
|
+
const bindGroup = this.device.createBindGroup({
|
|
38213
|
+
layout: this.layout,
|
|
38214
|
+
entries: [
|
|
38215
|
+
{
|
|
38216
|
+
binding: 0,
|
|
38217
|
+
resource: { buffer: this.pool.getBuffer(this.device, data) }
|
|
38218
|
+
},
|
|
38219
|
+
{
|
|
38220
|
+
binding: 1,
|
|
38221
|
+
resource: source.createView()
|
|
38222
|
+
},
|
|
38223
|
+
{
|
|
38224
|
+
binding: 2,
|
|
38225
|
+
resource: geometry.createView()
|
|
38226
|
+
}
|
|
38227
|
+
]
|
|
38228
|
+
});
|
|
38229
|
+
const pass = encoder.beginRenderPass({ colorAttachments: [this.attachment(source, dest)] });
|
|
38230
|
+
pass.setPipeline(this.pipeline);
|
|
38231
|
+
pass.setBindGroup(0, bindGroup);
|
|
38232
|
+
pass.draw(3);
|
|
38233
|
+
pass.end();
|
|
38234
|
+
}
|
|
38235
|
+
};
|
|
38236
|
+
/**
|
|
38237
|
+
* Color MSAA resolves average samples. Depth and octahedral normals cannot
|
|
38238
|
+
* be averaged across silhouettes: that invents a distant surface and a
|
|
38239
|
+
* normal that belongs to neither object. Keep the nearest visible sample
|
|
38240
|
+
* and carry outline coverage separately, without re-rendering geometry.
|
|
38241
|
+
*/
|
|
38242
|
+
const shader = `
|
|
38243
|
+
@group(0) @binding(0) var geometry : texture_multisampled_2d<f32>;
|
|
38244
|
+
@vertex fn vs(@builtin(vertex_index) i : u32) -> @builtin(position) vec4<f32> {
|
|
38245
|
+
let p = vec2<f32>(f32((i << 1u) & 2u), f32(i & 2u));
|
|
38246
|
+
return vec4<f32>(p * 2.0 - 1.0, 0.0, 1.0);
|
|
38247
|
+
}
|
|
38248
|
+
@fragment fn fs(@builtin(position) pos : vec4<f32>) -> @location(0) vec4<f32> {
|
|
38249
|
+
let pixel = vec2<i32>(pos.xy);
|
|
38250
|
+
let samples = i32(textureNumSamples(geometry));
|
|
38251
|
+
var nearest = textureLoad(geometry, pixel, 0);
|
|
38252
|
+
var coverage = 0.0;
|
|
38253
|
+
for (var i = 0; i < samples; i++) {
|
|
38254
|
+
let s = textureLoad(geometry, pixel, i);
|
|
38255
|
+
if (s.r < nearest.r) { nearest = s; }
|
|
38256
|
+
coverage += s.a;
|
|
38257
|
+
}
|
|
38258
|
+
return vec4<f32>(nearest.rgb, nearest.a * coverage / f32(samples));
|
|
38259
|
+
}
|
|
38260
|
+
`;
|
|
38261
|
+
var GeometryResolvePipeline = class {
|
|
38262
|
+
layout;
|
|
38263
|
+
pipeline;
|
|
38264
|
+
constructor(device) {
|
|
38265
|
+
this.device = device;
|
|
38266
|
+
this.layout = device.createBindGroupLayout({ entries: [{
|
|
38267
|
+
binding: 0,
|
|
38268
|
+
visibility: GPUShaderStage.FRAGMENT,
|
|
38269
|
+
texture: {
|
|
38270
|
+
sampleType: "unfilterable-float",
|
|
38271
|
+
multisampled: true
|
|
38272
|
+
}
|
|
38273
|
+
}] });
|
|
38274
|
+
const module$1 = device.createShaderModule({
|
|
38275
|
+
label: "geometry-resolve.wgsl",
|
|
38276
|
+
code: shader
|
|
38277
|
+
});
|
|
38278
|
+
this.pipeline = device.createRenderPipeline({
|
|
38279
|
+
label: "GeometryResolve",
|
|
38280
|
+
layout: device.createPipelineLayout({ bindGroupLayouts: [this.layout] }),
|
|
38281
|
+
vertex: {
|
|
38282
|
+
module: module$1,
|
|
38283
|
+
entryPoint: "vs"
|
|
38284
|
+
},
|
|
38285
|
+
fragment: {
|
|
38286
|
+
module: module$1,
|
|
38287
|
+
entryPoint: "fs",
|
|
38288
|
+
targets: [{ format: "rgba16float" }]
|
|
38289
|
+
},
|
|
38290
|
+
primitive: { topology: "triangle-list" }
|
|
38291
|
+
});
|
|
38292
|
+
}
|
|
38293
|
+
render(encoder, source, dest) {
|
|
38294
|
+
const bindGroup = this.device.createBindGroup({
|
|
38295
|
+
layout: this.layout,
|
|
38296
|
+
entries: [{
|
|
38297
|
+
binding: 0,
|
|
38298
|
+
resource: source.createView()
|
|
38299
|
+
}]
|
|
38300
|
+
});
|
|
38301
|
+
const pass = encoder.beginRenderPass({ colorAttachments: [{
|
|
38302
|
+
view: dest,
|
|
38303
|
+
loadOp: "clear",
|
|
38304
|
+
storeOp: "store"
|
|
38305
|
+
}] });
|
|
38306
|
+
pass.setPipeline(this.pipeline);
|
|
38307
|
+
pass.setBindGroup(0, bindGroup);
|
|
38308
|
+
pass.draw(3);
|
|
38309
|
+
pass.end();
|
|
38310
|
+
}
|
|
38311
|
+
};
|
|
37789
38312
|
function isKtx2(bytes) {
|
|
37790
38313
|
return bytes.length >= KTX2_IDENTIFIER.length && KTX2_IDENTIFIER.every((byte, i) => bytes[i] === byte);
|
|
37791
38314
|
}
|
|
@@ -38150,6 +38673,9 @@ struct TextModelUniforms {
|
|
|
38150
38673
|
materialParams : vec4<f32>, // x = shininess, y = specularIntensity, z = ambientIntensity, w = materialMode (0=unlit, 1=lit)
|
|
38151
38674
|
pbr : vec4<f32>, // x = roughness (<0 = default), y = metallic
|
|
38152
38675
|
emissive : vec4<f32>, // rgb = sRGB emissive color, w = strength
|
|
38676
|
+
toonShadow : vec4<f32>, // rgb shadow-side multiplier, w diffuse modelling
|
|
38677
|
+
toonLight : vec4<f32>, // rgb lit-side multiplier, w terminator threshold
|
|
38678
|
+
toonParams : vec4<f32>, // x terminator softness, y outline participation
|
|
38153
38679
|
};
|
|
38154
38680
|
|
|
38155
38681
|
@group(0) @binding(0) var<uniform> cam : CameraUniforms;
|
|
@@ -38282,7 +38808,7 @@ fn shadeText(in : VSOut, fw : vec2<f32>) -> TextFragment {
|
|
|
38282
38808
|
if (shaded.a < 0.0001) {
|
|
38283
38809
|
return out;
|
|
38284
38810
|
}
|
|
38285
|
-
let lit = shadeSurfaceFull(in.worldPos, in.worldNormal, shaded.rgb / shaded.a, model.materialParams, model.pbr, model.emissive);
|
|
38811
|
+
let lit = shadeSurfaceFull(in.worldPos, in.worldNormal, shaded.rgb / shaded.a, model.materialParams, model.pbr, model.emissive, model.toonShadow, model.toonLight, model.toonParams);
|
|
38286
38812
|
out.color = vec4<f32>(lit.display * shaded.a, shaded.a);
|
|
38287
38813
|
out.hdr = vec4<f32>(lit.hdr * shaded.a, shaded.a);
|
|
38288
38814
|
return out;
|
|
@@ -38323,7 +38849,7 @@ struct MrtBloomOutput {
|
|
|
38323
38849
|
@fragment fn fs_mrt(in : VSOut) -> MrtOutput {
|
|
38324
38850
|
var out : MrtOutput;
|
|
38325
38851
|
out.color = textFragment(in).color;
|
|
38326
|
-
out.depth =
|
|
38852
|
+
out.depth = geometryPixel(in.linearDepth, in.worldNormal, model.toonParams.y);
|
|
38327
38853
|
return out;
|
|
38328
38854
|
}
|
|
38329
38855
|
|
|
@@ -38339,7 +38865,7 @@ struct MrtBloomOutput {
|
|
|
38339
38865
|
let f = textFragment(in);
|
|
38340
38866
|
var out : MrtBloomOutput;
|
|
38341
38867
|
out.color = f.color;
|
|
38342
|
-
out.depth =
|
|
38868
|
+
out.depth = geometryPixel(in.linearDepth, in.worldNormal, model.toonParams.y);
|
|
38343
38869
|
out.hdr = f.hdr;
|
|
38344
38870
|
return out;
|
|
38345
38871
|
}
|
|
@@ -39403,6 +39929,8 @@ var Renderer3D = class {
|
|
|
39403
39929
|
shadowSampler = null;
|
|
39404
39930
|
meshBounds = /* @__PURE__ */ new WeakMap();
|
|
39405
39931
|
bloomPipeline = null;
|
|
39932
|
+
outlinePipeline = null;
|
|
39933
|
+
geometryResolvePipeline = null;
|
|
39406
39934
|
lastCameraBuffer = null;
|
|
39407
39935
|
/**
|
|
39408
39936
|
* Samples per pixel in the 3D pass. Mesh silhouettes (extruded text,
|
|
@@ -39469,7 +39997,39 @@ var Renderer3D = class {
|
|
|
39469
39997
|
primitive: { topology: "triangle-list" }
|
|
39470
39998
|
});
|
|
39471
39999
|
}
|
|
40000
|
+
/**
|
|
40001
|
+
* Size-dependent render targets, by label, size, samples and usage. One
|
|
40002
|
+
* frame (one command buffer) can render 3D scenes of different sizes, so
|
|
40003
|
+
* a target is never destroyed while the frame may use it: targets the last
|
|
40004
|
+
* frame did not use are destroyed at the next `resetPools`.
|
|
40005
|
+
*/
|
|
40006
|
+
attachments = /* @__PURE__ */ new Map();
|
|
40007
|
+
attachmentsUsed = /* @__PURE__ */ new Set();
|
|
40008
|
+
attachment(label, width, height, desc) {
|
|
40009
|
+
const key = `${label}:${width}x${height}:${desc.sampleCount ?? 1}:${desc.usage}`;
|
|
40010
|
+
this.attachmentsUsed.add(key);
|
|
40011
|
+
let texture = this.attachments.get(key);
|
|
40012
|
+
if (!texture) {
|
|
40013
|
+
texture = this.device.createTexture({
|
|
40014
|
+
label,
|
|
40015
|
+
size: {
|
|
40016
|
+
width,
|
|
40017
|
+
height
|
|
40018
|
+
},
|
|
40019
|
+
...desc
|
|
40020
|
+
});
|
|
40021
|
+
this.attachments.set(key, texture);
|
|
40022
|
+
}
|
|
40023
|
+
return texture;
|
|
40024
|
+
}
|
|
39472
40025
|
resetPools() {
|
|
40026
|
+
for (const [key, texture] of this.attachments) {
|
|
40027
|
+
if (this.attachmentsUsed.has(key)) continue;
|
|
40028
|
+
texture.destroy();
|
|
40029
|
+
this.attachments.delete(key);
|
|
40030
|
+
}
|
|
40031
|
+
this.attachmentsUsed.clear();
|
|
40032
|
+
this.outlinePipeline?.reset();
|
|
39473
40033
|
this.bloomPipeline?.resetPools();
|
|
39474
40034
|
this.cameraPool.reset();
|
|
39475
40035
|
this.lastCameraPose = null;
|
|
@@ -39484,33 +40044,18 @@ var Renderer3D = class {
|
|
|
39484
40044
|
this.morphPipeline.resetPools();
|
|
39485
40045
|
}
|
|
39486
40046
|
getOrCreateDepthTexture(width, height) {
|
|
39487
|
-
|
|
39488
|
-
|
|
39489
|
-
|
|
39490
|
-
|
|
39491
|
-
|
|
39492
|
-
width,
|
|
39493
|
-
height
|
|
39494
|
-
},
|
|
39495
|
-
format: "depth24plus",
|
|
39496
|
-
sampleCount: this.sampleCount,
|
|
39497
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
39498
|
-
});
|
|
39499
|
-
}
|
|
40047
|
+
this.depthTexture = this.attachment("Renderer3DDepthTexture", width, height, {
|
|
40048
|
+
format: "depth24plus",
|
|
40049
|
+
sampleCount: this.sampleCount,
|
|
40050
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
40051
|
+
});
|
|
39500
40052
|
return this.depthTexture;
|
|
39501
40053
|
}
|
|
39502
|
-
getOrCreateMsaaTexture(
|
|
39503
|
-
|
|
39504
|
-
current?.destroy();
|
|
39505
|
-
return this.device.createTexture({
|
|
39506
|
-
label,
|
|
39507
|
-
size: {
|
|
39508
|
-
width,
|
|
39509
|
-
height
|
|
39510
|
-
},
|
|
40054
|
+
getOrCreateMsaaTexture(_current, label, format, width, height, sampled = false) {
|
|
40055
|
+
return this.attachment(label, width, height, {
|
|
39511
40056
|
format,
|
|
39512
40057
|
sampleCount: this.sampleCount,
|
|
39513
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
40058
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | (sampled ? GPUTextureUsage.TEXTURE_BINDING : 0)
|
|
39514
40059
|
});
|
|
39515
40060
|
}
|
|
39516
40061
|
/** The HDR radiance target the last `beginPass(…, writeHdr)` drew into. */
|
|
@@ -39518,110 +40063,54 @@ var Renderer3D = class {
|
|
|
39518
40063
|
return this.hdrTexture;
|
|
39519
40064
|
}
|
|
39520
40065
|
getOrCreateHdrTexture(width, height) {
|
|
39521
|
-
|
|
39522
|
-
|
|
39523
|
-
|
|
39524
|
-
|
|
39525
|
-
size: {
|
|
39526
|
-
width,
|
|
39527
|
-
height
|
|
39528
|
-
},
|
|
39529
|
-
format: "rgba16float",
|
|
39530
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
39531
|
-
});
|
|
39532
|
-
}
|
|
40066
|
+
this.hdrTexture = this.attachment("Renderer3DHdrRadiance", width, height, {
|
|
40067
|
+
format: "rgba16float",
|
|
40068
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
40069
|
+
});
|
|
39533
40070
|
return this.hdrTexture;
|
|
39534
40071
|
}
|
|
39535
40072
|
getOrCreateLinearDepthTexture(width, height) {
|
|
39536
|
-
|
|
39537
|
-
|
|
39538
|
-
|
|
39539
|
-
|
|
39540
|
-
size: {
|
|
39541
|
-
width,
|
|
39542
|
-
height
|
|
39543
|
-
},
|
|
39544
|
-
format: "rgba16float",
|
|
39545
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
39546
|
-
});
|
|
39547
|
-
}
|
|
40073
|
+
this.linearDepthTexture = this.attachment("Renderer3DLinearDepthTexture", width, height, {
|
|
40074
|
+
format: "rgba16float",
|
|
40075
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
40076
|
+
});
|
|
39548
40077
|
return this.linearDepthTexture;
|
|
39549
40078
|
}
|
|
39550
40079
|
getOrCreateReflectionTexture(width, height) {
|
|
39551
|
-
|
|
39552
|
-
this.
|
|
39553
|
-
|
|
39554
|
-
|
|
39555
|
-
size: {
|
|
39556
|
-
width,
|
|
39557
|
-
height
|
|
39558
|
-
},
|
|
39559
|
-
format: this.format,
|
|
39560
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
39561
|
-
});
|
|
39562
|
-
}
|
|
40080
|
+
this.reflectionColorTexture = this.attachment("Renderer3DReflectionColor", width, height, {
|
|
40081
|
+
format: this.format,
|
|
40082
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
40083
|
+
});
|
|
39563
40084
|
return this.reflectionColorTexture;
|
|
39564
40085
|
}
|
|
39565
40086
|
getOrCreateReflectionMsaaTexture(width, height) {
|
|
39566
|
-
|
|
39567
|
-
this.
|
|
39568
|
-
|
|
39569
|
-
|
|
39570
|
-
|
|
39571
|
-
width,
|
|
39572
|
-
height
|
|
39573
|
-
},
|
|
39574
|
-
format: this.format,
|
|
39575
|
-
sampleCount: this.sampleCount,
|
|
39576
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
39577
|
-
});
|
|
39578
|
-
}
|
|
40087
|
+
this.reflectionMsaaColorTexture = this.attachment("Renderer3DReflectionMsaaColor", width, height, {
|
|
40088
|
+
format: this.format,
|
|
40089
|
+
sampleCount: this.sampleCount,
|
|
40090
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
40091
|
+
});
|
|
39579
40092
|
return this.reflectionMsaaColorTexture;
|
|
39580
40093
|
}
|
|
39581
40094
|
getOrCreateReflectionDepthTexture(width, height) {
|
|
39582
|
-
|
|
39583
|
-
|
|
39584
|
-
|
|
39585
|
-
|
|
39586
|
-
|
|
39587
|
-
width,
|
|
39588
|
-
height
|
|
39589
|
-
},
|
|
39590
|
-
format: "depth24plus",
|
|
39591
|
-
sampleCount: this.sampleCount,
|
|
39592
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
39593
|
-
});
|
|
39594
|
-
}
|
|
40095
|
+
this.reflectionDepthTexture = this.attachment("Renderer3DReflectionDepth", width, height, {
|
|
40096
|
+
format: "depth24plus",
|
|
40097
|
+
sampleCount: this.sampleCount,
|
|
40098
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
40099
|
+
});
|
|
39595
40100
|
return this.reflectionDepthTexture;
|
|
39596
40101
|
}
|
|
39597
40102
|
getOrCreateReflectionTempTexture(width, height) {
|
|
39598
|
-
|
|
39599
|
-
this.
|
|
39600
|
-
|
|
39601
|
-
|
|
39602
|
-
size: {
|
|
39603
|
-
width,
|
|
39604
|
-
height
|
|
39605
|
-
},
|
|
39606
|
-
format: this.format,
|
|
39607
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
39608
|
-
});
|
|
39609
|
-
}
|
|
40103
|
+
this.reflectionTempTexture = this.attachment("Renderer3DReflectionTemp", width, height, {
|
|
40104
|
+
format: this.format,
|
|
40105
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
40106
|
+
});
|
|
39610
40107
|
return this.reflectionTempTexture;
|
|
39611
40108
|
}
|
|
39612
40109
|
getOrCreateReflectionBlurredTexture(width, height) {
|
|
39613
|
-
|
|
39614
|
-
this.
|
|
39615
|
-
|
|
39616
|
-
|
|
39617
|
-
size: {
|
|
39618
|
-
width,
|
|
39619
|
-
height
|
|
39620
|
-
},
|
|
39621
|
-
format: this.format,
|
|
39622
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
39623
|
-
});
|
|
39624
|
-
}
|
|
40110
|
+
this.reflectionBlurredTexture = this.attachment("Renderer3DReflectionBlurred", width, height, {
|
|
40111
|
+
format: this.format,
|
|
40112
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
|
|
40113
|
+
});
|
|
39625
40114
|
return this.reflectionBlurredTexture;
|
|
39626
40115
|
}
|
|
39627
40116
|
packCameraUniforms(camera, surfaceWidth, surfaceHeight, time$2 = 0) {
|
|
@@ -39903,16 +40392,22 @@ var Renderer3D = class {
|
|
|
39903
40392
|
storeOp: "store",
|
|
39904
40393
|
clearValue
|
|
39905
40394
|
};
|
|
39906
|
-
if (msaa) this.msaaColorTexture = this.getOrCreateMsaaTexture(this.msaaColorTexture, "Renderer3DMsaaColor", this.format, surfaceWidth, surfaceHeight);
|
|
40395
|
+
if (msaa) this.msaaColorTexture = this.getOrCreateMsaaTexture(this.msaaColorTexture, "Renderer3DMsaaColor", this.format, surfaceWidth, surfaceHeight, Boolean(world?.environment?.outlines));
|
|
39907
40396
|
const colorAttachments = [attach(colorTargetView, msaa ? this.msaaColorTexture : null, clearColor, loadOp)];
|
|
40397
|
+
if (msaa && world?.environment?.outlines) colorAttachments[0].storeOp = "store";
|
|
39908
40398
|
if (linearDepthTargetView) {
|
|
39909
|
-
if (msaa) this.msaaLinearDepthTexture = this.getOrCreateMsaaTexture(this.msaaLinearDepthTexture, "Renderer3DMsaaLinearDepth", "rgba16float", surfaceWidth, surfaceHeight);
|
|
39910
|
-
|
|
39911
|
-
r: camera.far,
|
|
39912
|
-
g:
|
|
39913
|
-
b:
|
|
39914
|
-
a:
|
|
39915
|
-
}, "clear")
|
|
40399
|
+
if (msaa) this.msaaLinearDepthTexture = this.getOrCreateMsaaTexture(this.msaaLinearDepthTexture, "Renderer3DMsaaLinearDepth", "rgba16float", surfaceWidth, surfaceHeight, true);
|
|
40400
|
+
const geometryAttachment = attach(linearDepthTargetView, msaa ? this.msaaLinearDepthTexture : null, {
|
|
40401
|
+
r: Math.min(camera.far, 65504),
|
|
40402
|
+
g: .5,
|
|
40403
|
+
b: .5,
|
|
40404
|
+
a: 0
|
|
40405
|
+
}, "clear");
|
|
40406
|
+
if (msaa && world?.environment?.outlines) {
|
|
40407
|
+
geometryAttachment.resolveTarget = void 0;
|
|
40408
|
+
geometryAttachment.storeOp = "store";
|
|
40409
|
+
}
|
|
40410
|
+
colorAttachments.push(geometryAttachment);
|
|
39916
40411
|
}
|
|
39917
40412
|
this.passWritesHdr = writeHdr;
|
|
39918
40413
|
if (writeHdr) {
|
|
@@ -40003,8 +40498,9 @@ var Renderer3D = class {
|
|
|
40003
40498
|
this.floorReflectionPipeline.draw(pass, cameraBindGroup, lightsBindGroup, reflectionTexture, floor, useMrt, useBloom);
|
|
40004
40499
|
}
|
|
40005
40500
|
/**
|
|
40006
|
-
* A
|
|
40007
|
-
*
|
|
40501
|
+
* A centered unit quad in world space. Translate to the authored pivot,
|
|
40502
|
+
* rotate and scale, then offset the unit quad back from that pivot.
|
|
40503
|
+
* Shared with children in preserve-3d containers.
|
|
40008
40504
|
*/
|
|
40009
40505
|
quadModelMatrix(opts) {
|
|
40010
40506
|
if (opts.modelMatrix) return opts.modelMatrix;
|
|
@@ -40018,7 +40514,7 @@ var Renderer3D = class {
|
|
|
40018
40514
|
1
|
|
40019
40515
|
], anchor = [.5, .5] } = opts;
|
|
40020
40516
|
let m = Matrix4Math.identity();
|
|
40021
|
-
m = Matrix4Math.multiply(m, Matrix4Math.translate(position[0], position[1], position[2]));
|
|
40517
|
+
m = Matrix4Math.multiply(m, Matrix4Math.translate(position[0] + (anchor[0] - .5) * width, position[1] + (anchor[1] - .5) * height, position[2]));
|
|
40022
40518
|
const rxRad = rotation[0] * Math.PI / 180;
|
|
40023
40519
|
const ryRad = rotation[1] * Math.PI / 180;
|
|
40024
40520
|
const rzRad = rotation[2] * Math.PI / 180;
|
|
@@ -40083,6 +40579,8 @@ var Renderer3D = class {
|
|
|
40083
40579
|
metallic: opts.metallic,
|
|
40084
40580
|
emissive: opts.emissive,
|
|
40085
40581
|
emissiveIntensity: opts.emissiveIntensity,
|
|
40582
|
+
toon: opts.toon,
|
|
40583
|
+
outline: opts.outline,
|
|
40086
40584
|
matte: opts.matte
|
|
40087
40585
|
}, useMrt, this.passWritesHdr);
|
|
40088
40586
|
}
|
|
@@ -40128,6 +40626,8 @@ var Renderer3D = class {
|
|
|
40128
40626
|
metallic,
|
|
40129
40627
|
emissive: opts.emissive,
|
|
40130
40628
|
emissiveIntensity: opts.emissiveIntensity,
|
|
40629
|
+
toon: opts.toon,
|
|
40630
|
+
outline: opts.outline,
|
|
40131
40631
|
matte: opts.matte,
|
|
40132
40632
|
relief: opts.relief
|
|
40133
40633
|
}, useMrt, this.passWritesHdr);
|
|
@@ -40371,6 +40871,8 @@ var Renderer3D = class {
|
|
|
40371
40871
|
metallic,
|
|
40372
40872
|
emissive: opts.emissive,
|
|
40373
40873
|
emissiveIntensity: opts.emissiveIntensity,
|
|
40874
|
+
toon: opts.toon,
|
|
40875
|
+
outline: opts.outline,
|
|
40374
40876
|
matte: opts.matte,
|
|
40375
40877
|
maps: opts.maps,
|
|
40376
40878
|
isInstanced: Boolean(opts.instanceBuffer || opts.instanceCount && opts.instanceCount > 1),
|
|
@@ -40525,6 +41027,23 @@ var Renderer3D = class {
|
|
|
40525
41027
|
this.bloomPipeline ??= new BloomPipeline(this.device);
|
|
40526
41028
|
this.bloomPipeline.apply(encoder, source, dest, options, hdrSource ?? void 0);
|
|
40527
41029
|
}
|
|
41030
|
+
/** Geometry ink is applied before lens blur, independently of material shading. */
|
|
41031
|
+
resolveGeometry(encoder, geometry) {
|
|
41032
|
+
if (this.sampleCount <= 1 || !this.msaaLinearDepthTexture) return;
|
|
41033
|
+
this.geometryResolvePipeline ??= new GeometryResolvePipeline(this.device);
|
|
41034
|
+
this.geometryResolvePipeline.render(encoder, this.msaaLinearDepthTexture, geometry.createView());
|
|
41035
|
+
}
|
|
41036
|
+
applyOutlines(encoder, source, geometry, dest, camera, options, fog) {
|
|
41037
|
+
let colorSource = source;
|
|
41038
|
+
let geometrySource = geometry;
|
|
41039
|
+
if (this.sampleCount > 1) {
|
|
41040
|
+
if (!this.msaaColorTexture || !this.msaaLinearDepthTexture) throw new Error("Geometry outlines require the scene's retained MSAA color and geometry samples");
|
|
41041
|
+
colorSource = this.msaaColorTexture;
|
|
41042
|
+
geometrySource = this.msaaLinearDepthTexture;
|
|
41043
|
+
}
|
|
41044
|
+
this.outlinePipeline ??= new GeometryOutlinePipeline(this.device, this.format, this.sampleCount);
|
|
41045
|
+
this.outlinePipeline.render(encoder, colorSource, geometrySource, dest, camera, options, fog);
|
|
41046
|
+
}
|
|
40528
41047
|
applyDepthOfField(encoder, sourceColorTex, depthTex, destView, cameraBuffer) {
|
|
40529
41048
|
const sampler = this.samplerCache.getSampler(this.device);
|
|
40530
41049
|
const bindGroup = this.device.createBindGroup({
|
|
@@ -40577,7 +41096,10 @@ var Renderer3D = class {
|
|
|
40577
41096
|
}, useMrt);
|
|
40578
41097
|
}
|
|
40579
41098
|
destroy() {
|
|
41099
|
+
for (const texture of this.attachments.values()) texture.destroy();
|
|
41100
|
+
this.attachments.clear();
|
|
40580
41101
|
this.bloomPipeline?.destroy();
|
|
41102
|
+
this.outlinePipeline?.destroy();
|
|
40581
41103
|
this.depthTexture?.destroy();
|
|
40582
41104
|
for (const texture of this.shadowTextures.values()) texture.destroy();
|
|
40583
41105
|
this.shadowTextures.clear();
|
|
@@ -41608,5 +42130,5 @@ var NodeSurfaceProvider = class {
|
|
|
41608
42130
|
if (typeof globalThis !== "undefined") globalThis.__GATEWAI_DELAYS__ = globalThis.__GATEWAI_DELAYS__ || /* @__PURE__ */ new Set();
|
|
41609
42131
|
|
|
41610
42132
|
//#endregion
|
|
41611
|
-
export {
|
|
41612
|
-
//# sourceMappingURL=dist
|
|
42133
|
+
export { poseNodes as $, TextAnchorConfigSchema as $t, emojiGraphemes as A, evaluateSkewMatrix as An, AnimatableGlyphPropsSchema as At, jointMatrices as B, sampleCurveGeometry as Bn, GlyphAnchorPointSchema as Bt, drawGifNode as C, distanceToCurveParameter as Cn, parseColorToRgb as Ct, drawSignalNode as D, evaluateExpressionSelector as Dn, AdvancedTextAnimatorSchema as Dt, drawParagraphNode as E, evaluateCubicBezierDerivative as En, AdvancedTextAnimatorBuilder as Et, getPrimitiveGeometry as F, generatePathSegments as Fn, DynamicStrokePropertiesSchema as Ft, measureMaxCaptionHeight as G, SelectorBasedOnSchema as Gt, loadModel3D as H, signalRegistry as Hn, LineSpacingDynamicsSchema as Ht, getRegisteredFontSource as I, getScramblePool as In, EnhancedTextNodeSchema as It, parseDashArray as J, SelectorUnitsSchema as Jt, mediaDecoderCache as K, SelectorModeSchema as Kt, getRenderer2D as L, getShuffledOrder as Ln, ExpressionSelectorSchema as Lt, fitSpansToText as M, evaluateTypewriterState as Mn, AudioSpectrumTypographySchema as Mt, generateExtrudedTextGeometry as N, evaluateVolumetricFormation as Nn, ChromaticGlitchConfigSchema as Nt, drawSvgNode as O, evaluateMarqueeOffset as On, AnchorGroupingSchema as Ot, getHeadlessFontPath as P, generateArcLengthLUT as Pn, CubicBezierSegmentSchema as Pt, parseSvgPathToSegments as Q, SpringPhysicsSchema as Qt, initHeadlessWebGPU as R, parseSvgPathToCubicBeziers as Rn, ExtendedGlyphPropertiesSchema as Rt, drawCaptionNode as S, deterministicWigglyNoise as Sn, linearRgb as St, drawLottieNode as T, evaluateCubicBezier as Tn, AETextAnimatorSchema as Tt, loadOBJ as U, waveToCubicBeziers as Un, LongShadowConfigSchema as Ut, loadFBX as V, samplePathChainGeometry as Vn, KineticMarqueeConfigSchema as Vt, lutStore as W, ParticleDissolveConfigSchema as Wt, parseMTL as X, SkewPropertiesSchema as Xt, parseFBX as Y, SignalRegistry as Yt, parseOBJ as Z, Spatial3DPropertiesSchema as Zt, buildShapeSvgPath as _, buildPathLUT as _n, Light3D as _t, GlassPipeline as a, TextPathSourceSchema as an, setRegisteredFontSource as at, colorMatrixWgsl as b, computeLineLeadingDisplacement as bn, Path3D as bt, Renderer2D as c, TextSelectorSchema as cn, srtLoader as ct, ScreenSpaceRelightPipeline as d, TypewriterAnimatorSchema as dn, transformScale as dt, TextAnimatorBuilder as en, probeVideoSize as et, ShadowPipeline as f, TypingCadenceSchema as fn, GetFontAssetUrl as ft, WebGPUAudioProcessor as g, VolumetricFormationModeSchema as gn, LIGHT_UNIFORM_SIZE_BYTES as gt, SlugPipeline as h, VolumetricFormationConfigSchema as hn, ENVIRONMENT_PRESETS as ht, EffectPipeline as i, TextPathOptionsSchema as in, sampleMorphWeights as it, ensureDevice as j, evaluateSpringProgress as jn, AudioSignalComputePipeline as jt, drawVideoNode as k, evaluateSelectorCombination as kn, AnchorPresetSchema as kt, Renderer3D as l, TextSignalSelectorSchema as ln, textureCache as lt, SlugGeometry as m, Vec2Schema as mn, Camera3D as mt, AudioLatentTrackCache as n, TextCursorStyleSchema as nn, resolveInputUrl as nt, MotionBlurPipeline as o, TextRangeSelectorSchema as on, shaderStore as ot, SlugFontCache as p, VariableFontAxesSchema as pn, resolveMediaSourceUrl as pt, parseColor as q, SelectorShapeSchema as qt, AudioMeshDeformPipeline as r, TextPathBuilder as rn, resolveTextSpans as rt, NodeSurfaceProvider as s, TextScrambleConfigSchema as sn, spansText as st, AudioLatentEngine as t, TextCursorConfigSchema as tn, registerHeadlessFont as tt, SSAOPipeline as u, TextWigglySelectorSchema as un, trackAudioPitch as ut, clearAllVideoCache as v, buildWGSLSignalFn as vn, MAX_LIGHTS as vt, drawImageNode as w, ellipseToCubicBeziers as wn, resolveEnvironment as wt, describeGpu as x, computeRangeSelectorWeight as xn, Vector3Math as xt, clearHeadlessFonts as y, computeAnchorPivotOffset as yn, Matrix4Math as yt, inputStore as z, sampleAudioSpectrumScale as zn, GlyphAnchorGroupingSchema as zt };
|
|
42134
|
+
//# sourceMappingURL=dist--Uu5bQ_6.mjs.map
|