framefields 2.0.2

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.
Files changed (408) hide show
  1. package/LICENCE +202 -0
  2. package/README.md +740 -0
  3. package/dist/audio/index.d.mts +5 -0
  4. package/dist/audio/index.mjs +14 -0
  5. package/dist/audio-Dvwwz8xU.d.mts +37 -0
  6. package/dist/audio-Dvwwz8xU.d.mts.map +1 -0
  7. package/dist/audio-TAvPwzLR.mjs +214 -0
  8. package/dist/audio-TAvPwzLR.mjs.map +1 -0
  9. package/dist/audio-x28ZgQBP.mjs +85 -0
  10. package/dist/audio-x28ZgQBP.mjs.map +1 -0
  11. package/dist/chunk-GMkBE123.mjs +47 -0
  12. package/dist/client-C74hb7fy.mjs +66 -0
  13. package/dist/client-C74hb7fy.mjs.map +1 -0
  14. package/dist/dist-1iUYuPct.mjs +1859 -0
  15. package/dist/dist-1iUYuPct.mjs.map +1 -0
  16. package/dist/dist-Bx6J0VcM.mjs +1859 -0
  17. package/dist/dist-Bx6J0VcM.mjs.map +1 -0
  18. package/dist/dist-C_hjvkdN.mjs +2220 -0
  19. package/dist/dist-C_hjvkdN.mjs.map +1 -0
  20. package/dist/dist-DKm2IyEJ.mjs +94 -0
  21. package/dist/dist-DKm2IyEJ.mjs.map +1 -0
  22. package/dist/dist-cjs-B5EVqDFp.mjs +85 -0
  23. package/dist/dist-cjs-B5EVqDFp.mjs.map +1 -0
  24. package/dist/dist-cjs-BGJkdexX.mjs +437 -0
  25. package/dist/dist-cjs-BGJkdexX.mjs.map +1 -0
  26. package/dist/dist-cjs-BKmGCgtm.mjs +9069 -0
  27. package/dist/dist-cjs-BKmGCgtm.mjs.map +1 -0
  28. package/dist/dist-cjs-BUc0_kg-.mjs +1091 -0
  29. package/dist/dist-cjs-BUc0_kg-.mjs.map +1 -0
  30. package/dist/dist-cjs-BUwe2XhR.mjs +153 -0
  31. package/dist/dist-cjs-BUwe2XhR.mjs.map +1 -0
  32. package/dist/dist-cjs-BWgoUCXJ.mjs +137 -0
  33. package/dist/dist-cjs-BWgoUCXJ.mjs.map +1 -0
  34. package/dist/dist-cjs-CmZEMtO6.mjs +6 -0
  35. package/dist/dist-cjs-D7kEM-Mj.mjs +181 -0
  36. package/dist/dist-cjs-D7kEM-Mj.mjs.map +1 -0
  37. package/dist/dist-cjs-DFUmy89O.mjs +48 -0
  38. package/dist/dist-cjs-DFUmy89O.mjs.map +1 -0
  39. package/dist/dist-cjs-Df7144zM.mjs +209 -0
  40. package/dist/dist-cjs-Df7144zM.mjs.map +1 -0
  41. package/dist/dist-cjs-DgxjcvBN.mjs +98 -0
  42. package/dist/dist-cjs-DgxjcvBN.mjs.map +1 -0
  43. package/dist/dist-cjs-DsMdld8l.mjs +5015 -0
  44. package/dist/dist-cjs-DsMdld8l.mjs.map +1 -0
  45. package/dist/dist-cjs-Dzs5P3K0.mjs +51 -0
  46. package/dist/dist-cjs-Dzs5P3K0.mjs.map +1 -0
  47. package/dist/dist-cjs-ECMuIF57.mjs +323 -0
  48. package/dist/dist-cjs-ECMuIF57.mjs.map +1 -0
  49. package/dist/dist-cjs-lYvO8aDo.mjs +64 -0
  50. package/dist/dist-cjs-lYvO8aDo.mjs.map +1 -0
  51. package/dist/dist-cjs-qEJrwjGk.mjs +66 -0
  52. package/dist/dist-cjs-qEJrwjGk.mjs.map +1 -0
  53. package/dist/dist-cjs-x5cwlqA5.mjs +43 -0
  54. package/dist/dist-cjs-x5cwlqA5.mjs.map +1 -0
  55. package/dist/dist-gjHmorxL.mjs +27479 -0
  56. package/dist/dist-gjHmorxL.mjs.map +1 -0
  57. package/dist/effects/index.d.mts +5 -0
  58. package/dist/effects/index.mjs +35 -0
  59. package/dist/effects-CHWORCYd.mjs +811 -0
  60. package/dist/effects-CHWORCYd.mjs.map +1 -0
  61. package/dist/event-streams-D-APZ7Ke.mjs +204 -0
  62. package/dist/event-streams-D-APZ7Ke.mjs.map +1 -0
  63. package/dist/fonts/index.d.mts +2 -0
  64. package/dist/fonts/index.mjs +3 -0
  65. package/dist/fonts-DrGTBJJk.mjs +188 -0
  66. package/dist/fonts-DrGTBJJk.mjs.map +1 -0
  67. package/dist/index-B0BNPEoH.d.mts +2117 -0
  68. package/dist/index-B0BNPEoH.d.mts.map +1 -0
  69. package/dist/index-BMVVmc4G.d.mts +72 -0
  70. package/dist/index-BMVVmc4G.d.mts.map +1 -0
  71. package/dist/index-D1ZsMpke.d.mts +264 -0
  72. package/dist/index-D1ZsMpke.d.mts.map +1 -0
  73. package/dist/index-D2jDC7O5.d.mts +3643 -0
  74. package/dist/index-D2jDC7O5.d.mts.map +1 -0
  75. package/dist/index-D2wJqSl5.d.mts +114 -0
  76. package/dist/index-D2wJqSl5.d.mts.map +1 -0
  77. package/dist/index-DKFGNyMB.d.mts +309 -0
  78. package/dist/index-DKFGNyMB.d.mts.map +1 -0
  79. package/dist/index-DiSKzDGR.d.mts +65 -0
  80. package/dist/index-DiSKzDGR.d.mts.map +1 -0
  81. package/dist/index.d.mts +4425 -0
  82. package/dist/index.d.mts.map +1 -0
  83. package/dist/index.mjs +2623 -0
  84. package/dist/index.mjs.map +1 -0
  85. package/dist/package-C58KmGKw.mjs +6 -0
  86. package/dist/package-C58KmGKw.mjs.map +1 -0
  87. package/dist/preview/index.d.mts +90 -0
  88. package/dist/preview/index.d.mts.map +1 -0
  89. package/dist/preview/index.mjs +15 -0
  90. package/dist/preview-engine/audio.mjs +1 -0
  91. package/dist/preview-engine/child_process-AIL2NBWS.mjs +1 -0
  92. package/dist/preview-engine/chunk-24P6DAB3.mjs +1 -0
  93. package/dist/preview-engine/chunk-37EFVZWT.mjs +1 -0
  94. package/dist/preview-engine/chunk-3O5OKR6D.mjs +223 -0
  95. package/dist/preview-engine/chunk-47VT677S.mjs +8 -0
  96. package/dist/preview-engine/chunk-4BEJJKEU.mjs +315 -0
  97. package/dist/preview-engine/chunk-4GEWSUX5.mjs +1 -0
  98. package/dist/preview-engine/chunk-55CCFPUX.mjs +237 -0
  99. package/dist/preview-engine/chunk-5JD65JSJ.mjs +110 -0
  100. package/dist/preview-engine/chunk-5UP7FSGT.mjs +294 -0
  101. package/dist/preview-engine/chunk-5XDHHOF2.mjs +367 -0
  102. package/dist/preview-engine/chunk-6YJP57MZ.mjs +729 -0
  103. package/dist/preview-engine/chunk-6ZOXGAYA.mjs +112 -0
  104. package/dist/preview-engine/chunk-AOLAHYVV.mjs +529 -0
  105. package/dist/preview-engine/chunk-B6PLCMBM.mjs +1 -0
  106. package/dist/preview-engine/chunk-BJKH76OM.mjs +264 -0
  107. package/dist/preview-engine/chunk-BUIQ5TUH.mjs +104 -0
  108. package/dist/preview-engine/chunk-BVF64D6H.mjs +1 -0
  109. package/dist/preview-engine/chunk-CA5N7JRZ.mjs +138 -0
  110. package/dist/preview-engine/chunk-CNSHAFEA.mjs +1 -0
  111. package/dist/preview-engine/chunk-CURR5X7D.mjs +1 -0
  112. package/dist/preview-engine/chunk-CVGM2U4J.mjs +47 -0
  113. package/dist/preview-engine/chunk-CYY366IE.mjs +1 -0
  114. package/dist/preview-engine/chunk-D5PHI6ET.mjs +109 -0
  115. package/dist/preview-engine/chunk-D7MZHP2Y.mjs +275 -0
  116. package/dist/preview-engine/chunk-DPPH3NK2.mjs +182 -0
  117. package/dist/preview-engine/chunk-DPST2XLC.mjs +418 -0
  118. package/dist/preview-engine/chunk-DRLEOHN5.mjs +1 -0
  119. package/dist/preview-engine/chunk-EDIZNO3P.mjs +1 -0
  120. package/dist/preview-engine/chunk-EHIIT4ZR.mjs +52 -0
  121. package/dist/preview-engine/chunk-FKZ4XXPE.mjs +1 -0
  122. package/dist/preview-engine/chunk-G3HW4VER.mjs +60 -0
  123. package/dist/preview-engine/chunk-G76HSKOS.mjs +184 -0
  124. package/dist/preview-engine/chunk-GYG2IIBR.mjs +1 -0
  125. package/dist/preview-engine/chunk-H2F5NVQ6.mjs +63 -0
  126. package/dist/preview-engine/chunk-H5BPCY7N.mjs +188 -0
  127. package/dist/preview-engine/chunk-HAXK42HG.mjs +997 -0
  128. package/dist/preview-engine/chunk-HXMDPMLB.mjs +1 -0
  129. package/dist/preview-engine/chunk-HYBAPT6I.mjs +1 -0
  130. package/dist/preview-engine/chunk-I4FH6HYU.mjs +73 -0
  131. package/dist/preview-engine/chunk-IYVN2QEL.mjs +1 -0
  132. package/dist/preview-engine/chunk-JPXQPP6J.mjs +1 -0
  133. package/dist/preview-engine/chunk-JWNHTRED.mjs +164 -0
  134. package/dist/preview-engine/chunk-KZOLCZIV.mjs +103 -0
  135. package/dist/preview-engine/chunk-L62MRHGZ.mjs +89 -0
  136. package/dist/preview-engine/chunk-LEEZXHQO.mjs +117 -0
  137. package/dist/preview-engine/chunk-LKYN3BM2.mjs +1 -0
  138. package/dist/preview-engine/chunk-LP3EP33S.mjs +610 -0
  139. package/dist/preview-engine/chunk-M2GRYRLM.mjs +111 -0
  140. package/dist/preview-engine/chunk-MC7TZZLD.mjs +134 -0
  141. package/dist/preview-engine/chunk-MT2DZQHO.mjs +1 -0
  142. package/dist/preview-engine/chunk-MTJHQATU.mjs +1 -0
  143. package/dist/preview-engine/chunk-N4LHIPHZ.mjs +340 -0
  144. package/dist/preview-engine/chunk-N4PWLBZ7.mjs +5 -0
  145. package/dist/preview-engine/chunk-NQZKBFC6.mjs +40 -0
  146. package/dist/preview-engine/chunk-NWRSVVTF.mjs +186 -0
  147. package/dist/preview-engine/chunk-P3HBP725.mjs +1 -0
  148. package/dist/preview-engine/chunk-PIAJWALT.mjs +1 -0
  149. package/dist/preview-engine/chunk-PJ3DVG45.mjs +1 -0
  150. package/dist/preview-engine/chunk-QP2NI4XD.mjs +82 -0
  151. package/dist/preview-engine/chunk-SA3JUR6D.mjs +52 -0
  152. package/dist/preview-engine/chunk-SRT2OCQW.mjs +1 -0
  153. package/dist/preview-engine/chunk-SWD76532.mjs +98 -0
  154. package/dist/preview-engine/chunk-SXX7HX34.mjs +191 -0
  155. package/dist/preview-engine/chunk-SZ7YRPKO.mjs +3 -0
  156. package/dist/preview-engine/chunk-TMRLZV5X.mjs +1 -0
  157. package/dist/preview-engine/chunk-U446SQP3.mjs +292 -0
  158. package/dist/preview-engine/chunk-UDNCEHUI.mjs +141 -0
  159. package/dist/preview-engine/chunk-V3H7WWOT.mjs +271 -0
  160. package/dist/preview-engine/chunk-V7ZVVUQU.mjs +108 -0
  161. package/dist/preview-engine/chunk-VJGK7MLJ.mjs +3 -0
  162. package/dist/preview-engine/chunk-VSSB73UU.mjs +58 -0
  163. package/dist/preview-engine/chunk-VXUJWPIK.mjs +1 -0
  164. package/dist/preview-engine/chunk-XD4GKD6H.mjs +5 -0
  165. package/dist/preview-engine/chunk-XKO4RYKN.mjs +3 -0
  166. package/dist/preview-engine/chunk-XOEEGC4Z.mjs +1 -0
  167. package/dist/preview-engine/chunk-YAQFFQPG.mjs +1 -0
  168. package/dist/preview-engine/chunk-YKMBRUAE.mjs +1 -0
  169. package/dist/preview-engine/chunk-YSTLMWCG.mjs +1 -0
  170. package/dist/preview-engine/chunk-Z4ERCLNF.mjs +1 -0
  171. package/dist/preview-engine/chunk-ZEYUXJIV.mjs +1 -0
  172. package/dist/preview-engine/chunk-ZX6APG6E.mjs +117 -0
  173. package/dist/preview-engine/effects.mjs +1 -0
  174. package/dist/preview-engine/esbuild-GWV7CM7D.mjs +1 -0
  175. package/dist/preview-engine/fonts.mjs +1 -0
  176. package/dist/preview-engine/framefields.mjs +1959 -0
  177. package/dist/preview-engine/onnxruntime-node-56GSZEH3.mjs +1 -0
  178. package/dist/preview-engine/player.mjs +155 -0
  179. package/dist/preview-engine/renderers-2AUSIYZN.mjs +1 -0
  180. package/dist/preview-engine/renderers-2QN6KZJP.mjs +1 -0
  181. package/dist/preview-engine/renderers-32SKW7ML.mjs +1 -0
  182. package/dist/preview-engine/renderers-5QYK6766.mjs +1 -0
  183. package/dist/preview-engine/renderers-6BJA6MSU.mjs +251 -0
  184. package/dist/preview-engine/renderers-6QAF3LQ2.mjs +1 -0
  185. package/dist/preview-engine/renderers-7AO5746S.mjs +296 -0
  186. package/dist/preview-engine/renderers-AFYKNM6N.mjs +1 -0
  187. package/dist/preview-engine/renderers-AGMH5CRH.mjs +1 -0
  188. package/dist/preview-engine/renderers-AHSGP6LY.mjs +126 -0
  189. package/dist/preview-engine/renderers-ASTBICLA.mjs +1 -0
  190. package/dist/preview-engine/renderers-BHVPLYNN.mjs +1 -0
  191. package/dist/preview-engine/renderers-D7PVQFVU.mjs +1 -0
  192. package/dist/preview-engine/renderers-DB4ABTNA.mjs +1 -0
  193. package/dist/preview-engine/renderers-F2NFJI5L.mjs +1 -0
  194. package/dist/preview-engine/renderers-FI7YHNLY.mjs +1 -0
  195. package/dist/preview-engine/renderers-GBHULMPH.mjs +1 -0
  196. package/dist/preview-engine/renderers-GUKQUMGG.mjs +55 -0
  197. package/dist/preview-engine/renderers-HGT7QDY3.mjs +1 -0
  198. package/dist/preview-engine/renderers-HOYLA7ZK.mjs +1 -0
  199. package/dist/preview-engine/renderers-KKI2D3MZ.mjs +1 -0
  200. package/dist/preview-engine/renderers-KRAJNV4E.mjs +1 -0
  201. package/dist/preview-engine/renderers-KUGZKSVE.mjs +1 -0
  202. package/dist/preview-engine/renderers-L2EQQIOC.mjs +1 -0
  203. package/dist/preview-engine/renderers-LK3NRMGR.mjs +1 -0
  204. package/dist/preview-engine/renderers-LX654SZ3.mjs +1 -0
  205. package/dist/preview-engine/renderers-MCFQFYEL.mjs +1 -0
  206. package/dist/preview-engine/renderers-O6HOYIPS.mjs +1 -0
  207. package/dist/preview-engine/renderers-OEVXCGE2.mjs +1 -0
  208. package/dist/preview-engine/renderers-QVD6C4CS.mjs +1 -0
  209. package/dist/preview-engine/renderers-R3XEYD5V.mjs +248 -0
  210. package/dist/preview-engine/renderers-RBFWJWVM.mjs +1 -0
  211. package/dist/preview-engine/renderers-RX3VLVLO.mjs +1 -0
  212. package/dist/preview-engine/renderers-SM6JP64K.mjs +1 -0
  213. package/dist/preview-engine/renderers-TKMAATVS.mjs +1 -0
  214. package/dist/preview-engine/renderers-UGZUPONY.mjs +1 -0
  215. package/dist/preview-engine/renderers-UTFXZE3G.mjs +1 -0
  216. package/dist/preview-engine/renderers-UWPH7HBH.mjs +1 -0
  217. package/dist/preview-engine/renderers-UZGECFVO.mjs +1 -0
  218. package/dist/preview-engine/renderers-VGU3LNLT.mjs +1 -0
  219. package/dist/preview-engine/renderers-W3VVM5HB.mjs +1 -0
  220. package/dist/preview-engine/renderers-WJUTT5BB.mjs +1 -0
  221. package/dist/preview-engine/renderers-XA2M4YXK.mjs +1 -0
  222. package/dist/preview-engine/renderers-XIHRFEFQ.mjs +1 -0
  223. package/dist/preview-engine/renderers-XJTA5MFG.mjs +1 -0
  224. package/dist/preview-engine/renderers-XLTY5APF.mjs +1 -0
  225. package/dist/preview-engine/renderers-XZ3VXFGZ.mjs +1 -0
  226. package/dist/preview-engine/renderers-YKUQUCTO.mjs +124 -0
  227. package/dist/preview-engine/renderers-YVN3EIOP.mjs +1 -0
  228. package/dist/preview-engine/renderers-YWRP23SZ.mjs +125 -0
  229. package/dist/preview-engine/renderers-ZPWOUWZJ.mjs +120 -0
  230. package/dist/preview-engine/resvg-js-VMU4A77S.mjs +1 -0
  231. package/dist/preview-engine/server-utils-2FAIV45N.mjs +1 -0
  232. package/dist/preview-engine/sharp-V6ZTBNDW.mjs +1 -0
  233. package/dist/preview-engine/shims/fs-promises.mjs +1 -0
  234. package/dist/preview-engine/shims/fs.mjs +1 -0
  235. package/dist/preview-engine/shims/module.mjs +1 -0
  236. package/dist/preview-engine/shims/os.mjs +1 -0
  237. package/dist/preview-engine/shims/path.mjs +1 -0
  238. package/dist/preview-engine/shims/url.mjs +1 -0
  239. package/dist/preview-engine/signals.mjs +1 -0
  240. package/dist/preview-engine/webgpu-NSSANM4F.mjs +1 -0
  241. package/dist/preview-uQM210iy.mjs +2149 -0
  242. package/dist/preview-uQM210iy.mjs.map +1 -0
  243. package/dist/program-Dl510wmI.mjs +5183 -0
  244. package/dist/program-Dl510wmI.mjs.map +1 -0
  245. package/dist/renderer/index.d.mts +3 -0
  246. package/dist/renderer/index.mjs +6 -0
  247. package/dist/renderer-3BNskNuJ.mjs +3 -0
  248. package/dist/renderer-7DOcIxFG.mjs +288 -0
  249. package/dist/renderer-7DOcIxFG.mjs.map +1 -0
  250. package/dist/renderer-9dHlMQGX.mjs +3 -0
  251. package/dist/renderer-B1CvhW4p.mjs +677 -0
  252. package/dist/renderer-B1CvhW4p.mjs.map +1 -0
  253. package/dist/renderer-B2XzjK0z.mjs +3 -0
  254. package/dist/renderer-B80s47yo.mjs +166 -0
  255. package/dist/renderer-B80s47yo.mjs.map +1 -0
  256. package/dist/renderer-B9-QSJcG.mjs +479 -0
  257. package/dist/renderer-B9-QSJcG.mjs.map +1 -0
  258. package/dist/renderer-BAQmR0Zo.mjs +3 -0
  259. package/dist/renderer-BDLnExoP.mjs +127 -0
  260. package/dist/renderer-BDLnExoP.mjs.map +1 -0
  261. package/dist/renderer-BGXU6vcW.mjs +270 -0
  262. package/dist/renderer-BGXU6vcW.mjs.map +1 -0
  263. package/dist/renderer-BGvORwkQ.mjs +3 -0
  264. package/dist/renderer-BLikd6BK.mjs +3 -0
  265. package/dist/renderer-BMovYRoR.mjs +3 -0
  266. package/dist/renderer-BQHbp-Sp.mjs +243 -0
  267. package/dist/renderer-BQHbp-Sp.mjs.map +1 -0
  268. package/dist/renderer-BREIjsUU.mjs +252 -0
  269. package/dist/renderer-BREIjsUU.mjs.map +1 -0
  270. package/dist/renderer-BSbTJBWc.mjs +3 -0
  271. package/dist/renderer-BTu2EVhF.mjs +3 -0
  272. package/dist/renderer-BU1rwNRT.mjs +3 -0
  273. package/dist/renderer-BXMmISWG.mjs +499 -0
  274. package/dist/renderer-BXMmISWG.mjs.map +1 -0
  275. package/dist/renderer-BZJm3m4f.mjs +3 -0
  276. package/dist/renderer-B_NuVaIP.mjs +744 -0
  277. package/dist/renderer-B_NuVaIP.mjs.map +1 -0
  278. package/dist/renderer-BfJSUjPN.mjs +3 -0
  279. package/dist/renderer-BqyAgNt3.mjs +3 -0
  280. package/dist/renderer-BryTM2g7.mjs +3 -0
  281. package/dist/renderer-BsgIcBKH.mjs +391 -0
  282. package/dist/renderer-BsgIcBKH.mjs.map +1 -0
  283. package/dist/renderer-ByDhfrPE.mjs +422 -0
  284. package/dist/renderer-ByDhfrPE.mjs.map +1 -0
  285. package/dist/renderer-C-H680_l.mjs +3 -0
  286. package/dist/renderer-C17wL9QX.mjs +181 -0
  287. package/dist/renderer-C17wL9QX.mjs.map +1 -0
  288. package/dist/renderer-C2n-EHxg.mjs +1 -0
  289. package/dist/renderer-CB5aWAaf.mjs +343 -0
  290. package/dist/renderer-CB5aWAaf.mjs.map +1 -0
  291. package/dist/renderer-CB7lH5K8.mjs +3 -0
  292. package/dist/renderer-CDLrNgfo.mjs +3 -0
  293. package/dist/renderer-CDOUAN7X.mjs +454 -0
  294. package/dist/renderer-CDOUAN7X.mjs.map +1 -0
  295. package/dist/renderer-CH8sdfYX.mjs +387 -0
  296. package/dist/renderer-CH8sdfYX.mjs.map +1 -0
  297. package/dist/renderer-CIvaRnP_.mjs +261 -0
  298. package/dist/renderer-CIvaRnP_.mjs.map +1 -0
  299. package/dist/renderer-CMzEjdzi.mjs +369 -0
  300. package/dist/renderer-CMzEjdzi.mjs.map +1 -0
  301. package/dist/renderer-COkcU3db.mjs +3302 -0
  302. package/dist/renderer-COkcU3db.mjs.map +1 -0
  303. package/dist/renderer-CQCoggIa.mjs +3 -0
  304. package/dist/renderer-CQdVj2JS.mjs +3 -0
  305. package/dist/renderer-CQiTodg9.mjs +337 -0
  306. package/dist/renderer-CQiTodg9.mjs.map +1 -0
  307. package/dist/renderer-CV2m6k1V.mjs +3 -0
  308. package/dist/renderer-CYY-poLe.mjs +3 -0
  309. package/dist/renderer-CZgB5st8.mjs +3 -0
  310. package/dist/renderer-C_Ki91kc.mjs +3 -0
  311. package/dist/renderer-CclIvsLO.mjs +3 -0
  312. package/dist/renderer-Cj-whdVr.mjs +655 -0
  313. package/dist/renderer-Cj-whdVr.mjs.map +1 -0
  314. package/dist/renderer-CkykdR_D.mjs +3 -0
  315. package/dist/renderer-Cl1oUXMi.mjs +1143 -0
  316. package/dist/renderer-Cl1oUXMi.mjs.map +1 -0
  317. package/dist/renderer-CmApuKjS.mjs +3 -0
  318. package/dist/renderer-CpkiHRhh.mjs +269 -0
  319. package/dist/renderer-CpkiHRhh.mjs.map +1 -0
  320. package/dist/renderer-CszOjcRW.mjs +3 -0
  321. package/dist/renderer-CtVkU_GA.mjs +44 -0
  322. package/dist/renderer-CtVkU_GA.mjs.map +1 -0
  323. package/dist/renderer-Cu074POw.mjs +3 -0
  324. package/dist/renderer-CwQhzcUn.mjs +644 -0
  325. package/dist/renderer-CwQhzcUn.mjs.map +1 -0
  326. package/dist/renderer-CzPWB0Ss.mjs +273 -0
  327. package/dist/renderer-CzPWB0Ss.mjs.map +1 -0
  328. package/dist/renderer-D4qLmox-.mjs +3 -0
  329. package/dist/renderer-D6bWQtr-.mjs +3 -0
  330. package/dist/renderer-D6cJ6MSq.mjs +3 -0
  331. package/dist/renderer-D7EX8IjU.mjs +240 -0
  332. package/dist/renderer-D7EX8IjU.mjs.map +1 -0
  333. package/dist/renderer-DDp7_TUi.d.mts +10 -0
  334. package/dist/renderer-DDp7_TUi.d.mts.map +1 -0
  335. package/dist/renderer-DFKsLrUs.mjs +256 -0
  336. package/dist/renderer-DFKsLrUs.mjs.map +1 -0
  337. package/dist/renderer-DPSsf8-t.mjs +3 -0
  338. package/dist/renderer-DQLGnEFc.mjs +3 -0
  339. package/dist/renderer-DY2SVYUW.mjs +3 -0
  340. package/dist/renderer-DZGtBUCx.mjs +792 -0
  341. package/dist/renderer-DZGtBUCx.mjs.map +1 -0
  342. package/dist/renderer-DabG62XS.mjs +406 -0
  343. package/dist/renderer-DabG62XS.mjs.map +1 -0
  344. package/dist/renderer-DbaQLI4z.mjs +771 -0
  345. package/dist/renderer-DbaQLI4z.mjs.map +1 -0
  346. package/dist/renderer-DjI45OYC.mjs +71 -0
  347. package/dist/renderer-DjI45OYC.mjs.map +1 -0
  348. package/dist/renderer-Dm08-hAU.mjs +323 -0
  349. package/dist/renderer-Dm08-hAU.mjs.map +1 -0
  350. package/dist/renderer-DoAY5JbB.mjs +4 -0
  351. package/dist/renderer-Dp_FfvF-.mjs +401 -0
  352. package/dist/renderer-Dp_FfvF-.mjs.map +1 -0
  353. package/dist/renderer-Dt6fzgX5.mjs +756 -0
  354. package/dist/renderer-Dt6fzgX5.mjs.map +1 -0
  355. package/dist/renderer-DuplLRbp.mjs +3 -0
  356. package/dist/renderer-DvfUbZ31.mjs +3 -0
  357. package/dist/renderer-DxjVQV6f.mjs +311 -0
  358. package/dist/renderer-DxjVQV6f.mjs.map +1 -0
  359. package/dist/renderer-Fco4EmAu.mjs +23868 -0
  360. package/dist/renderer-Fco4EmAu.mjs.map +1 -0
  361. package/dist/renderer-HFfcJlmR.mjs +981 -0
  362. package/dist/renderer-HFfcJlmR.mjs.map +1 -0
  363. package/dist/renderer-I-Sw3JBB.mjs +145 -0
  364. package/dist/renderer-I-Sw3JBB.mjs.map +1 -0
  365. package/dist/renderer-OWQmmg4Z.mjs +697 -0
  366. package/dist/renderer-OWQmmg4Z.mjs.map +1 -0
  367. package/dist/renderer-Q_uUQipO.mjs +3 -0
  368. package/dist/renderer-Ryo2CEFD.mjs +586 -0
  369. package/dist/renderer-Ryo2CEFD.mjs.map +1 -0
  370. package/dist/renderer-Tp6OXWNZ.mjs +257 -0
  371. package/dist/renderer-Tp6OXWNZ.mjs.map +1 -0
  372. package/dist/renderer-UQFCgeNx.mjs +3 -0
  373. package/dist/renderer-WkVrkCVA.mjs +83 -0
  374. package/dist/renderer-WkVrkCVA.mjs.map +1 -0
  375. package/dist/renderer-XcmYTd6P.mjs +3818 -0
  376. package/dist/renderer-XcmYTd6P.mjs.map +1 -0
  377. package/dist/renderer-_uvdg48N.mjs +333 -0
  378. package/dist/renderer-_uvdg48N.mjs.map +1 -0
  379. package/dist/renderer-bZU_ndxf.mjs +8 -0
  380. package/dist/renderer-bZU_ndxf.mjs.map +1 -0
  381. package/dist/renderer-eMsnzJg9.mjs +3 -0
  382. package/dist/renderer-ho_jXJ0H.mjs +254 -0
  383. package/dist/renderer-ho_jXJ0H.mjs.map +1 -0
  384. package/dist/renderer-k2JL79kM.mjs +306 -0
  385. package/dist/renderer-k2JL79kM.mjs.map +1 -0
  386. package/dist/renderer-pHiz78e0.mjs +3 -0
  387. package/dist/renderer-pxXf9dvk.mjs +394 -0
  388. package/dist/renderer-pxXf9dvk.mjs.map +1 -0
  389. package/dist/renderer-vCFTm0oe.mjs +226 -0
  390. package/dist/renderer-vCFTm0oe.mjs.map +1 -0
  391. package/dist/renderer-vvpdx1vk.mjs +379 -0
  392. package/dist/renderer-vvpdx1vk.mjs.map +1 -0
  393. package/dist/renderer-x2s9LmVL.mjs +1121 -0
  394. package/dist/renderer-x2s9LmVL.mjs.map +1 -0
  395. package/dist/renderers-BWg16W-V-BXG_cjhM.mjs +49 -0
  396. package/dist/renderers-BWg16W-V-BXG_cjhM.mjs.map +1 -0
  397. package/dist/signals/index.d.mts +7 -0
  398. package/dist/signals/index.mjs +10 -0
  399. package/dist/signals-BwbdO3AN.mjs +224 -0
  400. package/dist/signals-BwbdO3AN.mjs.map +1 -0
  401. package/dist/signin-CZj4Oc5s.mjs +865 -0
  402. package/dist/signin-CZj4Oc5s.mjs.map +1 -0
  403. package/dist/sso-oidc-C0_31ThY.mjs +1051 -0
  404. package/dist/sso-oidc-C0_31ThY.mjs.map +1 -0
  405. package/dist/sts-DD4ggEXC.mjs +6 -0
  406. package/dist/sts-nXw8RDJI.mjs +1395 -0
  407. package/dist/sts-nXw8RDJI.mjs.map +1 -0
  408. package/package.json +173 -0
@@ -0,0 +1,2220 @@
1
+ //#region ../tensor-webgpu/dist/index.mjs
2
+ var ControlNetMultiplexer = class {
3
+ textures = /* @__PURE__ */ new Map();
4
+ set(type, texture) {
5
+ this.textures.set(type, texture);
6
+ }
7
+ get(type) {
8
+ return this.textures.get(type);
9
+ }
10
+ has(type) {
11
+ return this.textures.has(type);
12
+ }
13
+ getOutputs() {
14
+ return {
15
+ canny: this.textures.get("canny"),
16
+ depth: this.textures.get("depth"),
17
+ normals: this.textures.get("normals"),
18
+ poseSkeleton: this.textures.get("poseSkeleton"),
19
+ segmentationMask: this.textures.get("segmentationMask"),
20
+ faceLandmarks: this.textures.get("faceLandmarks"),
21
+ motionVectors: this.textures.get("motionVectors"),
22
+ deflickered: this.textures.get("deflickered")
23
+ };
24
+ }
25
+ createBindGroupEntry(type, bindingIndex) {
26
+ const tex = this.textures.get(type);
27
+ if (!tex) throw new Error(`[ControlNetMultiplexer] Cannot create bind group entry: conditioning texture "${type}" is not registered in VRAM.`);
28
+ return {
29
+ binding: bindingIndex,
30
+ resource: tex.createView({ label: `controlnet_${type}_view` })
31
+ };
32
+ }
33
+ exportTensorView(type) {
34
+ const tex = this.textures.get(type);
35
+ if (!tex) throw new Error(`[ControlNetMultiplexer] Conditioning tensor "${type}" not found in multiplexer.`);
36
+ return {
37
+ texture: tex,
38
+ width: tex.width,
39
+ height: tex.height,
40
+ format: tex.format
41
+ };
42
+ }
43
+ async readPixelsAsync(device, type) {
44
+ const tex = this.textures.get(type);
45
+ if (!tex) throw new Error(`[ControlNetMultiplexer] Cannot read pixels: conditioning texture "${type}" is missing.`);
46
+ const width = tex.width;
47
+ const height = tex.height;
48
+ const format = tex.format;
49
+ let bytesPerPixel = 4;
50
+ if (format === "rgba16float" || format === "rg32float") bytesPerPixel = 8;
51
+ else if (format === "r32float") bytesPerPixel = 4;
52
+ else if (format === "rgba32float") bytesPerPixel = 16;
53
+ const unalignedBytesPerRow = width * bytesPerPixel;
54
+ const bytesPerRow = Math.ceil(unalignedBytesPerRow / 256) * 256;
55
+ const bufferSize = bytesPerRow * height;
56
+ const stagingBuffer = device.createBuffer({
57
+ size: bufferSize,
58
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
59
+ label: `controlnet_readback_staging_${type}`
60
+ });
61
+ const encoder = device.createCommandEncoder({ label: `readback_encoder_${type}` });
62
+ encoder.copyTextureToBuffer({ texture: tex }, {
63
+ buffer: stagingBuffer,
64
+ bytesPerRow,
65
+ rowsPerImage: height
66
+ }, [
67
+ width,
68
+ height,
69
+ 1
70
+ ]);
71
+ device.queue.submit([encoder.finish()]);
72
+ await stagingBuffer.mapAsync(GPUMapMode.READ);
73
+ const mappedRange = stagingBuffer.getMappedRange();
74
+ const resultData = new Uint8Array(width * height * bytesPerPixel);
75
+ const sourceBytes = new Uint8Array(mappedRange);
76
+ if (bytesPerRow === unalignedBytesPerRow) resultData.set(sourceBytes.subarray(0, width * height * bytesPerPixel));
77
+ else for (let y = 0; y < height; y++) {
78
+ const srcOffset = y * bytesPerRow;
79
+ const dstOffset = y * unalignedBytesPerRow;
80
+ resultData.set(sourceBytes.subarray(srcOffset, srcOffset + unalignedBytesPerRow), dstOffset);
81
+ }
82
+ stagingBuffer.unmap();
83
+ stagingBuffer.destroy();
84
+ return {
85
+ width,
86
+ height,
87
+ format,
88
+ data: resultData
89
+ };
90
+ }
91
+ destroy() {
92
+ for (const tex of this.textures.values()) try {
93
+ tex.destroy();
94
+ } catch (_) {}
95
+ this.textures.clear();
96
+ }
97
+ };
98
+ /**
99
+ * @file canny.wgsl.ts
100
+ * High-performance WebGPU Canny Edge Compute Shaders
101
+ * Pass 1: Sobel gradient magnitude & quantized angle
102
+ * Pass 2: Non-Maximum Suppression (NMS) & Dual-Threshold Hysteresis
103
+ */
104
+ const cannySobelWgsl = `
105
+ struct CannyParams {
106
+ lowThreshold: f32,
107
+ highThreshold: f32,
108
+ width: u32,
109
+ height: u32,
110
+ };
111
+
112
+ @group(0) @binding(0) var inputTex: texture_2d<f32>;
113
+ @group(0) @binding(1) var magnitudeTex: texture_storage_2d<rgba16float, write>;
114
+ @group(0) @binding(2) var<uniform> params: CannyParams;
115
+
116
+ fn getLuma(coord: vec2<i32>, maxCoord: vec2<i32>) -> f32 {
117
+ let clamped = clamp(coord, vec2<i32>(0), maxCoord);
118
+ let c = textureLoad(inputTex, clamped, 0);
119
+ return dot(c.rgb, vec3<f32>(0.299, 0.587, 0.114));
120
+ }
121
+
122
+ @compute @workgroup_size(16, 16)
123
+ fn computeSobel(@builtin(global_invocation_id) id: vec3<u32>) {
124
+ if (id.x >= params.width || id.y >= params.height) { return; }
125
+
126
+ let x = i32(id.x);
127
+ let y = i32(id.y);
128
+ let maxCoord = vec2<i32>(i32(params.width) - 1, i32(params.height) - 1);
129
+
130
+ let p00 = getLuma(vec2<i32>(x - 1, y - 1), maxCoord);
131
+ let p10 = getLuma(vec2<i32>(x, y - 1), maxCoord);
132
+ let p20 = getLuma(vec2<i32>(x + 1, y - 1), maxCoord);
133
+ let p01 = getLuma(vec2<i32>(x - 1, y), maxCoord);
134
+ let p21 = getLuma(vec2<i32>(x + 1, y), maxCoord);
135
+ let p02 = getLuma(vec2<i32>(x - 1, y + 1), maxCoord);
136
+ let p12 = getLuma(vec2<i32>(x, y + 1), maxCoord);
137
+ let p22 = getLuma(vec2<i32>(x + 1, y + 1), maxCoord);
138
+
139
+ let gx = (p20 + 2.0 * p21 + p22) - (p00 + 2.0 * p01 + p02);
140
+ let gy = (p02 + 2.0 * p12 + p22) - (p00 + 2.0 * p10 + p20);
141
+
142
+ let mag = sqrt(gx * gx + gy * gy);
143
+ let angle = atan2(gy, gx);
144
+
145
+ // Quantize angle into 4 sectors (0: 0 deg, 1: 45 deg, 2: 90 deg, 3: 135 deg)
146
+ var sector: f32 = 0.0;
147
+ let a = (angle * 180.0 / 3.14159265 + 180.0) % 180.0;
148
+ if ((a >= 0.0 && a < 22.5) || (a >= 157.5 && a <= 180.0)) {
149
+ sector = 0.0;
150
+ } else if (a >= 22.5 && a < 67.5) {
151
+ sector = 1.0;
152
+ } else if (a >= 67.5 && a < 112.5) {
153
+ sector = 2.0;
154
+ } else {
155
+ sector = 3.0;
156
+ }
157
+
158
+ textureStore(magnitudeTex, id.xy, vec4<f32>(mag, sector, 0.0, 1.0));
159
+ }
160
+ `;
161
+ const cannyNmsRgba8Wgsl = `
162
+ struct CannyParams {
163
+ lowThreshold: f32,
164
+ highThreshold: f32,
165
+ width: u32,
166
+ height: u32,
167
+ };
168
+
169
+ @group(0) @binding(0) var magnitudeTex: texture_2d<f32>;
170
+ @group(0) @binding(1) var edgeTex: texture_storage_2d<rgba8unorm, write>;
171
+ @group(0) @binding(2) var<uniform> params: CannyParams;
172
+
173
+ @compute @workgroup_size(16, 16)
174
+ fn computeNonMaxSuppression(@builtin(global_invocation_id) id: vec3<u32>) {
175
+ if (id.x >= params.width || id.y >= params.height) { return; }
176
+
177
+ let x = i32(id.x);
178
+ let y = i32(id.y);
179
+ let maxCoord = vec2<i32>(i32(params.width) - 1, i32(params.height) - 1);
180
+
181
+ let center = textureLoad(magnitudeTex, vec2<i32>(x, y), 0);
182
+ let mag = center.r;
183
+ let sector = u32(round(center.g));
184
+
185
+ var n1 = 0.0;
186
+ var n2 = 0.0;
187
+
188
+ switch (sector) {
189
+ case 0u: {
190
+ n1 = textureLoad(magnitudeTex, clamp(vec2<i32>(x - 1, y), vec2<i32>(0), maxCoord), 0).r;
191
+ n2 = textureLoad(magnitudeTex, clamp(vec2<i32>(x + 1, y), vec2<i32>(0), maxCoord), 0).r;
192
+ }
193
+ case 1u: {
194
+ n1 = textureLoad(magnitudeTex, clamp(vec2<i32>(x + 1, y - 1), vec2<i32>(0), maxCoord), 0).r;
195
+ n2 = textureLoad(magnitudeTex, clamp(vec2<i32>(x - 1, y + 1), vec2<i32>(0), maxCoord), 0).r;
196
+ }
197
+ case 2u: {
198
+ n1 = textureLoad(magnitudeTex, clamp(vec2<i32>(x, y - 1), vec2<i32>(0), maxCoord), 0).r;
199
+ n2 = textureLoad(magnitudeTex, clamp(vec2<i32>(x, y + 1), vec2<i32>(0), maxCoord), 0).r;
200
+ }
201
+ default: {
202
+ n1 = textureLoad(magnitudeTex, clamp(vec2<i32>(x - 1, y - 1), vec2<i32>(0), maxCoord), 0).r;
203
+ n2 = textureLoad(magnitudeTex, clamp(vec2<i32>(x + 1, y + 1), vec2<i32>(0), maxCoord), 0).r;
204
+ }
205
+ }
206
+
207
+ var edge = 0.0;
208
+ // Non-maximum suppression along gradient sector with directional tie-breaking
209
+ if (mag > n1 && mag >= n2 && mag > 0.0) {
210
+ if (mag >= params.highThreshold) {
211
+ edge = 1.0;
212
+ } else if (mag >= params.lowThreshold) {
213
+ edge = 0.5;
214
+ }
215
+ }
216
+
217
+ textureStore(edgeTex, id.xy, vec4<f32>(edge, edge, edge, 1.0));
218
+ }
219
+ `;
220
+ const cannyNmsR32fWgsl = `
221
+ struct CannyParams {
222
+ lowThreshold: f32,
223
+ highThreshold: f32,
224
+ width: u32,
225
+ height: u32,
226
+ };
227
+
228
+ @group(0) @binding(0) var magnitudeTex: texture_2d<f32>;
229
+ @group(0) @binding(1) var edgeTex: texture_storage_2d<r32float, write>;
230
+ @group(0) @binding(2) var<uniform> params: CannyParams;
231
+
232
+ @compute @workgroup_size(16, 16)
233
+ fn computeNonMaxSuppression(@builtin(global_invocation_id) id: vec3<u32>) {
234
+ if (id.x >= params.width || id.y >= params.height) { return; }
235
+
236
+ let x = i32(id.x);
237
+ let y = i32(id.y);
238
+ let maxCoord = vec2<i32>(i32(params.width) - 1, i32(params.height) - 1);
239
+
240
+ let center = textureLoad(magnitudeTex, vec2<i32>(x, y), 0);
241
+ let mag = center.r;
242
+ let sector = u32(round(center.g));
243
+
244
+ var n1 = 0.0;
245
+ var n2 = 0.0;
246
+
247
+ switch (sector) {
248
+ case 0u: {
249
+ n1 = textureLoad(magnitudeTex, clamp(vec2<i32>(x - 1, y), vec2<i32>(0), maxCoord), 0).r;
250
+ n2 = textureLoad(magnitudeTex, clamp(vec2<i32>(x + 1, y), vec2<i32>(0), maxCoord), 0).r;
251
+ }
252
+ case 1u: {
253
+ n1 = textureLoad(magnitudeTex, clamp(vec2<i32>(x + 1, y - 1), vec2<i32>(0), maxCoord), 0).r;
254
+ n2 = textureLoad(magnitudeTex, clamp(vec2<i32>(x - 1, y + 1), vec2<i32>(0), maxCoord), 0).r;
255
+ }
256
+ case 2u: {
257
+ n1 = textureLoad(magnitudeTex, clamp(vec2<i32>(x, y - 1), vec2<i32>(0), maxCoord), 0).r;
258
+ n2 = textureLoad(magnitudeTex, clamp(vec2<i32>(x, y + 1), vec2<i32>(0), maxCoord), 0).r;
259
+ }
260
+ default: {
261
+ n1 = textureLoad(magnitudeTex, clamp(vec2<i32>(x - 1, y - 1), vec2<i32>(0), maxCoord), 0).r;
262
+ n2 = textureLoad(magnitudeTex, clamp(vec2<i32>(x + 1, y + 1), vec2<i32>(0), maxCoord), 0).r;
263
+ }
264
+ }
265
+
266
+ var edge = 0.0;
267
+ // Non-maximum suppression along gradient sector with directional tie-breaking
268
+ if (mag > n1 && mag >= n2 && mag > 0.0) {
269
+ if (mag >= params.highThreshold) {
270
+ edge = 1.0;
271
+ } else if (mag >= params.lowThreshold) {
272
+ edge = 0.5;
273
+ }
274
+ }
275
+
276
+ textureStore(edgeTex, id.xy, vec4<f32>(edge, 0.0, 0.0, 1.0));
277
+ }
278
+ `;
279
+ var CannyComputePipeline = class {
280
+ sobelPipeline;
281
+ nmsRgba8Pipeline;
282
+ nmsR32fPipeline;
283
+ uniformBuffer;
284
+ cachedIntermediateTexture;
285
+ cachedOutputTexture;
286
+ constructor(device) {
287
+ this.device = device;
288
+ const sobelModule = device.createShaderModule({
289
+ label: "canny_sobel.wgsl",
290
+ code: cannySobelWgsl
291
+ });
292
+ this.sobelPipeline = device.createComputePipeline({
293
+ label: "CannySobelPipeline",
294
+ layout: "auto",
295
+ compute: {
296
+ module: sobelModule,
297
+ entryPoint: "computeSobel"
298
+ }
299
+ });
300
+ const nmsRgba8Module = device.createShaderModule({
301
+ label: "canny_nms_rgba8.wgsl",
302
+ code: cannyNmsRgba8Wgsl
303
+ });
304
+ this.nmsRgba8Pipeline = device.createComputePipeline({
305
+ label: "CannyNmsRgba8Pipeline",
306
+ layout: "auto",
307
+ compute: {
308
+ module: nmsRgba8Module,
309
+ entryPoint: "computeNonMaxSuppression"
310
+ }
311
+ });
312
+ const nmsR32fModule = device.createShaderModule({
313
+ label: "canny_nms_r32f.wgsl",
314
+ code: cannyNmsR32fWgsl
315
+ });
316
+ this.nmsR32fPipeline = device.createComputePipeline({
317
+ label: "CannyNmsR32fPipeline",
318
+ layout: "auto",
319
+ compute: {
320
+ module: nmsR32fModule,
321
+ entryPoint: "computeNonMaxSuppression"
322
+ }
323
+ });
324
+ this.uniformBuffer = device.createBuffer({
325
+ size: 16,
326
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
327
+ label: "canny_uniform_buffer"
328
+ });
329
+ }
330
+ execute(inputTexture, options = {}) {
331
+ const width = inputTexture.width;
332
+ const height = inputTexture.height;
333
+ const lowThreshold = options.low ?? .1;
334
+ const highThreshold = options.high ?? .3;
335
+ const outputFormat = options.outputFormat ?? "rgba8unorm";
336
+ const uniformData = /* @__PURE__ */ new ArrayBuffer(16);
337
+ const f32View = new Float32Array(uniformData);
338
+ const u32View = new Uint32Array(uniformData);
339
+ f32View[0] = lowThreshold;
340
+ f32View[1] = highThreshold;
341
+ u32View[2] = width;
342
+ u32View[3] = height;
343
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, uniformData);
344
+ if (!this.cachedIntermediateTexture || this.cachedIntermediateTexture.width !== width || this.cachedIntermediateTexture.height !== height) {
345
+ this.cachedIntermediateTexture?.destroy();
346
+ this.cachedIntermediateTexture = this.device.createTexture({
347
+ label: "canny_magnitude_intermediate",
348
+ size: [width, height],
349
+ format: "rgba16float",
350
+ usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING
351
+ });
352
+ }
353
+ if (!this.cachedOutputTexture || this.cachedOutputTexture.width !== width || this.cachedOutputTexture.height !== height || this.cachedOutputTexture.format !== outputFormat) {
354
+ this.cachedOutputTexture?.destroy();
355
+ this.cachedOutputTexture = this.device.createTexture({
356
+ label: `canny_edge_output_${outputFormat}`,
357
+ size: [width, height],
358
+ format: outputFormat,
359
+ usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
360
+ });
361
+ }
362
+ const commandEncoder = this.device.createCommandEncoder({ label: "canny_command_encoder" });
363
+ const sobelBindGroup = this.device.createBindGroup({
364
+ layout: this.sobelPipeline.getBindGroupLayout(0),
365
+ entries: [
366
+ {
367
+ binding: 0,
368
+ resource: inputTexture.createView()
369
+ },
370
+ {
371
+ binding: 1,
372
+ resource: this.cachedIntermediateTexture.createView()
373
+ },
374
+ {
375
+ binding: 2,
376
+ resource: { buffer: this.uniformBuffer }
377
+ }
378
+ ]
379
+ });
380
+ const pass1 = commandEncoder.beginComputePass({ label: "canny_sobel_pass" });
381
+ pass1.setPipeline(this.sobelPipeline);
382
+ pass1.setBindGroup(0, sobelBindGroup);
383
+ pass1.dispatchWorkgroups(Math.ceil(width / 16), Math.ceil(height / 16));
384
+ pass1.end();
385
+ const nmsPipeline = outputFormat === "r32float" ? this.nmsR32fPipeline : this.nmsRgba8Pipeline;
386
+ const nmsBindGroup = this.device.createBindGroup({
387
+ layout: nmsPipeline.getBindGroupLayout(0),
388
+ entries: [
389
+ {
390
+ binding: 0,
391
+ resource: this.cachedIntermediateTexture.createView()
392
+ },
393
+ {
394
+ binding: 1,
395
+ resource: this.cachedOutputTexture.createView()
396
+ },
397
+ {
398
+ binding: 2,
399
+ resource: { buffer: this.uniformBuffer }
400
+ }
401
+ ]
402
+ });
403
+ const pass2 = commandEncoder.beginComputePass({ label: "canny_nms_pass" });
404
+ pass2.setPipeline(nmsPipeline);
405
+ pass2.setBindGroup(0, nmsBindGroup);
406
+ pass2.dispatchWorkgroups(Math.ceil(width / 16), Math.ceil(height / 16));
407
+ pass2.end();
408
+ this.device.queue.submit([commandEncoder.finish()]);
409
+ return this.cachedOutputTexture;
410
+ }
411
+ destroy() {
412
+ this.cachedIntermediateTexture?.destroy();
413
+ this.cachedOutputTexture?.destroy();
414
+ this.uniformBuffer.destroy();
415
+ }
416
+ };
417
+ /**
418
+ * @file depth-normals.wgsl.ts
419
+ * Screen-Space Normal Map Reconstruction from Depth Tensor
420
+ * Analytical cross-product of spatial partial derivatives:
421
+ * dP/dx = [1, 0, dD/dx]^T, dP/dy = [0, 1, dD/dy]^T
422
+ * N = normalize(dP/dx x dP/dy) = normalize([-dx, -dy, 1.0])
423
+ */
424
+ const depthNormalsRgba16fWgsl = `
425
+ struct DepthNormalParams {
426
+ width: u32,
427
+ height: u32,
428
+ depthScale: f32,
429
+ _pad: f32,
430
+ };
431
+
432
+ @group(0) @binding(0) var depthTex: texture_2d<f32>;
433
+ @group(0) @binding(1) var normalTex: texture_storage_2d<rgba16float, write>;
434
+ @group(0) @binding(2) var<uniform> params: DepthNormalParams;
435
+
436
+ @compute @workgroup_size(16, 16)
437
+ fn computeNormals(@builtin(global_invocation_id) id: vec3<u32>) {
438
+ if (id.x >= params.width || id.y >= params.height) { return; }
439
+
440
+ let c = id.xy;
441
+ let maxX = params.width - 1u;
442
+ let maxY = params.height - 1u;
443
+
444
+ let left = textureLoad(depthTex, vec2<u32>(max(c.x - 1u, 0u), c.y), 0).r;
445
+ let right = textureLoad(depthTex, vec2<u32>(min(c.x + 1u, maxX), c.y), 0).r;
446
+ let up = textureLoad(depthTex, vec2<u32>(c.x, max(c.y - 1u, 0u)), 0).r;
447
+ let down = textureLoad(depthTex, vec2<u32>(c.x, min(c.y + 1u, maxY)), 0).r;
448
+
449
+ let dx = (right - left) * 0.5 * params.depthScale;
450
+ let dy = (down - up) * 0.5 * params.depthScale;
451
+
452
+ let normal = normalize(vec3<f32>(-dx, -dy, 1.0));
453
+ // Pack [-1, 1] range to [0, 1]
454
+ let packedColor = vec4<f32>(normal * 0.5 + 0.5, 1.0);
455
+ textureStore(normalTex, id.xy, packedColor);
456
+ }
457
+ `;
458
+ const depthNormalsRgba8Wgsl = `
459
+ struct DepthNormalParams {
460
+ width: u32,
461
+ height: u32,
462
+ depthScale: f32,
463
+ _pad: f32,
464
+ };
465
+
466
+ @group(0) @binding(0) var depthTex: texture_2d<f32>;
467
+ @group(0) @binding(1) var normalTex: texture_storage_2d<rgba8unorm, write>;
468
+ @group(0) @binding(2) var<uniform> params: DepthNormalParams;
469
+
470
+ @compute @workgroup_size(16, 16)
471
+ fn computeNormals(@builtin(global_invocation_id) id: vec3<u32>) {
472
+ if (id.x >= params.width || id.y >= params.height) { return; }
473
+
474
+ let c = id.xy;
475
+ let maxX = params.width - 1u;
476
+ let maxY = params.height - 1u;
477
+
478
+ let left = textureLoad(depthTex, vec2<u32>(max(c.x - 1u, 0u), c.y), 0).r;
479
+ let right = textureLoad(depthTex, vec2<u32>(min(c.x + 1u, maxX), c.y), 0).r;
480
+ let up = textureLoad(depthTex, vec2<u32>(c.x, max(c.y - 1u, 0u)), 0).r;
481
+ let down = textureLoad(depthTex, vec2<u32>(c.x, min(c.y + 1u, maxY)), 0).r;
482
+
483
+ let dx = (right - left) * 0.5 * params.depthScale;
484
+ let dy = (down - up) * 0.5 * params.depthScale;
485
+
486
+ let normal = normalize(vec3<f32>(-dx, -dy, 1.0));
487
+ // Pack [-1, 1] range to [0, 1]
488
+ let packedColor = vec4<f32>(normal * 0.5 + 0.5, 1.0);
489
+ textureStore(normalTex, id.xy, packedColor);
490
+ }
491
+ `;
492
+ var DepthNormalsComputePipeline = class {
493
+ normalRgba16fPipeline;
494
+ normalRgba8Pipeline;
495
+ uniformBuffer;
496
+ cachedOutputTexture;
497
+ constructor(device) {
498
+ this.device = device;
499
+ const rgba16fModule = device.createShaderModule({
500
+ label: "depth_normals_rgba16f.wgsl",
501
+ code: depthNormalsRgba16fWgsl
502
+ });
503
+ this.normalRgba16fPipeline = device.createComputePipeline({
504
+ label: "DepthNormalsRgba16fPipeline",
505
+ layout: "auto",
506
+ compute: {
507
+ module: rgba16fModule,
508
+ entryPoint: "computeNormals"
509
+ }
510
+ });
511
+ const rgba8Module = device.createShaderModule({
512
+ label: "depth_normals_rgba8.wgsl",
513
+ code: depthNormalsRgba8Wgsl
514
+ });
515
+ this.normalRgba8Pipeline = device.createComputePipeline({
516
+ label: "DepthNormalsRgba8Pipeline",
517
+ layout: "auto",
518
+ compute: {
519
+ module: rgba8Module,
520
+ entryPoint: "computeNormals"
521
+ }
522
+ });
523
+ this.uniformBuffer = device.createBuffer({
524
+ size: 16,
525
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
526
+ label: "depth_normals_uniform_buffer"
527
+ });
528
+ }
529
+ execute(depthTexture, options = {}) {
530
+ const width = depthTexture.width;
531
+ const height = depthTexture.height;
532
+ const depthScale = options.depthScale ?? 1;
533
+ const outputFormat = options.outputFormat ?? "rgba16float";
534
+ const uniformData = /* @__PURE__ */ new ArrayBuffer(16);
535
+ const u32View = new Uint32Array(uniformData);
536
+ const f32View = new Float32Array(uniformData);
537
+ u32View[0] = width;
538
+ u32View[1] = height;
539
+ f32View[2] = depthScale;
540
+ f32View[3] = 0;
541
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, uniformData);
542
+ if (!this.cachedOutputTexture || this.cachedOutputTexture.width !== width || this.cachedOutputTexture.height !== height || this.cachedOutputTexture.format !== outputFormat) {
543
+ this.cachedOutputTexture?.destroy();
544
+ this.cachedOutputTexture = this.device.createTexture({
545
+ label: `normal_output_${outputFormat}`,
546
+ size: [width, height],
547
+ format: outputFormat,
548
+ usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
549
+ });
550
+ }
551
+ const pipeline = outputFormat === "rgba8unorm" ? this.normalRgba8Pipeline : this.normalRgba16fPipeline;
552
+ const commandEncoder = this.device.createCommandEncoder({ label: "depth_normals_command_encoder" });
553
+ const bindGroup = this.device.createBindGroup({
554
+ layout: pipeline.getBindGroupLayout(0),
555
+ entries: [
556
+ {
557
+ binding: 0,
558
+ resource: depthTexture.createView()
559
+ },
560
+ {
561
+ binding: 1,
562
+ resource: this.cachedOutputTexture.createView()
563
+ },
564
+ {
565
+ binding: 2,
566
+ resource: { buffer: this.uniformBuffer }
567
+ }
568
+ ]
569
+ });
570
+ const pass = commandEncoder.beginComputePass({ label: "depth_normals_compute_pass" });
571
+ pass.setPipeline(pipeline);
572
+ pass.setBindGroup(0, bindGroup);
573
+ pass.dispatchWorkgroups(Math.ceil(width / 16), Math.ceil(height / 16));
574
+ pass.end();
575
+ this.device.queue.submit([commandEncoder.finish()]);
576
+ return this.cachedOutputTexture;
577
+ }
578
+ destroy() {
579
+ this.cachedOutputTexture?.destroy();
580
+ this.uniformBuffer.destroy();
581
+ }
582
+ };
583
+ /**
584
+ * @file face-landmarks.wgsl.ts
585
+ * Native WebGPU WGSL compute shader for ControlNet Face & MediaPipe facial contour rasterization.
586
+ * Renders antialiased facial mesh contours (lips, eyes, brows, nose, oval) directly in VRAM for SDXL ControlNet.
587
+ */
588
+ const faceLandmarksWgsl = `
589
+ struct FaceSegment {
590
+ start: vec2<f32>,
591
+ end: vec2<f32>,
592
+ color: vec4<f32>,
593
+ radius: f32,
594
+ enabled: f32,
595
+ pad: vec2<f32>,
596
+ };
597
+
598
+ struct FaceParams {
599
+ width: u32,
600
+ height: u32,
601
+ numSegments: u32,
602
+ pad: u32,
603
+ };
604
+
605
+ @group(0) @binding(0) var outputTex: texture_storage_2d<rgba8unorm, write>;
606
+ @group(0) @binding(1) var<uniform> params: FaceParams;
607
+ @group(0) @binding(2) var<storage, read> segments: array<FaceSegment>;
608
+
609
+ @compute @workgroup_size(16, 16)
610
+ fn computeFaceLandmarks(@builtin(global_invocation_id) id: vec3<u32>) {
611
+ if (id.x >= params.width || id.y >= params.height) {
612
+ return;
613
+ }
614
+
615
+ let p = vec2<f32>(f32(id.x) + 0.5, f32(id.y) + 0.5);
616
+ var outColor = vec4<f32>(0.0, 0.0, 0.0, 1.0); // Solid black background for SDXL ControlNet
617
+
618
+ let count = params.numSegments;
619
+ for (var i = 0u; i < count; i = i + 1u) {
620
+ let seg = segments[i];
621
+ if (seg.enabled < 0.5) {
622
+ continue;
623
+ }
624
+
625
+ let ab = seg.end - seg.start;
626
+ let ap = p - seg.start;
627
+ let l2 = dot(ab, ab);
628
+
629
+ var t: f32 = 0.0;
630
+ if (l2 > 0.0001) {
631
+ t = clamp(dot(ap, ab) / l2, 0.0, 1.0);
632
+ }
633
+
634
+ let closest = seg.start + t * ab;
635
+ let dist = length(p - closest);
636
+
637
+ if (dist <= seg.radius) {
638
+ let edgeAlpha = clamp(seg.radius - dist + 0.5, 0.0, 1.0);
639
+ outColor = vec4<f32>(mix(outColor.rgb, seg.color.rgb, edgeAlpha * seg.color.a), 1.0);
640
+ }
641
+ }
642
+
643
+ textureStore(outputTex, id.xy, outColor);
644
+ }
645
+ `;
646
+ function buildLoopSegments(indices, color) {
647
+ const segs = [];
648
+ for (let i = 0; i < indices.length - 1; i++) segs.push({
649
+ from: indices[i],
650
+ to: indices[i + 1],
651
+ color
652
+ });
653
+ return segs;
654
+ }
655
+ const CANONICAL_FACE_CONTOURS = [
656
+ ...buildLoopSegments([
657
+ 70,
658
+ 63,
659
+ 105,
660
+ 66,
661
+ 107
662
+ ], [
663
+ 0,
664
+ 1,
665
+ 1,
666
+ 1
667
+ ]),
668
+ ...buildLoopSegments([
669
+ 300,
670
+ 293,
671
+ 334,
672
+ 296,
673
+ 336
674
+ ], [
675
+ 0,
676
+ 1,
677
+ 1,
678
+ 1
679
+ ]),
680
+ ...buildLoopSegments([
681
+ 33,
682
+ 160,
683
+ 158,
684
+ 133,
685
+ 153,
686
+ 144,
687
+ 33
688
+ ], [
689
+ 0,
690
+ 1,
691
+ 0,
692
+ 1
693
+ ]),
694
+ ...buildLoopSegments([
695
+ 263,
696
+ 387,
697
+ 385,
698
+ 362,
699
+ 380,
700
+ 373,
701
+ 263
702
+ ], [
703
+ 0,
704
+ 1,
705
+ 0,
706
+ 1
707
+ ]),
708
+ ...buildLoopSegments([
709
+ 168,
710
+ 6,
711
+ 197,
712
+ 195,
713
+ 4
714
+ ], [
715
+ 1,
716
+ 1,
717
+ 0,
718
+ 1
719
+ ]),
720
+ ...buildLoopSegments([
721
+ 98,
722
+ 97,
723
+ 2,
724
+ 326,
725
+ 327
726
+ ], [
727
+ 1,
728
+ 1,
729
+ 0,
730
+ 1
731
+ ]),
732
+ ...buildLoopSegments([
733
+ 61,
734
+ 185,
735
+ 40,
736
+ 39,
737
+ 37,
738
+ 0,
739
+ 267,
740
+ 269,
741
+ 270,
742
+ 409,
743
+ 291,
744
+ 375,
745
+ 321,
746
+ 405,
747
+ 314,
748
+ 17,
749
+ 84,
750
+ 181,
751
+ 91,
752
+ 146,
753
+ 61
754
+ ], [
755
+ 1,
756
+ .2,
757
+ .2,
758
+ 1
759
+ ]),
760
+ ...buildLoopSegments([
761
+ 78,
762
+ 95,
763
+ 88,
764
+ 178,
765
+ 87,
766
+ 14,
767
+ 317,
768
+ 402,
769
+ 318,
770
+ 324,
771
+ 308,
772
+ 415,
773
+ 310,
774
+ 311,
775
+ 312,
776
+ 13,
777
+ 82,
778
+ 81,
779
+ 80,
780
+ 191,
781
+ 78
782
+ ], [
783
+ 1,
784
+ 0,
785
+ .8,
786
+ 1
787
+ ]),
788
+ ...buildLoopSegments([
789
+ 10,
790
+ 338,
791
+ 297,
792
+ 332,
793
+ 284,
794
+ 251,
795
+ 389,
796
+ 356,
797
+ 454,
798
+ 323,
799
+ 361,
800
+ 288,
801
+ 397,
802
+ 365,
803
+ 379,
804
+ 378,
805
+ 400,
806
+ 377,
807
+ 152,
808
+ 148,
809
+ 176,
810
+ 149,
811
+ 150,
812
+ 136,
813
+ 172,
814
+ 58,
815
+ 132,
816
+ 93,
817
+ 234,
818
+ 127,
819
+ 162,
820
+ 21,
821
+ 54,
822
+ 103,
823
+ 67,
824
+ 109,
825
+ 10
826
+ ], [
827
+ .9,
828
+ .9,
829
+ .9,
830
+ 1
831
+ ])
832
+ ];
833
+ var FaceLandmarksComputePipeline = class {
834
+ computePipeline;
835
+ uniformBuffer;
836
+ storageBuffer;
837
+ cachedOutputTexture;
838
+ constructor(device) {
839
+ this.device = device;
840
+ const shaderModule = device.createShaderModule({
841
+ label: "face_landmarks.wgsl",
842
+ code: faceLandmarksWgsl
843
+ });
844
+ this.computePipeline = device.createComputePipeline({
845
+ label: "FaceLandmarksComputePipeline",
846
+ layout: "auto",
847
+ compute: {
848
+ module: shaderModule,
849
+ entryPoint: "computeFaceLandmarks"
850
+ }
851
+ });
852
+ this.uniformBuffer = device.createBuffer({
853
+ size: 64,
854
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
855
+ label: "face_landmarks_uniform_buffer"
856
+ });
857
+ const storageSize = Math.max(256, CANONICAL_FACE_CONTOURS.length * 48);
858
+ this.storageBuffer = device.createBuffer({
859
+ size: storageSize,
860
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
861
+ label: "face_landmarks_storage_buffer"
862
+ });
863
+ }
864
+ execute(landmarks, options = {}) {
865
+ const width = options.width ?? 1024;
866
+ const height = options.height ?? 1024;
867
+ const lineWidth = options.lineWidth ?? 4;
868
+ const radius = Math.max(1, lineWidth / 2);
869
+ const u32Uniforms = new Uint32Array(4);
870
+ u32Uniforms[0] = width;
871
+ u32Uniforms[1] = height;
872
+ u32Uniforms[2] = CANONICAL_FACE_CONTOURS.length;
873
+ u32Uniforms[3] = 0;
874
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, u32Uniforms);
875
+ const f32Segments = new Float32Array(CANONICAL_FACE_CONTOURS.length * 12);
876
+ for (let i = 0; i < CANONICAL_FACE_CONTOURS.length; i++) {
877
+ const seg = CANONICAL_FACE_CONTOURS[i];
878
+ const ptA = landmarks[seg.from];
879
+ const ptB = landmarks[seg.to];
880
+ const offset = i * 12;
881
+ if (!ptA || !ptB || (ptA.visibility ?? 1) < .2 || (ptB.visibility ?? 1) < .2) {
882
+ f32Segments[offset + 9] = 0;
883
+ continue;
884
+ }
885
+ f32Segments[offset + 0] = ptA.x * width;
886
+ f32Segments[offset + 1] = ptA.y * height;
887
+ f32Segments[offset + 2] = ptB.x * width;
888
+ f32Segments[offset + 3] = ptB.y * height;
889
+ f32Segments[offset + 4] = seg.color[0];
890
+ f32Segments[offset + 5] = seg.color[1];
891
+ f32Segments[offset + 6] = seg.color[2];
892
+ f32Segments[offset + 7] = seg.color[3];
893
+ f32Segments[offset + 8] = radius;
894
+ f32Segments[offset + 9] = 1;
895
+ f32Segments[offset + 10] = 0;
896
+ f32Segments[offset + 11] = 0;
897
+ }
898
+ this.device.queue.writeBuffer(this.storageBuffer, 0, f32Segments);
899
+ if (!this.cachedOutputTexture || this.cachedOutputTexture.width !== width || this.cachedOutputTexture.height !== height) {
900
+ this.cachedOutputTexture?.destroy();
901
+ this.cachedOutputTexture = this.device.createTexture({
902
+ size: {
903
+ width,
904
+ height
905
+ },
906
+ format: "rgba8unorm",
907
+ usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST,
908
+ label: "face_landmarks_output_texture"
909
+ });
910
+ }
911
+ const bindGroup = this.device.createBindGroup({
912
+ label: "FaceLandmarksBindGroup",
913
+ layout: this.computePipeline.getBindGroupLayout(0),
914
+ entries: [
915
+ {
916
+ binding: 0,
917
+ resource: this.cachedOutputTexture.createView()
918
+ },
919
+ {
920
+ binding: 1,
921
+ resource: { buffer: this.uniformBuffer }
922
+ },
923
+ {
924
+ binding: 2,
925
+ resource: { buffer: this.storageBuffer }
926
+ }
927
+ ]
928
+ });
929
+ const commandEncoder = this.device.createCommandEncoder({ label: "FaceLandmarksCommandEncoder" });
930
+ const pass = commandEncoder.beginComputePass({ label: "FaceLandmarksComputePass" });
931
+ pass.setPipeline(this.computePipeline);
932
+ pass.setBindGroup(0, bindGroup);
933
+ pass.dispatchWorkgroups(Math.ceil(width / 16), Math.ceil(height / 16));
934
+ pass.end();
935
+ this.device.queue.submit([commandEncoder.finish()]);
936
+ return this.cachedOutputTexture;
937
+ }
938
+ destroy() {
939
+ this.uniformBuffer.destroy();
940
+ this.storageBuffer.destroy();
941
+ this.cachedOutputTexture?.destroy();
942
+ }
943
+ };
944
+ /**
945
+ * @file optical-flow.wgsl.ts
946
+ * High-Performance Native WebGPU Optical Flow Compute Shaders
947
+ * Implements coarse-to-fine Lucas-Kanade motion vector estimation with
948
+ * spatial structure tensor integration and Tikhonov aperture regularization.
949
+ */
950
+ const opticalFlowDirectWgsl = `
951
+ struct FlowParams {
952
+ width: u32,
953
+ height: u32,
954
+ windowSize: u32, // Half-window radius W (e.g. 2 for 5x5 window)
955
+ regularization: f32, // Tikhonov regularization lambda
956
+ maxDisplacement: f32, // Maximum allowable flow vector length
957
+ _pad0: f32,
958
+ _pad1: f32,
959
+ _pad2: f32,
960
+ };
961
+
962
+ @group(0) @binding(0) var prevTex: texture_2d<f32>;
963
+ @group(0) @binding(1) var currTex: texture_2d<f32>;
964
+ @group(0) @binding(2) var flowTex: texture_storage_2d<rgba16float, write>;
965
+ @group(0) @binding(3) var<uniform> params: FlowParams;
966
+
967
+ fn rgbToLuminance(rgb: vec3<f32>) -> f32 {
968
+ return dot(rgb, vec3<f32>(0.299, 0.587, 0.114));
969
+ }
970
+
971
+ fn sampleLuma(tex: texture_2d<f32>, coord: vec2<i32>) -> f32 {
972
+ let inDims = vec2<f32>(textureDimensions(tex));
973
+ let scaleRatio = inDims / vec2<f32>(f32(params.width), f32(params.height));
974
+ let actualCoord = vec2<i32>(vec2<f32>(coord) * scaleRatio);
975
+ let clamped = clamp(actualCoord, vec2<i32>(0, 0), vec2<i32>(inDims) - vec2<i32>(1, 1));
976
+ let color = textureLoad(tex, clamped, 0);
977
+ return rgbToLuminance(color.rgb);
978
+ }
979
+
980
+ @compute @workgroup_size(16, 16)
981
+ fn computeFlow(@builtin(global_invocation_id) id: vec3<u32>) {
982
+ if (id.x >= params.width || id.y >= params.height) {
983
+ return;
984
+ }
985
+
986
+ let centerCoord = vec2<i32>(i32(id.x), i32(id.y));
987
+ let w = i32(max(params.windowSize, 1u));
988
+
989
+ var sxx: f32 = 0.0;
990
+ var syy: f32 = 0.0;
991
+ var sxy: f32 = 0.0;
992
+ var sxt: f32 = 0.0;
993
+ var syt: f32 = 0.0;
994
+
995
+ for (var dy = -w; dy <= w; dy = dy + 1) {
996
+ for (var dx = -w; dx <= w; dx = dx + 1) {
997
+ let p = centerCoord + vec2<i32>(dx, dy);
998
+
999
+ // Central difference spatial gradients on current frame
1000
+ let lx = sampleLuma(currTex, p - vec2<i32>(1, 0));
1001
+ let rx = sampleLuma(currTex, p + vec2<i32>(1, 0));
1002
+ let uy = sampleLuma(currTex, p - vec2<i32>(0, 1));
1003
+ let dyL = sampleLuma(currTex, p + vec2<i32>(0, 1));
1004
+
1005
+ let ix = (rx - lx) * 0.5;
1006
+ let iy = (dyL - uy) * 0.5;
1007
+
1008
+ // Temporal gradient: difference between current and previous frame
1009
+ let cCurr = sampleLuma(currTex, p);
1010
+ let cPrev = sampleLuma(prevTex, p);
1011
+ let it = cCurr - cPrev;
1012
+
1013
+ // Gaussian spatial falloff weight
1014
+ let distSq = f32(dx * dx + dy * dy);
1015
+ let weight = exp(-distSq / (2.0 * f32(w * w) + 0.1));
1016
+
1017
+ sxx += ix * ix * weight;
1018
+ syy += iy * iy * weight;
1019
+ sxy += ix * iy * weight;
1020
+ sxt += ix * it * weight;
1021
+ syt += iy * it * weight;
1022
+ }
1023
+ }
1024
+
1025
+ // Tikhonov regularization prevents singularity in flat/homogeneous regions
1026
+ let trace = sxx + syy;
1027
+ let reg = max(params.regularization, 1e-4) * max(trace, 1.0);
1028
+ let A = sxx + reg;
1029
+ let B = sxy;
1030
+ let C = syy + reg;
1031
+
1032
+ let det = A * C - B * B;
1033
+ var u: f32 = 0.0;
1034
+ var v: f32 = 0.0;
1035
+
1036
+ if (det > 1e-6) {
1037
+ u = (-sxt * C + syt * B) / det;
1038
+ v = (-syt * A + sxt * B) / det;
1039
+ }
1040
+
1041
+ let mag = length(vec2<f32>(u, v));
1042
+ let maxD = max(params.maxDisplacement, 1.0);
1043
+ if (mag > maxD) {
1044
+ let scale = maxD / mag;
1045
+ u *= scale;
1046
+ v *= scale;
1047
+ }
1048
+
1049
+ textureStore(flowTex, id.xy, vec4<f32>(u, v, min(mag, maxD), 1.0));
1050
+ }
1051
+ `;
1052
+ const opticalFlowRefineWgsl = `
1053
+ struct FlowParams {
1054
+ width: u32,
1055
+ height: u32,
1056
+ windowSize: u32,
1057
+ regularization: f32,
1058
+ maxDisplacement: f32,
1059
+ coarseWidth: u32,
1060
+ coarseHeight: u32,
1061
+ _pad0: f32,
1062
+ };
1063
+
1064
+ @group(0) @binding(0) var prevTex: texture_2d<f32>;
1065
+ @group(0) @binding(1) var currTex: texture_2d<f32>;
1066
+ @group(0) @binding(2) var coarseFlowTex: texture_2d<f32>;
1067
+ @group(0) @binding(3) var fineFlowTex: texture_storage_2d<rgba16float, write>;
1068
+ @group(0) @binding(4) var<uniform> params: FlowParams;
1069
+ @group(0) @binding(5) var bilinearSamp: sampler;
1070
+
1071
+ fn rgbToLuminance(rgb: vec3<f32>) -> f32 {
1072
+ return dot(rgb, vec3<f32>(0.299, 0.587, 0.114));
1073
+ }
1074
+
1075
+ fn sampleLuma(tex: texture_2d<f32>, coord: vec2<i32>) -> f32 {
1076
+ let clamped = clamp(coord, vec2<i32>(0, 0), vec2<i32>(i32(params.width) - 1, i32(params.height) - 1));
1077
+ let color = textureLoad(tex, clamped, 0);
1078
+ return rgbToLuminance(color.rgb);
1079
+ }
1080
+
1081
+ fn sampleWarpedPrevLuma(uv: vec2<f32>, priorFlow: vec2<f32>) -> f32 {
1082
+ let invDims = vec2<f32>(1.0 / f32(params.width), 1.0 / f32(params.height));
1083
+ let warpedUv = clamp(uv - priorFlow * invDims, vec2<f32>(0.0), vec2<f32>(1.0));
1084
+ let sampleColor = textureSampleLevel(prevTex, bilinearSamp, warpedUv, 0.0);
1085
+ return rgbToLuminance(sampleColor.rgb);
1086
+ }
1087
+
1088
+ @compute @workgroup_size(16, 16)
1089
+ fn refineFlow(@builtin(global_invocation_id) id: vec3<u32>) {
1090
+ if (id.x >= params.width || id.y >= params.height) {
1091
+ return;
1092
+ }
1093
+
1094
+ let centerCoord = vec2<i32>(i32(id.x), i32(id.y));
1095
+ let w = i32(max(params.windowSize, 1u));
1096
+ let invDims = vec2<f32>(1.0 / f32(params.width), 1.0 / f32(params.height));
1097
+ let centerUv = (vec2<f32>(id.xy) + 0.5) * invDims;
1098
+
1099
+ // Read upsampled prior flow from coarse scale (scaled by 2x)
1100
+ let coarseCoord = vec2<i32>(centerCoord / 2);
1101
+ let coarseSample = textureLoad(coarseFlowTex, coarseCoord, 0);
1102
+ let priorFlow = coarseSample.xy * 2.0;
1103
+
1104
+ var sxx: f32 = 0.0;
1105
+ var syy: f32 = 0.0;
1106
+ var sxy: f32 = 0.0;
1107
+ var sxt: f32 = 0.0;
1108
+ var syt: f32 = 0.0;
1109
+
1110
+ for (var dy = -w; dy <= w; dy = dy + 1) {
1111
+ for (var dx = -w; dx <= w; dx = dx + 1) {
1112
+ let p = centerCoord + vec2<i32>(dx, dy);
1113
+ let pUv = (vec2<f32>(p) + 0.5) * invDims;
1114
+
1115
+ let lx = sampleLuma(currTex, p - vec2<i32>(1, 0));
1116
+ let rx = sampleLuma(currTex, p + vec2<i32>(1, 0));
1117
+ let uy = sampleLuma(currTex, p - vec2<i32>(0, 1));
1118
+ let dyL = sampleLuma(currTex, p + vec2<i32>(0, 1));
1119
+
1120
+ let ix = (rx - lx) * 0.5;
1121
+ let iy = (dyL - uy) * 0.5;
1122
+
1123
+ // Temporal residual against warped previous frame
1124
+ let cCurr = sampleLuma(currTex, p);
1125
+ let cWarpedPrev = sampleWarpedPrevLuma(pUv, priorFlow);
1126
+ let it = cCurr - cWarpedPrev;
1127
+
1128
+ let distSq = f32(dx * dx + dy * dy);
1129
+ let weight = exp(-distSq / (2.0 * f32(w * w) + 0.1));
1130
+
1131
+ sxx += ix * ix * weight;
1132
+ syy += iy * iy * weight;
1133
+ sxy += ix * iy * weight;
1134
+ sxt += ix * it * weight;
1135
+ syt += iy * it * weight;
1136
+ }
1137
+ }
1138
+
1139
+ let trace = sxx + syy;
1140
+ let reg = max(params.regularization, 1e-4) * max(trace, 1.0);
1141
+ let A = sxx + reg;
1142
+ let B = sxy;
1143
+ let C = syy + reg;
1144
+
1145
+ let det = A * C - B * B;
1146
+ var du: f32 = 0.0;
1147
+ var dv: f32 = 0.0;
1148
+
1149
+ if (det > 1e-6) {
1150
+ du = (-sxt * C + syt * B) / det;
1151
+ dv = (-syt * A + sxt * B) / det;
1152
+ }
1153
+
1154
+ // Combine coarse prior flow with fine residual flow
1155
+ var totalFlow = priorFlow + vec2<f32>(du, dv);
1156
+ let mag = length(totalFlow);
1157
+ let maxD = max(params.maxDisplacement, 1.0);
1158
+ if (mag > maxD) {
1159
+ totalFlow *= (maxD / mag);
1160
+ }
1161
+
1162
+ textureStore(fineFlowTex, id.xy, vec4<f32>(totalFlow.x, totalFlow.y, min(mag, maxD), 1.0));
1163
+ }
1164
+ `;
1165
+ var OpticalFlowComputePipeline = class {
1166
+ directPipeline;
1167
+ refinePipeline;
1168
+ directUniformBuffer;
1169
+ refineUniformBuffer;
1170
+ bilinearSampler;
1171
+ cachedCoarseTexture;
1172
+ cachedOutputTexture;
1173
+ constructor(device) {
1174
+ this.device = device;
1175
+ const directModule = device.createShaderModule({
1176
+ label: "optical_flow_direct.wgsl",
1177
+ code: opticalFlowDirectWgsl
1178
+ });
1179
+ this.directPipeline = device.createComputePipeline({
1180
+ label: "OpticalFlowDirectPipeline",
1181
+ layout: "auto",
1182
+ compute: {
1183
+ module: directModule,
1184
+ entryPoint: "computeFlow"
1185
+ }
1186
+ });
1187
+ const refineModule = device.createShaderModule({
1188
+ label: "optical_flow_refine.wgsl",
1189
+ code: opticalFlowRefineWgsl
1190
+ });
1191
+ this.refinePipeline = device.createComputePipeline({
1192
+ label: "OpticalFlowRefinePipeline",
1193
+ layout: "auto",
1194
+ compute: {
1195
+ module: refineModule,
1196
+ entryPoint: "refineFlow"
1197
+ }
1198
+ });
1199
+ this.directUniformBuffer = device.createBuffer({
1200
+ size: 32,
1201
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
1202
+ label: "optical_flow_direct_uniform"
1203
+ });
1204
+ this.refineUniformBuffer = device.createBuffer({
1205
+ size: 32,
1206
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
1207
+ label: "optical_flow_refine_uniform"
1208
+ });
1209
+ this.bilinearSampler = device.createSampler({
1210
+ label: "optical_flow_bilinear_sampler",
1211
+ magFilter: "linear",
1212
+ minFilter: "linear",
1213
+ addressModeU: "clamp-to-edge",
1214
+ addressModeV: "clamp-to-edge"
1215
+ });
1216
+ }
1217
+ execute(prevTexture, currTexture, options = {}, customEncoder) {
1218
+ const width = currTexture.width;
1219
+ const height = currTexture.height;
1220
+ const windowSize = options?.windowSize ?? 3;
1221
+ const regularization = options?.regularization ?? options?.lambda ?? .05;
1222
+ const scale = options?.scale ?? .5;
1223
+ const maxDisplacement = 64;
1224
+ const outputFormat = options.outputFormat ?? "rgba16float";
1225
+ if (!this.cachedOutputTexture || this.cachedOutputTexture.width !== width || this.cachedOutputTexture.height !== height || this.cachedOutputTexture.format !== outputFormat) {
1226
+ this.cachedOutputTexture?.destroy();
1227
+ this.cachedOutputTexture = this.device.createTexture({
1228
+ label: `optical_flow_output_${outputFormat}`,
1229
+ size: [width, height],
1230
+ format: outputFormat,
1231
+ usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
1232
+ });
1233
+ }
1234
+ const commandEncoder = customEncoder ?? this.device.createCommandEncoder({ label: "optical_flow_command_encoder" });
1235
+ if (scale > .1 && scale < .95 && width >= 64 && height >= 64) {
1236
+ const coarseW = Math.max(16, Math.floor(width * scale));
1237
+ const coarseH = Math.max(16, Math.floor(height * scale));
1238
+ if (!this.cachedCoarseTexture || this.cachedCoarseTexture.width !== coarseW || this.cachedCoarseTexture.height !== coarseH) {
1239
+ this.cachedCoarseTexture?.destroy();
1240
+ this.cachedCoarseTexture = this.device.createTexture({
1241
+ label: "optical_flow_coarse",
1242
+ size: [coarseW, coarseH],
1243
+ format: "rgba16float",
1244
+ usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
1245
+ });
1246
+ }
1247
+ const directData = /* @__PURE__ */ new ArrayBuffer(32);
1248
+ const directU32 = new Uint32Array(directData);
1249
+ const directF32 = new Float32Array(directData);
1250
+ directU32[0] = coarseW;
1251
+ directU32[1] = coarseH;
1252
+ directU32[2] = windowSize;
1253
+ directF32[3] = regularization;
1254
+ directF32[4] = maxDisplacement * scale;
1255
+ this.device.queue.writeBuffer(this.directUniformBuffer, 0, directData);
1256
+ const coarseBindGroup = this.device.createBindGroup({
1257
+ layout: this.directPipeline.getBindGroupLayout(0),
1258
+ entries: [
1259
+ {
1260
+ binding: 0,
1261
+ resource: prevTexture.createView()
1262
+ },
1263
+ {
1264
+ binding: 1,
1265
+ resource: currTexture.createView()
1266
+ },
1267
+ {
1268
+ binding: 2,
1269
+ resource: this.cachedCoarseTexture.createView()
1270
+ },
1271
+ {
1272
+ binding: 3,
1273
+ resource: { buffer: this.directUniformBuffer }
1274
+ }
1275
+ ]
1276
+ });
1277
+ const coarsePass = commandEncoder.beginComputePass({ label: "optical_flow_coarse_pass" });
1278
+ coarsePass.setPipeline(this.directPipeline);
1279
+ coarsePass.setBindGroup(0, coarseBindGroup);
1280
+ coarsePass.dispatchWorkgroups(Math.ceil(coarseW / 16), Math.ceil(coarseH / 16));
1281
+ coarsePass.end();
1282
+ const refineData = /* @__PURE__ */ new ArrayBuffer(32);
1283
+ const refineU32 = new Uint32Array(refineData);
1284
+ const refineF32 = new Float32Array(refineData);
1285
+ refineU32[0] = width;
1286
+ refineU32[1] = height;
1287
+ refineU32[2] = windowSize;
1288
+ refineF32[3] = regularization;
1289
+ refineF32[4] = maxDisplacement;
1290
+ refineU32[5] = coarseW;
1291
+ refineU32[6] = coarseH;
1292
+ this.device.queue.writeBuffer(this.refineUniformBuffer, 0, refineData);
1293
+ const refineBindGroup = this.device.createBindGroup({
1294
+ layout: this.refinePipeline.getBindGroupLayout(0),
1295
+ entries: [
1296
+ {
1297
+ binding: 0,
1298
+ resource: prevTexture.createView()
1299
+ },
1300
+ {
1301
+ binding: 1,
1302
+ resource: currTexture.createView()
1303
+ },
1304
+ {
1305
+ binding: 2,
1306
+ resource: this.cachedCoarseTexture.createView()
1307
+ },
1308
+ {
1309
+ binding: 3,
1310
+ resource: this.cachedOutputTexture.createView()
1311
+ },
1312
+ {
1313
+ binding: 4,
1314
+ resource: { buffer: this.refineUniformBuffer }
1315
+ },
1316
+ {
1317
+ binding: 5,
1318
+ resource: this.bilinearSampler
1319
+ }
1320
+ ]
1321
+ });
1322
+ const finePass = commandEncoder.beginComputePass({ label: "optical_flow_fine_pass" });
1323
+ finePass.setPipeline(this.refinePipeline);
1324
+ finePass.setBindGroup(0, refineBindGroup);
1325
+ finePass.dispatchWorkgroups(Math.ceil(width / 16), Math.ceil(height / 16));
1326
+ finePass.end();
1327
+ } else {
1328
+ const directData = /* @__PURE__ */ new ArrayBuffer(32);
1329
+ const directU32 = new Uint32Array(directData);
1330
+ const directF32 = new Float32Array(directData);
1331
+ directU32[0] = width;
1332
+ directU32[1] = height;
1333
+ directU32[2] = windowSize;
1334
+ directF32[3] = regularization;
1335
+ directF32[4] = maxDisplacement;
1336
+ this.device.queue.writeBuffer(this.directUniformBuffer, 0, directData);
1337
+ const directBindGroup = this.device.createBindGroup({
1338
+ layout: this.directPipeline.getBindGroupLayout(0),
1339
+ entries: [
1340
+ {
1341
+ binding: 0,
1342
+ resource: prevTexture.createView()
1343
+ },
1344
+ {
1345
+ binding: 1,
1346
+ resource: currTexture.createView()
1347
+ },
1348
+ {
1349
+ binding: 2,
1350
+ resource: this.cachedOutputTexture.createView()
1351
+ },
1352
+ {
1353
+ binding: 3,
1354
+ resource: { buffer: this.directUniformBuffer }
1355
+ }
1356
+ ]
1357
+ });
1358
+ const directPass = commandEncoder.beginComputePass({ label: "optical_flow_direct_pass" });
1359
+ directPass.setPipeline(this.directPipeline);
1360
+ directPass.setBindGroup(0, directBindGroup);
1361
+ directPass.dispatchWorkgroups(Math.ceil(width / 16), Math.ceil(height / 16));
1362
+ directPass.end();
1363
+ }
1364
+ if (!customEncoder) this.device.queue.submit([commandEncoder.finish()]);
1365
+ return this.cachedOutputTexture;
1366
+ }
1367
+ destroy() {
1368
+ this.cachedCoarseTexture?.destroy();
1369
+ this.cachedOutputTexture?.destroy();
1370
+ this.directUniformBuffer.destroy();
1371
+ this.refineUniformBuffer.destroy();
1372
+ }
1373
+ };
1374
+ /**
1375
+ * @file pose-skeleton.wgsl.ts
1376
+ * Native WebGPU WGSL compute shader for ControlNet OpenPose skeleton rasterization.
1377
+ * Renders instanced bone cylinders/capsules directly in VRAM without CPU roundtrips.
1378
+ */
1379
+ const poseSkeletonWgsl = `
1380
+ struct Bone {
1381
+ start: vec2<f32>,
1382
+ end: vec2<f32>,
1383
+ color: vec4<f32>,
1384
+ radius: f32,
1385
+ enabled: f32,
1386
+ pad: vec2<f32>,
1387
+ };
1388
+
1389
+ struct SkeletonParams {
1390
+ width: u32,
1391
+ height: u32,
1392
+ numBones: u32,
1393
+ pad: u32,
1394
+ bones: array<Bone, 24>,
1395
+ };
1396
+
1397
+ @group(0) @binding(0) var outputTex: texture_storage_2d<rgba8unorm, write>;
1398
+ @group(0) @binding(1) var<uniform> params: SkeletonParams;
1399
+
1400
+ @compute @workgroup_size(16, 16)
1401
+ fn computePoseSkeleton(@builtin(global_invocation_id) id: vec3<u32>) {
1402
+ if (id.x >= params.width || id.y >= params.height) {
1403
+ return;
1404
+ }
1405
+
1406
+ let p = vec2<f32>(f32(id.x) + 0.5, f32(id.y) + 0.5);
1407
+ var outColor = vec4<f32>(0.0, 0.0, 0.0, 0.0);
1408
+
1409
+ let count = min(params.numBones, 24u);
1410
+ for (var i = 0u; i < count; i = i + 1u) {
1411
+ let bone = params.bones[i];
1412
+ if (bone.enabled < 0.5) {
1413
+ continue;
1414
+ }
1415
+
1416
+ let ab = bone.end - bone.start;
1417
+ let ap = p - bone.start;
1418
+ let l2 = dot(ab, ab);
1419
+
1420
+ var t: f32 = 0.0;
1421
+ if (l2 > 0.0001) {
1422
+ t = clamp(dot(ap, ab) / l2, 0.0, 1.0);
1423
+ }
1424
+
1425
+ let closest = bone.start + t * ab;
1426
+ let dist = length(p - closest);
1427
+
1428
+ if (dist <= bone.radius) {
1429
+ // Sub-pixel edge antialiasing
1430
+ let edgeAlpha = clamp(bone.radius - dist + 0.5, 0.0, 1.0);
1431
+ let a = edgeAlpha * bone.color.a;
1432
+ outColor = vec4<f32>(mix(outColor.rgb, bone.color.rgb, a), max(outColor.a, a));
1433
+ }
1434
+ }
1435
+
1436
+ textureStore(outputTex, id.xy, outColor);
1437
+ }
1438
+ `;
1439
+ const CANONICAL_OPENPOSE_BONES = [
1440
+ {
1441
+ from: 0,
1442
+ to: 11,
1443
+ color: [
1444
+ 0,
1445
+ 1,
1446
+ 1,
1447
+ 1
1448
+ ]
1449
+ },
1450
+ {
1451
+ from: 0,
1452
+ to: 12,
1453
+ color: [
1454
+ 0,
1455
+ 1,
1456
+ 1,
1457
+ 1
1458
+ ]
1459
+ },
1460
+ {
1461
+ from: 11,
1462
+ to: 12,
1463
+ color: [
1464
+ 1,
1465
+ 0,
1466
+ 0,
1467
+ 1
1468
+ ]
1469
+ },
1470
+ {
1471
+ from: 11,
1472
+ to: 13,
1473
+ color: [
1474
+ 1,
1475
+ .333,
1476
+ 0,
1477
+ 1
1478
+ ]
1479
+ },
1480
+ {
1481
+ from: 13,
1482
+ to: 15,
1483
+ color: [
1484
+ 1,
1485
+ .667,
1486
+ 0,
1487
+ 1
1488
+ ]
1489
+ },
1490
+ {
1491
+ from: 12,
1492
+ to: 14,
1493
+ color: [
1494
+ 1,
1495
+ 1,
1496
+ 0,
1497
+ 1
1498
+ ]
1499
+ },
1500
+ {
1501
+ from: 14,
1502
+ to: 16,
1503
+ color: [
1504
+ .667,
1505
+ 1,
1506
+ 0,
1507
+ 1
1508
+ ]
1509
+ },
1510
+ {
1511
+ from: 11,
1512
+ to: 23,
1513
+ color: [
1514
+ .333,
1515
+ 1,
1516
+ 0,
1517
+ 1
1518
+ ]
1519
+ },
1520
+ {
1521
+ from: 12,
1522
+ to: 24,
1523
+ color: [
1524
+ 0,
1525
+ 1,
1526
+ 0,
1527
+ 1
1528
+ ]
1529
+ },
1530
+ {
1531
+ from: 23,
1532
+ to: 24,
1533
+ color: [
1534
+ 0,
1535
+ 1,
1536
+ .333,
1537
+ 1
1538
+ ]
1539
+ },
1540
+ {
1541
+ from: 23,
1542
+ to: 25,
1543
+ color: [
1544
+ 0,
1545
+ 1,
1546
+ .667,
1547
+ 1
1548
+ ]
1549
+ },
1550
+ {
1551
+ from: 25,
1552
+ to: 27,
1553
+ color: [
1554
+ 0,
1555
+ 1,
1556
+ 1,
1557
+ 1
1558
+ ]
1559
+ },
1560
+ {
1561
+ from: 24,
1562
+ to: 26,
1563
+ color: [
1564
+ 0,
1565
+ .667,
1566
+ 1,
1567
+ 1
1568
+ ]
1569
+ },
1570
+ {
1571
+ from: 26,
1572
+ to: 28,
1573
+ color: [
1574
+ 0,
1575
+ .333,
1576
+ 1,
1577
+ 1
1578
+ ]
1579
+ }
1580
+ ];
1581
+ var PoseSkeletonComputePipeline = class {
1582
+ computePipeline;
1583
+ uniformBuffer;
1584
+ cachedOutputTexture;
1585
+ constructor(device) {
1586
+ this.device = device;
1587
+ const shaderModule = device.createShaderModule({
1588
+ label: "pose_skeleton.wgsl",
1589
+ code: poseSkeletonWgsl
1590
+ });
1591
+ this.computePipeline = device.createComputePipeline({
1592
+ label: "PoseSkeletonComputePipeline",
1593
+ layout: "auto",
1594
+ compute: {
1595
+ module: shaderModule,
1596
+ entryPoint: "computePoseSkeleton"
1597
+ }
1598
+ });
1599
+ this.uniformBuffer = device.createBuffer({
1600
+ size: 1280,
1601
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
1602
+ label: "pose_skeleton_uniform_buffer"
1603
+ });
1604
+ }
1605
+ execute(landmarks, options = {}, bones) {
1606
+ const boneDefs = bones ?? CANONICAL_OPENPOSE_BONES;
1607
+ const width = options.width ?? 1024;
1608
+ const height = options.height ?? 1024;
1609
+ const lineWidth = options.lineWidth ?? 6;
1610
+ const radius = Math.max(1, lineWidth / 2);
1611
+ const arrayBuf = /* @__PURE__ */ new ArrayBuffer(1280);
1612
+ const u32View = new Uint32Array(arrayBuf);
1613
+ const f32View = new Float32Array(arrayBuf);
1614
+ u32View[0] = width;
1615
+ u32View[1] = height;
1616
+ u32View[2] = boneDefs.length;
1617
+ u32View[3] = 0;
1618
+ const boneBaseFloatOffset = 4;
1619
+ for (let i = 0; i < boneDefs.length; i++) {
1620
+ const boneDef = boneDefs[i];
1621
+ const ptA = landmarks[boneDef.from];
1622
+ const ptB = landmarks[boneDef.to];
1623
+ const offset = boneBaseFloatOffset + i * 12;
1624
+ if (!ptA || !ptB || (ptA.visibility ?? 1) < .2 || (ptB.visibility ?? 1) < .2) {
1625
+ f32View[offset + 9] = 0;
1626
+ continue;
1627
+ }
1628
+ f32View[offset + 0] = ptA.x * width;
1629
+ f32View[offset + 1] = ptA.y * height;
1630
+ f32View[offset + 2] = ptB.x * width;
1631
+ f32View[offset + 3] = ptB.y * height;
1632
+ f32View[offset + 4] = boneDef.color[0];
1633
+ f32View[offset + 5] = boneDef.color[1];
1634
+ f32View[offset + 6] = boneDef.color[2];
1635
+ f32View[offset + 7] = boneDef.color[3];
1636
+ f32View[offset + 8] = radius;
1637
+ f32View[offset + 9] = 1;
1638
+ }
1639
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, arrayBuf);
1640
+ if (!this.cachedOutputTexture || this.cachedOutputTexture.width !== width || this.cachedOutputTexture.height !== height) {
1641
+ this.cachedOutputTexture?.destroy();
1642
+ this.cachedOutputTexture = this.device.createTexture({
1643
+ label: "openpose_skeleton_texture",
1644
+ size: [width, height],
1645
+ format: "rgba8unorm",
1646
+ usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
1647
+ });
1648
+ }
1649
+ const commandEncoder = this.device.createCommandEncoder({ label: "pose_skeleton_command_encoder" });
1650
+ const bindGroup = this.device.createBindGroup({
1651
+ label: "pose_skeleton_bind_group",
1652
+ layout: this.computePipeline.getBindGroupLayout(0),
1653
+ entries: [{
1654
+ binding: 0,
1655
+ resource: this.cachedOutputTexture.createView({ label: "pose_skeleton_output_view" })
1656
+ }, {
1657
+ binding: 1,
1658
+ resource: { buffer: this.uniformBuffer }
1659
+ }]
1660
+ });
1661
+ const pass = commandEncoder.beginComputePass({ label: "pose_skeleton_compute_pass" });
1662
+ pass.setPipeline(this.computePipeline);
1663
+ pass.setBindGroup(0, bindGroup);
1664
+ pass.dispatchWorkgroups(Math.ceil(width / 16), Math.ceil(height / 16), 1);
1665
+ pass.end();
1666
+ this.device.queue.submit([commandEncoder.finish()]);
1667
+ return this.cachedOutputTexture;
1668
+ }
1669
+ destroy() {
1670
+ this.cachedOutputTexture?.destroy();
1671
+ this.cachedOutputTexture = void 0;
1672
+ this.uniformBuffer.destroy();
1673
+ }
1674
+ };
1675
+ /**
1676
+ * @file segmentation.wgsl.ts
1677
+ * Native WebGPU WGSL compute shader for segmentation mask thresholding and edge feathering.
1678
+ * Outputs crisp alpha mattes directly in VRAM without CPU roundtrips.
1679
+ */
1680
+ const segmentationWgsl = `
1681
+ struct SegParams {
1682
+ threshold: f32,
1683
+ feather: f32,
1684
+ width: u32,
1685
+ height: u32,
1686
+ };
1687
+
1688
+ @group(0) @binding(0) var inputTex: texture_2d<f32>;
1689
+ @group(0) @binding(1) var outputTex: texture_storage_2d<rgba8unorm, write>;
1690
+ @group(0) @binding(2) var<uniform> params: SegParams;
1691
+
1692
+ @compute @workgroup_size(16, 16)
1693
+ fn computeSegmentation(@builtin(global_invocation_id) id: vec3<u32>) {
1694
+ if (id.x >= params.width || id.y >= params.height) {
1695
+ return;
1696
+ }
1697
+
1698
+ let coord = vec2<i32>(i32(id.x), i32(id.y));
1699
+ let sample = textureLoad(inputTex, coord, 0);
1700
+
1701
+ // Luminance or alpha channel extraction
1702
+ let rawAlpha = max(sample.a, dot(sample.rgb, vec3<f32>(0.299, 0.587, 0.114)));
1703
+
1704
+ let lower = max(0.0, params.threshold - params.feather);
1705
+ let upper = min(1.0, params.threshold + params.feather);
1706
+ let alpha = smoothstep(lower, upper, rawAlpha);
1707
+
1708
+ textureStore(outputTex, id.xy, vec4<f32>(alpha, alpha, alpha, 1.0));
1709
+ }
1710
+ `;
1711
+ var SegmentationComputePipeline = class {
1712
+ computePipeline;
1713
+ uniformBuffer;
1714
+ cachedOutputTexture;
1715
+ constructor(device) {
1716
+ this.device = device;
1717
+ const shaderModule = device.createShaderModule({
1718
+ label: "segmentation.wgsl",
1719
+ code: segmentationWgsl
1720
+ });
1721
+ this.computePipeline = device.createComputePipeline({
1722
+ label: "SegmentationComputePipeline",
1723
+ layout: "auto",
1724
+ compute: {
1725
+ module: shaderModule,
1726
+ entryPoint: "computeSegmentation"
1727
+ }
1728
+ });
1729
+ this.uniformBuffer = device.createBuffer({
1730
+ size: 16,
1731
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
1732
+ label: "segmentation_uniform_buffer"
1733
+ });
1734
+ }
1735
+ execute(inputTexture, options = {}) {
1736
+ const width = inputTexture.width;
1737
+ const height = inputTexture.height;
1738
+ const threshold = options.threshold ?? .5;
1739
+ const feather = options.feather ?? .05;
1740
+ const arrayBuf = /* @__PURE__ */ new ArrayBuffer(16);
1741
+ const f32View = new Float32Array(arrayBuf);
1742
+ const u32View = new Uint32Array(arrayBuf);
1743
+ f32View[0] = threshold;
1744
+ f32View[1] = feather;
1745
+ u32View[2] = width;
1746
+ u32View[3] = height;
1747
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, arrayBuf);
1748
+ if (!this.cachedOutputTexture || this.cachedOutputTexture.width !== width || this.cachedOutputTexture.height !== height) {
1749
+ this.cachedOutputTexture?.destroy();
1750
+ this.cachedOutputTexture = this.device.createTexture({
1751
+ label: "segmentation_output_texture",
1752
+ size: [width, height],
1753
+ format: "rgba8unorm",
1754
+ usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
1755
+ });
1756
+ }
1757
+ const commandEncoder = this.device.createCommandEncoder({ label: "segmentation_command_encoder" });
1758
+ const bindGroup = this.device.createBindGroup({
1759
+ label: "segmentation_bind_group",
1760
+ layout: this.computePipeline.getBindGroupLayout(0),
1761
+ entries: [
1762
+ {
1763
+ binding: 0,
1764
+ resource: inputTexture.createView({ label: "segmentation_input_view" })
1765
+ },
1766
+ {
1767
+ binding: 1,
1768
+ resource: this.cachedOutputTexture.createView({ label: "segmentation_output_view" })
1769
+ },
1770
+ {
1771
+ binding: 2,
1772
+ resource: { buffer: this.uniformBuffer }
1773
+ }
1774
+ ]
1775
+ });
1776
+ const pass = commandEncoder.beginComputePass({ label: "segmentation_compute_pass" });
1777
+ pass.setPipeline(this.computePipeline);
1778
+ pass.setBindGroup(0, bindGroup);
1779
+ pass.dispatchWorkgroups(Math.ceil(width / 16), Math.ceil(height / 16), 1);
1780
+ pass.end();
1781
+ this.device.queue.submit([commandEncoder.finish()]);
1782
+ return this.cachedOutputTexture;
1783
+ }
1784
+ destroy() {
1785
+ this.cachedOutputTexture?.destroy();
1786
+ this.cachedOutputTexture = void 0;
1787
+ this.uniformBuffer.destroy();
1788
+ }
1789
+ };
1790
+ /**
1791
+ * @file temporal-warp-blend.wgsl.ts
1792
+ * Native WebGPU Forward Warping & Adaptive Photometric Temporal Blend Compute Shaders
1793
+ * Warps previous frame forward along motion vectors and blends adaptively with current
1794
+ * frame to eliminate generative AI video flicker with zero ghosting.
1795
+ */
1796
+ const temporalWarpBlendRgba8Wgsl = `
1797
+ struct WarpBlendParams {
1798
+ width: u32,
1799
+ height: u32,
1800
+ blendWeight: f32, // Base current frame weight alpha (e.g. 0.35)
1801
+ disocclusionThreshold: f32, // Photometric error cutoff for fallback to curr frame
1802
+ maxMotionPixels: f32, // Speed cutoff for fallback to curr frame
1803
+ isFirstFrame: f32, // 1.0 = pass-through first frame, 0.0 = temporal blend
1804
+ _pad0: f32,
1805
+ _pad1: f32,
1806
+ };
1807
+
1808
+ @group(0) @binding(0) var prevTex: texture_2d<f32>;
1809
+ @group(0) @binding(1) var currTex: texture_2d<f32>;
1810
+ @group(0) @binding(2) var flowTex: texture_2d<f32>;
1811
+ @group(0) @binding(3) var outTex: texture_storage_2d<rgba8unorm, write>;
1812
+ @group(0) @binding(4) var<uniform> params: WarpBlendParams;
1813
+ @group(0) @binding(5) var bilinearSamp: sampler;
1814
+
1815
+ @compute @workgroup_size(16, 16)
1816
+ fn warpBlend(@builtin(global_invocation_id) id: vec3<u32>) {
1817
+ if (id.x >= params.width || id.y >= params.height) {
1818
+ return;
1819
+ }
1820
+
1821
+ let coord = vec2<i32>(i32(id.x), i32(id.y));
1822
+ let currColor = textureLoad(currTex, coord, 0);
1823
+
1824
+ // If first frame or scene cut reset, pass through current frame directly
1825
+ if (params.isFirstFrame > 0.5) {
1826
+ textureStore(outTex, id.xy, currColor);
1827
+ return;
1828
+ }
1829
+
1830
+ let dims = vec2<f32>(f32(params.width), f32(params.height));
1831
+ let invDims = vec2<f32>(1.0 / dims.x, 1.0 / dims.y);
1832
+ let uv = (vec2<f32>(id.xy) + 0.5) * invDims;
1833
+
1834
+ // Read motion vector (u, v) in pixel units
1835
+ let flowSample = textureLoad(flowTex, coord, 0);
1836
+ let flow = flowSample.xy;
1837
+ let speed = length(flow);
1838
+
1839
+ // Motion-compensated backward warp coordinate pointing to previous frame
1840
+ let warpedUv = clamp(uv - flow * invDims, vec2<f32>(0.0), vec2<f32>(1.0));
1841
+ let warpedPrev = textureSampleLevel(prevTex, bilinearSamp, warpedUv, 0.0);
1842
+
1843
+ // Photometric consistency error normalized to [0, 1] range (1 / sqrt(3) ~= 0.57735027)
1844
+ let colorDiff = length(currColor.rgb - warpedPrev.rgb) * 0.57735027;
1845
+
1846
+ // Adaptive blend weight:
1847
+ // - Coherent motion (low diff, low speed): alpha = blendWeight (strong deflicker smoothing)
1848
+ // - Disocclusion or extreme motion (high diff): alpha -> 1.0 (fall back to curr frame, no ghosting)
1849
+ let tLow = params.disocclusionThreshold;
1850
+ let tHigh = params.disocclusionThreshold * 1.5;
1851
+ let errFactor = smoothstep(tLow, tHigh, colorDiff);
1852
+ let speedFactor = smoothstep(params.maxMotionPixels * 0.5, params.maxMotionPixels, speed);
1853
+
1854
+ let fallbackFactor = max(errFactor, speedFactor);
1855
+ let alpha = clamp(mix(params.blendWeight, 1.0, fallbackFactor), 0.0, 1.0);
1856
+
1857
+ let blendedRgb = mix(warpedPrev.rgb, currColor.rgb, alpha);
1858
+ let blendedA = mix(warpedPrev.a, currColor.a, alpha);
1859
+
1860
+ textureStore(outTex, id.xy, vec4<f32>(blendedRgb, blendedA));
1861
+ }
1862
+ `;
1863
+ const temporalWarpBlendRgba16fWgsl = `
1864
+ struct WarpBlendParams {
1865
+ width: u32,
1866
+ height: u32,
1867
+ blendWeight: f32,
1868
+ disocclusionThreshold: f32,
1869
+ maxMotionPixels: f32,
1870
+ isFirstFrame: f32,
1871
+ _pad0: f32,
1872
+ _pad1: f32,
1873
+ };
1874
+
1875
+ @group(0) @binding(0) var prevTex: texture_2d<f32>;
1876
+ @group(0) @binding(1) var currTex: texture_2d<f32>;
1877
+ @group(0) @binding(2) var flowTex: texture_2d<f32>;
1878
+ @group(0) @binding(3) var outTex: texture_storage_2d<rgba16float, write>;
1879
+ @group(0) @binding(4) var<uniform> params: WarpBlendParams;
1880
+ @group(0) @binding(5) var bilinearSamp: sampler;
1881
+
1882
+ @compute @workgroup_size(16, 16)
1883
+ fn warpBlend(@builtin(global_invocation_id) id: vec3<u32>) {
1884
+ if (id.x >= params.width || id.y >= params.height) {
1885
+ return;
1886
+ }
1887
+
1888
+ let coord = vec2<i32>(i32(id.x), i32(id.y));
1889
+ let currColor = textureLoad(currTex, coord, 0);
1890
+
1891
+ if (params.isFirstFrame > 0.5) {
1892
+ textureStore(outTex, id.xy, currColor);
1893
+ return;
1894
+ }
1895
+
1896
+ let dims = vec2<f32>(f32(params.width), f32(params.height));
1897
+ let invDims = vec2<f32>(1.0 / dims.x, 1.0 / dims.y);
1898
+ let uv = (vec2<f32>(id.xy) + 0.5) * invDims;
1899
+
1900
+ let flowSample = textureLoad(flowTex, coord, 0);
1901
+ let flow = flowSample.xy;
1902
+ let speed = length(flow);
1903
+
1904
+ let warpedUv = clamp(uv - flow * invDims, vec2<f32>(0.0), vec2<f32>(1.0));
1905
+ let warpedPrev = textureSampleLevel(prevTex, bilinearSamp, warpedUv, 0.0);
1906
+
1907
+ // Photometric consistency error normalized to [0, 1] range (1 / sqrt(3) ~= 0.57735027)
1908
+ let colorDiff = length(currColor.rgb - warpedPrev.rgb) * 0.57735027;
1909
+
1910
+ let tLow = params.disocclusionThreshold;
1911
+ let tHigh = params.disocclusionThreshold * 1.5;
1912
+ let errFactor = smoothstep(tLow, tHigh, colorDiff);
1913
+ let speedFactor = smoothstep(params.maxMotionPixels * 0.5, params.maxMotionPixels, speed);
1914
+
1915
+ let fallbackFactor = max(errFactor, speedFactor);
1916
+ let alpha = clamp(mix(params.blendWeight, 1.0, fallbackFactor), 0.0, 1.0);
1917
+
1918
+ let blendedRgb = mix(warpedPrev.rgb, currColor.rgb, alpha);
1919
+ let blendedA = mix(warpedPrev.a, currColor.a, alpha);
1920
+
1921
+ textureStore(outTex, id.xy, vec4<f32>(blendedRgb, blendedA));
1922
+ }
1923
+ `;
1924
+ var TemporalDeflickerPipeline = class {
1925
+ flowPipeline;
1926
+ rgba8Pipeline;
1927
+ rgba16fPipeline;
1928
+ uniformBuffer;
1929
+ bilinearSampler;
1930
+ historyTexture;
1931
+ cachedOutputTexture;
1932
+ constructor(device) {
1933
+ this.device = device;
1934
+ this.flowPipeline = new OpticalFlowComputePipeline(device);
1935
+ const rgba8Module = device.createShaderModule({
1936
+ label: "temporal_warp_blend_rgba8.wgsl",
1937
+ code: temporalWarpBlendRgba8Wgsl
1938
+ });
1939
+ this.rgba8Pipeline = device.createComputePipeline({
1940
+ label: "TemporalWarpBlendRgba8Pipeline",
1941
+ layout: "auto",
1942
+ compute: {
1943
+ module: rgba8Module,
1944
+ entryPoint: "warpBlend"
1945
+ }
1946
+ });
1947
+ const rgba16fModule = device.createShaderModule({
1948
+ label: "temporal_warp_blend_rgba16f.wgsl",
1949
+ code: temporalWarpBlendRgba16fWgsl
1950
+ });
1951
+ this.rgba16fPipeline = device.createComputePipeline({
1952
+ label: "TemporalWarpBlendRgba16fPipeline",
1953
+ layout: "auto",
1954
+ compute: {
1955
+ module: rgba16fModule,
1956
+ entryPoint: "warpBlend"
1957
+ }
1958
+ });
1959
+ this.uniformBuffer = device.createBuffer({
1960
+ size: 32,
1961
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
1962
+ label: "temporal_deflicker_uniform"
1963
+ });
1964
+ this.bilinearSampler = device.createSampler({
1965
+ label: "temporal_deflicker_sampler",
1966
+ magFilter: "linear",
1967
+ minFilter: "linear",
1968
+ addressModeU: "clamp-to-edge",
1969
+ addressModeV: "clamp-to-edge"
1970
+ });
1971
+ }
1972
+ execute(currTexture, options = {}, customEncoder) {
1973
+ const width = currTexture.width;
1974
+ const height = currTexture.height;
1975
+ const rawBlendWeight = options.blendWeight ?? .35;
1976
+ const blendWeight = typeof rawBlendWeight === "number" ? rawBlendWeight : Number(rawBlendWeight);
1977
+ const disocclusionThreshold = options.disocclusionThreshold ?? .15;
1978
+ const maxMotionPixels = options.maxMotionPixels ?? 64;
1979
+ const format = currTexture.format;
1980
+ const isRgba16f = format === "rgba16float";
1981
+ if (!this.cachedOutputTexture || this.cachedOutputTexture.width !== width || this.cachedOutputTexture.height !== height || this.cachedOutputTexture.format !== format) {
1982
+ this.cachedOutputTexture?.destroy();
1983
+ this.cachedOutputTexture = this.device.createTexture({
1984
+ label: `deflickered_output_${format}`,
1985
+ size: [width, height],
1986
+ format,
1987
+ usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
1988
+ });
1989
+ }
1990
+ if (!this.historyTexture || this.historyTexture.width !== width || this.historyTexture.height !== height) {
1991
+ this.historyTexture?.destroy();
1992
+ this.historyTexture = this.device.createTexture({
1993
+ label: "deflicker_history_texture",
1994
+ size: [width, height],
1995
+ format,
1996
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC
1997
+ });
1998
+ const commandEncoder$1 = customEncoder ?? this.device.createCommandEncoder({ label: "deflicker_first_frame_encoder" });
1999
+ commandEncoder$1.copyTextureToTexture({ texture: currTexture }, { texture: this.historyTexture }, [width, height]);
2000
+ commandEncoder$1.copyTextureToTexture({ texture: currTexture }, { texture: this.cachedOutputTexture }, [width, height]);
2001
+ if (!customEncoder) this.device.queue.submit([commandEncoder$1.finish()]);
2002
+ return this.cachedOutputTexture;
2003
+ }
2004
+ const flowTexture = this.flowPipeline.execute(this.historyTexture, currTexture, options.opticalFlow, customEncoder);
2005
+ const uniformData = /* @__PURE__ */ new ArrayBuffer(32);
2006
+ const u32View = new Uint32Array(uniformData);
2007
+ const f32View = new Float32Array(uniformData);
2008
+ u32View[0] = width;
2009
+ u32View[1] = height;
2010
+ f32View[2] = blendWeight;
2011
+ f32View[3] = disocclusionThreshold;
2012
+ f32View[4] = maxMotionPixels;
2013
+ f32View[5] = 0;
2014
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, uniformData);
2015
+ const pipeline = isRgba16f ? this.rgba16fPipeline : this.rgba8Pipeline;
2016
+ const commandEncoder = customEncoder ?? this.device.createCommandEncoder({ label: "deflicker_blend_encoder" });
2017
+ const bindGroup = this.device.createBindGroup({
2018
+ layout: pipeline.getBindGroupLayout(0),
2019
+ entries: [
2020
+ {
2021
+ binding: 0,
2022
+ resource: this.historyTexture.createView()
2023
+ },
2024
+ {
2025
+ binding: 1,
2026
+ resource: currTexture.createView()
2027
+ },
2028
+ {
2029
+ binding: 2,
2030
+ resource: flowTexture.createView()
2031
+ },
2032
+ {
2033
+ binding: 3,
2034
+ resource: this.cachedOutputTexture.createView()
2035
+ },
2036
+ {
2037
+ binding: 4,
2038
+ resource: { buffer: this.uniformBuffer }
2039
+ },
2040
+ {
2041
+ binding: 5,
2042
+ resource: this.bilinearSampler
2043
+ }
2044
+ ]
2045
+ });
2046
+ const pass = commandEncoder.beginComputePass({ label: "deflicker_blend_pass" });
2047
+ pass.setPipeline(pipeline);
2048
+ pass.setBindGroup(0, bindGroup);
2049
+ pass.dispatchWorkgroups(Math.ceil(width / 16), Math.ceil(height / 16));
2050
+ pass.end();
2051
+ commandEncoder.copyTextureToTexture({ texture: this.cachedOutputTexture }, { texture: this.historyTexture }, [width, height]);
2052
+ if (!customEncoder) this.device.queue.submit([commandEncoder.finish()]);
2053
+ return this.cachedOutputTexture;
2054
+ }
2055
+ reset() {
2056
+ this.historyTexture?.destroy();
2057
+ this.historyTexture = void 0;
2058
+ }
2059
+ destroy() {
2060
+ this.flowPipeline.destroy();
2061
+ this.historyTexture?.destroy();
2062
+ this.cachedOutputTexture?.destroy();
2063
+ this.uniformBuffer.destroy();
2064
+ }
2065
+ };
2066
+ var TensorPipeline = class TensorPipeline$1 {
2067
+ id;
2068
+ cannyOptions;
2069
+ depthNormalsOptions;
2070
+ poseSkeletonOptions;
2071
+ faceLandmarksOptions;
2072
+ segmentationOptions;
2073
+ opticalFlowOptions;
2074
+ deflickerOptions;
2075
+ multiplexer = new ControlNetMultiplexer();
2076
+ cannyPipeline;
2077
+ depthNormalsPipeline;
2078
+ posePipeline;
2079
+ facePipeline;
2080
+ segmentationPipeline;
2081
+ opticalFlowPipeline;
2082
+ deflickerPipeline;
2083
+ prevInputTexture;
2084
+ constructor(source) {
2085
+ this.source = source;
2086
+ this.id = `tensor-${Math.random().toString(36).slice(2, 9)}`;
2087
+ }
2088
+ static from(source) {
2089
+ return new TensorPipeline$1(source);
2090
+ }
2091
+ canny(options = {}) {
2092
+ this.cannyOptions = options;
2093
+ return this;
2094
+ }
2095
+ depthNormals(options = {}) {
2096
+ this.depthNormalsOptions = options;
2097
+ return this;
2098
+ }
2099
+ poseSkeleton(options = {}) {
2100
+ this.poseSkeletonOptions = options;
2101
+ return this;
2102
+ }
2103
+ pose(landmarks, options = {}) {
2104
+ this.poseSkeletonOptions = {
2105
+ ...options,
2106
+ landmarks
2107
+ };
2108
+ return this;
2109
+ }
2110
+ faceLandmarks(options = {}) {
2111
+ this.faceLandmarksOptions = options;
2112
+ return this;
2113
+ }
2114
+ face(landmarks, options = {}) {
2115
+ this.faceLandmarksOptions = {
2116
+ ...options,
2117
+ landmarks
2118
+ };
2119
+ return this;
2120
+ }
2121
+ segmentation(options = {}) {
2122
+ this.segmentationOptions = options;
2123
+ return this;
2124
+ }
2125
+ opticalFlow(options = {}) {
2126
+ this.opticalFlowOptions = options;
2127
+ return this;
2128
+ }
2129
+ deflicker(options = {}) {
2130
+ this.deflickerOptions = options;
2131
+ return this;
2132
+ }
2133
+ getMultiplexer() {
2134
+ return this.multiplexer;
2135
+ }
2136
+ async execute(device, overrideSourceTexture) {
2137
+ let inputTexture = overrideSourceTexture;
2138
+ if (!inputTexture && typeof this.source?.createView === "function") inputTexture = this.source;
2139
+ if (!inputTexture) throw new Error("[TensorPipeline.execute] No GPUTexture available for tensor compute execution. Pass a valid GPUTexture to execute() or initialize with a GPUTexture source.");
2140
+ if (this.cannyOptions) {
2141
+ if (!this.cannyPipeline) this.cannyPipeline = new CannyComputePipeline(device);
2142
+ const cannyTex = this.cannyPipeline.execute(inputTexture, this.cannyOptions);
2143
+ this.multiplexer.set("canny", cannyTex);
2144
+ }
2145
+ if (this.depthNormalsOptions) {
2146
+ if (!this.depthNormalsPipeline) this.depthNormalsPipeline = new DepthNormalsComputePipeline(device);
2147
+ const normalTex = this.depthNormalsPipeline.execute(inputTexture, this.depthNormalsOptions);
2148
+ this.multiplexer.set("normals", normalTex);
2149
+ }
2150
+ if (this.poseSkeletonOptions?.landmarks) {
2151
+ if (!this.posePipeline) this.posePipeline = new PoseSkeletonComputePipeline(device);
2152
+ const skeletonTex = this.posePipeline.execute(this.poseSkeletonOptions.landmarks, {
2153
+ width: this.poseSkeletonOptions.width ?? inputTexture.width,
2154
+ height: this.poseSkeletonOptions.height ?? inputTexture.height,
2155
+ lineWidth: this.poseSkeletonOptions.lineWidth
2156
+ });
2157
+ this.multiplexer.set("poseSkeleton", skeletonTex);
2158
+ }
2159
+ if (this.faceLandmarksOptions?.landmarks) {
2160
+ if (!this.facePipeline) this.facePipeline = new FaceLandmarksComputePipeline(device);
2161
+ const faceTex = this.facePipeline.execute(this.faceLandmarksOptions.landmarks, {
2162
+ width: this.faceLandmarksOptions.width ?? inputTexture.width,
2163
+ height: this.faceLandmarksOptions.height ?? inputTexture.height,
2164
+ lineWidth: this.faceLandmarksOptions.lineWidth
2165
+ });
2166
+ this.multiplexer.set("faceLandmarks", faceTex);
2167
+ }
2168
+ if (this.segmentationOptions) {
2169
+ if (!this.segmentationPipeline) this.segmentationPipeline = new SegmentationComputePipeline(device);
2170
+ const segTex = this.segmentationPipeline.execute(inputTexture, this.segmentationOptions);
2171
+ this.multiplexer.set("segmentationMask", segTex);
2172
+ }
2173
+ if (this.opticalFlowOptions) {
2174
+ if (!this.opticalFlowPipeline) this.opticalFlowPipeline = new OpticalFlowComputePipeline(device);
2175
+ const prevTex = this.prevInputTexture ?? inputTexture;
2176
+ const flowTex = this.opticalFlowPipeline.execute(prevTex, inputTexture, this.opticalFlowOptions);
2177
+ this.multiplexer.set("motionVectors", flowTex);
2178
+ }
2179
+ if (this.deflickerOptions) {
2180
+ if (!this.deflickerPipeline) this.deflickerPipeline = new TemporalDeflickerPipeline(device);
2181
+ const deflickeredTex = this.deflickerPipeline.execute(inputTexture, this.deflickerOptions);
2182
+ this.multiplexer.set("deflickered", deflickeredTex);
2183
+ }
2184
+ this.prevInputTexture = inputTexture;
2185
+ return this.multiplexer.getOutputs();
2186
+ }
2187
+ toConfig() {
2188
+ return {
2189
+ canny: this.cannyOptions,
2190
+ depthNormals: this.depthNormalsOptions,
2191
+ poseSkeleton: this.poseSkeletonOptions,
2192
+ faceLandmarks: this.faceLandmarksOptions,
2193
+ segmentation: this.segmentationOptions,
2194
+ opticalFlow: this.opticalFlowOptions,
2195
+ deflicker: this.deflickerOptions
2196
+ };
2197
+ }
2198
+ toNode() {
2199
+ return {
2200
+ id: this.id,
2201
+ kind: "tensor",
2202
+ source: this.source,
2203
+ config: this.toConfig()
2204
+ };
2205
+ }
2206
+ destroy() {
2207
+ this.cannyPipeline?.destroy();
2208
+ this.depthNormalsPipeline?.destroy();
2209
+ this.posePipeline?.destroy();
2210
+ this.facePipeline?.destroy();
2211
+ this.segmentationPipeline?.destroy();
2212
+ this.opticalFlowPipeline?.destroy();
2213
+ this.deflickerPipeline?.destroy();
2214
+ this.multiplexer.destroy();
2215
+ }
2216
+ };
2217
+
2218
+ //#endregion
2219
+ export { PoseSkeletonComputePipeline as a, OpticalFlowComputePipeline as i, ControlNetMultiplexer as n, TemporalDeflickerPipeline as o, DepthNormalsComputePipeline as r, TensorPipeline as s, CannyComputePipeline as t };
2220
+ //# sourceMappingURL=dist-C_hjvkdN.mjs.map