@bloopjs/toodle 0.0.100

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 (358) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/dist/Toodle.d.ts +304 -0
  4. package/dist/Toodle.d.ts.map +1 -0
  5. package/dist/colors/mod.d.ts +872 -0
  6. package/dist/colors/mod.d.ts.map +1 -0
  7. package/dist/coreTypes/Color.d.ts +7 -0
  8. package/dist/coreTypes/Color.d.ts.map +1 -0
  9. package/dist/coreTypes/Point.d.ts +8 -0
  10. package/dist/coreTypes/Point.d.ts.map +1 -0
  11. package/dist/coreTypes/Size.d.ts +5 -0
  12. package/dist/coreTypes/Size.d.ts.map +1 -0
  13. package/dist/coreTypes/Transform.d.ts +16 -0
  14. package/dist/coreTypes/Transform.d.ts.map +1 -0
  15. package/dist/coreTypes/Vec2.d.ts +8 -0
  16. package/dist/coreTypes/Vec2.d.ts.map +1 -0
  17. package/dist/coreTypes/mod.d.ts +6 -0
  18. package/dist/coreTypes/mod.d.ts.map +1 -0
  19. package/dist/docs/snippets/add-remove-children.d.ts +1 -0
  20. package/dist/docs/snippets/basic-quad.d.ts +1 -0
  21. package/dist/docs/snippets/filter-linear.d.ts +1 -0
  22. package/dist/docs/snippets/filter-nearest.d.ts +1 -0
  23. package/dist/docs/snippets/flipxy.d.ts +1 -0
  24. package/dist/docs/snippets/hello-text.d.ts +1 -0
  25. package/dist/docs/snippets/jumbo-textures.d.ts +1 -0
  26. package/dist/docs/snippets/layer.d.ts +1 -0
  27. package/dist/docs/snippets/layout-edges.d.ts +1 -0
  28. package/dist/docs/snippets/layout-screen-and-world-space.d.ts +1 -0
  29. package/dist/docs/snippets/postprocess.d.ts +1 -0
  30. package/dist/docs/snippets/quad-size-scale.d.ts +1 -0
  31. package/dist/docs/snippets/quickstart.d.ts +1 -0
  32. package/dist/docs/snippets/repeat-texture-loading.d.ts +1 -0
  33. package/dist/docs/snippets/screen-shaders.d.ts +1 -0
  34. package/dist/docs/snippets/shader-color-flash.d.ts +1 -0
  35. package/dist/docs/snippets/shader-default.d.ts +1 -0
  36. package/dist/docs/snippets/shader-fill.d.ts +1 -0
  37. package/dist/docs/snippets/shapes-line.d.ts +1 -0
  38. package/dist/docs/snippets/sprite-region.d.ts +1 -0
  39. package/dist/docs/snippets/text-alignment.d.ts +1 -0
  40. package/dist/docs/snippets/text-shrink-to-fit.d.ts +1 -0
  41. package/dist/docs/snippets/text-word-wrap.d.ts +1 -0
  42. package/dist/docs/snippets/texture-bundles-prebaked.d.ts +1 -0
  43. package/dist/docs/snippets/texture-bundles.d.ts +1 -0
  44. package/dist/docs/snippets/transforms.d.ts +1 -0
  45. package/dist/docs/snippets/transparent-cropping.d.ts +1 -0
  46. package/dist/examples/0-hello.d.ts +1 -0
  47. package/dist/examples/1-hello.d.ts +1 -0
  48. package/dist/examples/1-hello.d.ts.map +1 -0
  49. package/dist/examples/1-quad.d.ts +1 -0
  50. package/dist/examples/10-resize.d.ts +1 -0
  51. package/dist/examples/10-resize.d.ts.map +1 -0
  52. package/dist/examples/11-bundle-test.d.ts +1 -0
  53. package/dist/examples/11-bundle-test.d.ts.map +1 -0
  54. package/dist/examples/12-transparent-pixel-cropping.d.ts +1 -0
  55. package/dist/examples/12-transparent-pixel-cropping.d.ts.map +1 -0
  56. package/dist/examples/13-crop.d.ts +1 -0
  57. package/dist/examples/13-crop.d.ts.map +1 -0
  58. package/dist/examples/14-bundle-bench.d.ts +1 -0
  59. package/dist/examples/14-bundle-bench.d.ts.map +1 -0
  60. package/dist/examples/15-text-layer.d.ts +1 -0
  61. package/dist/examples/15-text-layer.d.ts.map +1 -0
  62. package/dist/examples/16-jumbo-texture.d.ts +1 -0
  63. package/dist/examples/16-jumbo-textures.d.ts +1 -0
  64. package/dist/examples/16-screen-shader.d.ts +1 -0
  65. package/dist/examples/16-screen-shader.d.ts.map +1 -0
  66. package/dist/examples/17-lighting.d.ts +1 -0
  67. package/dist/examples/17-lighting.d.ts.map +1 -0
  68. package/dist/examples/17-translations.d.ts +1 -0
  69. package/dist/examples/18-blur.d.ts +1 -0
  70. package/dist/examples/19-postprocess.d.ts +1 -0
  71. package/dist/examples/19-screenshader.d.ts +1 -0
  72. package/dist/examples/2-shapes.d.ts +1 -0
  73. package/dist/examples/2-shapes.d.ts.map +1 -0
  74. package/dist/examples/3-shader.d.ts +1 -0
  75. package/dist/examples/3-shader.d.ts.map +1 -0
  76. package/dist/examples/4-shader-bench.d.ts +1 -0
  77. package/dist/examples/4-shader-bench.d.ts.map +1 -0
  78. package/dist/examples/5-z.d.ts +1 -0
  79. package/dist/examples/5-z.d.ts.map +1 -0
  80. package/dist/examples/6-atlas.d.ts +1 -0
  81. package/dist/examples/6-atlas.d.ts.map +1 -0
  82. package/dist/examples/7-text.d.ts +1 -0
  83. package/dist/examples/7-text.d.ts.map +1 -0
  84. package/dist/examples/8-text-bench.d.ts +1 -0
  85. package/dist/examples/8-text-bench.d.ts.map +1 -0
  86. package/dist/examples/9-alignment.d.ts +1 -0
  87. package/dist/examples/9-alignment.d.ts.map +1 -0
  88. package/dist/examples/main.d.ts +1 -0
  89. package/dist/examples/main.d.ts.map +1 -0
  90. package/dist/examples/util.d.ts +82 -0
  91. package/dist/examples/util.d.ts.map +1 -0
  92. package/dist/limits.d.ts +23 -0
  93. package/dist/limits.d.ts.map +1 -0
  94. package/dist/math/angle.d.ts +13 -0
  95. package/dist/math/angle.d.ts.map +1 -0
  96. package/dist/math/matrix.d.ts +26 -0
  97. package/dist/math/matrix.d.ts.map +1 -0
  98. package/dist/math/mod.d.ts +3 -0
  99. package/dist/math/mod.d.ts.map +1 -0
  100. package/dist/mod.d.ts +17 -0
  101. package/dist/mod.d.ts.map +1 -0
  102. package/dist/mod.js +19665 -0
  103. package/dist/mod.js.map +41 -0
  104. package/dist/postprocess.d.ts +10 -0
  105. package/dist/postprocess.d.ts.map +1 -0
  106. package/dist/scene/Batcher.d.ts +20 -0
  107. package/dist/scene/Batcher.d.ts.map +1 -0
  108. package/dist/scene/Camera.d.ts +16 -0
  109. package/dist/scene/Camera.d.ts.map +1 -0
  110. package/dist/scene/JumboQuadNode.d.ts +29 -0
  111. package/dist/scene/JumboQuadNode.d.ts.map +1 -0
  112. package/dist/scene/QuadNode.d.ts +159 -0
  113. package/dist/scene/QuadNode.d.ts.map +1 -0
  114. package/dist/scene/RenderComponent.d.ts +11 -0
  115. package/dist/scene/RenderComponent.d.ts.map +1 -0
  116. package/dist/scene/SceneNode.d.ts +300 -0
  117. package/dist/scene/SceneNode.d.ts.map +1 -0
  118. package/dist/scene/mod.d.ts +5 -0
  119. package/dist/scene/mod.d.ts.map +1 -0
  120. package/dist/screen/mod.d.ts +2 -0
  121. package/dist/screen/mod.d.ts.map +1 -0
  122. package/dist/screen/resolution.d.ts +5 -0
  123. package/dist/screen/resolution.d.ts.map +1 -0
  124. package/dist/shaders/EngineUniform.d.ts +9 -0
  125. package/dist/shaders/EngineUniform.d.ts.map +1 -0
  126. package/dist/shaders/IShader.d.ts +15 -0
  127. package/dist/shaders/IShader.d.ts.map +1 -0
  128. package/dist/shaders/QuadShader.d.ts +18 -0
  129. package/dist/shaders/QuadShader.d.ts.map +1 -0
  130. package/dist/shaders/ShaderDescriptor.d.ts +7 -0
  131. package/dist/shaders/ShaderDescriptor.d.ts.map +1 -0
  132. package/dist/shaders/mod.d.ts +6 -0
  133. package/dist/shaders/mod.d.ts.map +1 -0
  134. package/dist/shaders/parser.d.ts +8 -0
  135. package/dist/shaders/parser.d.ts.map +1 -0
  136. package/dist/shaders/postprocess/blur.d.ts +3 -0
  137. package/dist/shaders/postprocess/blur.d.ts.map +1 -0
  138. package/dist/shaders/postprocess/mod.d.ts +17 -0
  139. package/dist/shaders/postprocess/mod.d.ts.map +1 -0
  140. package/dist/shaders/samplers.d.ts +3 -0
  141. package/dist/shaders/samplers.d.ts.map +1 -0
  142. package/dist/shaders/wgsl/example.wgsl.d.ts +3 -0
  143. package/dist/shaders/wgsl/example.wgsl.d.ts.map +1 -0
  144. package/dist/shaders/wgsl/hello.wgsl.d.ts +3 -0
  145. package/dist/shaders/wgsl/hello.wgsl.d.ts.map +1 -0
  146. package/dist/shaders/wgsl/helloInstanced.wgsl.d.ts +3 -0
  147. package/dist/shaders/wgsl/helloInstanced.wgsl.d.ts.map +1 -0
  148. package/dist/shaders/wgsl/quad.wgsl.d.ts +3 -0
  149. package/dist/shaders/wgsl/quad.wgsl.d.ts.map +1 -0
  150. package/dist/src/Toodle.d.ts +303 -0
  151. package/dist/src/Toodle.d.ts.map +1 -0
  152. package/dist/src/colors/mod.d.ts +871 -0
  153. package/dist/src/coreTypes/Color.d.ts +6 -0
  154. package/dist/src/coreTypes/Color.d.ts.map +1 -0
  155. package/dist/src/coreTypes/Point.d.ts +7 -0
  156. package/dist/src/coreTypes/Point.d.ts.map +1 -0
  157. package/dist/src/coreTypes/Size.d.ts +4 -0
  158. package/dist/src/coreTypes/Size.d.ts.map +1 -0
  159. package/dist/src/coreTypes/Transform.d.ts +15 -0
  160. package/dist/src/coreTypes/Transform.d.ts.map +1 -0
  161. package/dist/src/coreTypes/Vec2.d.ts +7 -0
  162. package/dist/src/coreTypes/Vec2.d.ts.map +1 -0
  163. package/dist/src/coreTypes/mod.d.ts +5 -0
  164. package/dist/src/coreTypes/mod.d.ts.map +1 -0
  165. package/dist/src/limits.d.ts +22 -0
  166. package/dist/src/limits.d.ts.map +1 -0
  167. package/dist/src/math/angle.d.ts +12 -0
  168. package/dist/src/math/angle.d.ts.map +1 -0
  169. package/dist/src/math/matrix.d.ts +25 -0
  170. package/dist/src/math/matrix.d.ts.map +1 -0
  171. package/dist/src/math/mod.d.ts +2 -0
  172. package/dist/src/math/mod.d.ts.map +1 -0
  173. package/dist/src/mod.d.ts +16 -0
  174. package/dist/src/mod.d.ts.map +1 -0
  175. package/dist/src/postprocess.d.ts +10 -0
  176. package/dist/src/postprocess.d.ts.map +1 -0
  177. package/dist/src/scene/Batcher.d.ts +19 -0
  178. package/dist/src/scene/Batcher.d.ts.map +1 -0
  179. package/dist/src/scene/Camera.d.ts +15 -0
  180. package/dist/src/scene/Camera.d.ts.map +1 -0
  181. package/dist/src/scene/JumboQuadNode.d.ts +28 -0
  182. package/dist/src/scene/QuadNode.d.ts +158 -0
  183. package/dist/src/scene/QuadNode.d.ts.map +1 -0
  184. package/dist/src/scene/RenderComponent.d.ts +10 -0
  185. package/dist/src/scene/RenderComponent.d.ts.map +1 -0
  186. package/dist/src/scene/SceneNode.d.ts +299 -0
  187. package/dist/src/scene/SceneNode.d.ts.map +1 -0
  188. package/dist/src/scene/mod.d.ts +4 -0
  189. package/dist/src/scene/mod.d.ts.map +1 -0
  190. package/dist/src/screen/mod.d.ts +1 -0
  191. package/dist/src/screen/mod.d.ts.map +1 -0
  192. package/dist/src/screen/resolution.d.ts +4 -0
  193. package/dist/src/screen/resolution.d.ts.map +1 -0
  194. package/dist/src/shaders/EngineUniform.d.ts +8 -0
  195. package/dist/src/shaders/EngineUniform.d.ts.map +1 -0
  196. package/dist/src/shaders/IShader.d.ts +14 -0
  197. package/dist/src/shaders/IShader.d.ts.map +1 -0
  198. package/dist/src/shaders/QuadShader.d.ts +17 -0
  199. package/dist/src/shaders/QuadShader.d.ts.map +1 -0
  200. package/dist/src/shaders/ShaderDescriptor.d.ts +6 -0
  201. package/dist/src/shaders/ShaderDescriptor.d.ts.map +1 -0
  202. package/dist/src/shaders/mod.d.ts +5 -0
  203. package/dist/src/shaders/mod.d.ts.map +1 -0
  204. package/dist/src/shaders/parser.d.ts +7 -0
  205. package/dist/src/shaders/parser.d.ts.map +1 -0
  206. package/dist/src/shaders/postprocess/blur.d.ts +2 -0
  207. package/dist/src/shaders/postprocess/mod.d.ts +16 -0
  208. package/dist/src/shaders/postprocess/postprocess.d.ts +8 -0
  209. package/dist/src/shaders/postprocess/util.d.ts +2 -0
  210. package/dist/src/shaders/samplers.d.ts +2 -0
  211. package/dist/src/shaders/samplers.d.ts.map +1 -0
  212. package/dist/src/shaders/wgsl/example.wgsl.d.ts +2 -0
  213. package/dist/src/shaders/wgsl/example.wgsl.d.ts.map +1 -0
  214. package/dist/src/shaders/wgsl/hello.wgsl.d.ts +2 -0
  215. package/dist/src/shaders/wgsl/hello.wgsl.d.ts.map +1 -0
  216. package/dist/src/shaders/wgsl/helloInstanced.wgsl.d.ts +2 -0
  217. package/dist/src/shaders/wgsl/helloInstanced.wgsl.d.ts.map +1 -0
  218. package/dist/src/shaders/wgsl/quad.wgsl.d.ts +2 -0
  219. package/dist/src/shaders/wgsl/quad.wgsl.d.ts.map +1 -0
  220. package/dist/src/text/FontPipeline.d.ts +13 -0
  221. package/dist/src/text/FontPipeline.d.ts.map +1 -0
  222. package/dist/src/text/MsdfFont.d.ts +81 -0
  223. package/dist/src/text/MsdfFont.d.ts.map +1 -0
  224. package/dist/src/text/TextFormatting.d.ts +18 -0
  225. package/dist/src/text/TextFormatting.d.ts.map +1 -0
  226. package/dist/src/text/TextNode.d.ts +18 -0
  227. package/dist/src/text/TextNode.d.ts.map +1 -0
  228. package/dist/src/text/TextShader.d.ts +14 -0
  229. package/dist/src/text/TextShader.d.ts.map +1 -0
  230. package/dist/src/text/mod.d.ts +3 -0
  231. package/dist/src/text/mod.d.ts.map +1 -0
  232. package/dist/src/text/shaping.d.ts +38 -0
  233. package/dist/src/text/shaping.d.ts.map +1 -0
  234. package/dist/src/text/text.wgsl.d.ts +2 -0
  235. package/dist/src/text/text.wgsl.d.ts.map +1 -0
  236. package/dist/src/textures/AssetManager.d.ts +181 -0
  237. package/dist/src/textures/AssetManager.d.ts.map +1 -0
  238. package/dist/src/textures/NewTextureComputeShader.d.ts +28 -0
  239. package/dist/src/textures/TextureComputeShader.d.ts +20 -0
  240. package/dist/src/textures/TextureComputeShader.d.ts.map +1 -0
  241. package/dist/src/textures/crop.wgsl.d.ts +2 -0
  242. package/dist/src/textures/mod.d.ts +1 -0
  243. package/dist/src/textures/mod.d.ts.map +1 -0
  244. package/dist/src/textures/pixel-scraping.wgsl.d.ts +2 -0
  245. package/dist/src/textures/pixel-scraping.wgsl.d.ts.map +1 -0
  246. package/dist/src/textures/texture-processing.wgsl.d.ts +2 -0
  247. package/dist/src/textures/types.d.ts +176 -0
  248. package/dist/src/textures/types.d.ts.map +1 -0
  249. package/dist/src/textures/util.d.ts +7 -0
  250. package/dist/src/textures/util.d.ts.map +1 -0
  251. package/dist/src/utils/assert.d.ts +1 -0
  252. package/dist/src/utils/assert.d.ts.map +1 -0
  253. package/dist/src/utils/boilerplate.d.ts +10 -0
  254. package/dist/src/utils/boilerplate.d.ts.map +1 -0
  255. package/dist/src/utils/error.d.ts +7 -0
  256. package/dist/src/utils/error.d.ts.map +1 -0
  257. package/dist/src/utils/mod.d.ts +2 -0
  258. package/dist/src/utils/mod.d.ts.map +1 -0
  259. package/dist/src/utils/pool.d.ts +22 -0
  260. package/dist/src/utils/pool.d.ts.map +1 -0
  261. package/dist/test/math/matrix.test.d.ts +1 -0
  262. package/dist/test/scene/Batcher.test.d.ts +1 -0
  263. package/dist/test/scene/SceneNode.test.d.ts +1 -0
  264. package/dist/test/shader/parser.test.d.ts +1 -0
  265. package/dist/text/FontPipeline.d.ts +14 -0
  266. package/dist/text/FontPipeline.d.ts.map +1 -0
  267. package/dist/text/MsdfFont.d.ts +82 -0
  268. package/dist/text/MsdfFont.d.ts.map +1 -0
  269. package/dist/text/TextFormatting.d.ts +19 -0
  270. package/dist/text/TextFormatting.d.ts.map +1 -0
  271. package/dist/text/TextNode.d.ts +19 -0
  272. package/dist/text/TextNode.d.ts.map +1 -0
  273. package/dist/text/TextShader.d.ts +15 -0
  274. package/dist/text/TextShader.d.ts.map +1 -0
  275. package/dist/text/mod.d.ts +4 -0
  276. package/dist/text/mod.d.ts.map +1 -0
  277. package/dist/text/shaping.d.ts +39 -0
  278. package/dist/text/shaping.d.ts.map +1 -0
  279. package/dist/text/text.wgsl.d.ts +3 -0
  280. package/dist/text/text.wgsl.d.ts.map +1 -0
  281. package/dist/textures/AssetManager.d.ts +182 -0
  282. package/dist/textures/AssetManager.d.ts.map +1 -0
  283. package/dist/textures/TextureComputeShader.d.ts +21 -0
  284. package/dist/textures/TextureComputeShader.d.ts.map +1 -0
  285. package/dist/textures/mod.d.ts +2 -0
  286. package/dist/textures/mod.d.ts.map +1 -0
  287. package/dist/textures/pixel-scraping.wgsl.d.ts +3 -0
  288. package/dist/textures/pixel-scraping.wgsl.d.ts.map +1 -0
  289. package/dist/textures/types.d.ts +177 -0
  290. package/dist/textures/types.d.ts.map +1 -0
  291. package/dist/textures/util.d.ts +8 -0
  292. package/dist/textures/util.d.ts.map +1 -0
  293. package/dist/utils/assert.d.ts +2 -0
  294. package/dist/utils/assert.d.ts.map +1 -0
  295. package/dist/utils/boilerplate.d.ts +11 -0
  296. package/dist/utils/boilerplate.d.ts.map +1 -0
  297. package/dist/utils/error.d.ts +8 -0
  298. package/dist/utils/error.d.ts.map +1 -0
  299. package/dist/utils/mod.d.ts +3 -0
  300. package/dist/utils/mod.d.ts.map +1 -0
  301. package/dist/utils/pool.d.ts +23 -0
  302. package/dist/utils/pool.d.ts.map +1 -0
  303. package/package.json +47 -0
  304. package/src/Toodle.ts +853 -0
  305. package/src/colors/mod.ts +151 -0
  306. package/src/coreTypes/Color.ts +1 -0
  307. package/src/coreTypes/Point.ts +7 -0
  308. package/src/coreTypes/Size.ts +4 -0
  309. package/src/coreTypes/Transform.ts +16 -0
  310. package/src/coreTypes/Vec2.ts +7 -0
  311. package/src/coreTypes/mod.ts +5 -0
  312. package/src/globals.d.ts +4 -0
  313. package/src/limits.ts +23 -0
  314. package/src/math/angle.ts +17 -0
  315. package/src/math/matrix.ts +99 -0
  316. package/src/math/mod.ts +2 -0
  317. package/src/mod.ts +22 -0
  318. package/src/scene/Batcher.ts +61 -0
  319. package/src/scene/Camera.ts +69 -0
  320. package/src/scene/JumboQuadNode.ts +219 -0
  321. package/src/scene/QuadNode.ts +403 -0
  322. package/src/scene/RenderComponent.ts +12 -0
  323. package/src/scene/SceneNode.ts +668 -0
  324. package/src/scene/mod.ts +4 -0
  325. package/src/screen/mod.ts +1 -0
  326. package/src/screen/resolution.ts +1 -0
  327. package/src/shaders/EngineUniform.ts +11 -0
  328. package/src/shaders/IShader.ts +20 -0
  329. package/src/shaders/QuadShader.ts +288 -0
  330. package/src/shaders/ShaderDescriptor.ts +6 -0
  331. package/src/shaders/mod.ts +5 -0
  332. package/src/shaders/parser.ts +221 -0
  333. package/src/shaders/postprocess/blur.ts +245 -0
  334. package/src/shaders/postprocess/mod.ts +71 -0
  335. package/src/shaders/samplers.ts +13 -0
  336. package/src/shaders/wgsl/example.wgsl.ts +24 -0
  337. package/src/shaders/wgsl/hello.wgsl.ts +62 -0
  338. package/src/shaders/wgsl/helloInstanced.wgsl.ts +46 -0
  339. package/src/shaders/wgsl/quad.wgsl.ts +140 -0
  340. package/src/text/FontPipeline.ts +212 -0
  341. package/src/text/MsdfFont.ts +190 -0
  342. package/src/text/TextFormatting.ts +28 -0
  343. package/src/text/TextNode.ts +82 -0
  344. package/src/text/TextShader.ts +223 -0
  345. package/src/text/mod.ts +8 -0
  346. package/src/text/shaping.ts +280 -0
  347. package/src/text/text.wgsl.ts +149 -0
  348. package/src/textures/AssetManager.ts +746 -0
  349. package/src/textures/TextureComputeShader.ts +434 -0
  350. package/src/textures/mod.ts +1 -0
  351. package/src/textures/pixel-scraping.wgsl.ts +131 -0
  352. package/src/textures/types.ts +182 -0
  353. package/src/textures/util.ts +352 -0
  354. package/src/utils/assert.ts +5 -0
  355. package/src/utils/boilerplate.ts +110 -0
  356. package/src/utils/error.ts +14 -0
  357. package/src/utils/mod.ts +2 -0
  358. package/src/utils/pool.ts +42 -0
@@ -0,0 +1,288 @@
1
+ import {
2
+ makeShaderDataDefinitions,
3
+ makeStructuredView,
4
+ type StructuredView,
5
+ } from "webgpu-utils";
6
+ import { WgslReflect } from "wgsl_reflect";
7
+ import type { SceneNode } from "../scene/SceneNode";
8
+ import type { AssetManager } from "../textures/AssetManager";
9
+ import { assert } from "../utils/assert";
10
+ import {
11
+ attachVertexInstanceBuffer,
12
+ createGpuPipeline,
13
+ getGpuPipelineDescriptor,
14
+ setVertexInstanceBufferLayout,
15
+ } from "../utils/boilerplate";
16
+ import type { EngineUniform } from "./EngineUniform";
17
+ import type { IShader } from "./IShader";
18
+ import {
19
+ codeWithLineNumbers,
20
+ combineShaderCode,
21
+ struct2BufferLayout,
22
+ } from "./parser";
23
+ import { pixelArtSampler, smoothSampler } from "./samplers";
24
+ import quadWgsl from "./wgsl/quad.wgsl";
25
+
26
+ export type QuadShaderOpts = {
27
+ assetManager?: AssetManager;
28
+ blendMode?: GPUBlendState;
29
+ };
30
+
31
+ export class QuadShader implements IShader {
32
+ label: string;
33
+ code: string;
34
+
35
+ #uniformValues: StructuredView;
36
+ #instanceData: InstanceData;
37
+ #instanceIndex = 0;
38
+ #instanceCount;
39
+
40
+ #device: GPUDevice;
41
+ #pipeline: GPURenderPipeline;
42
+ #bindGroups: GPUBindGroup[] = [];
43
+ #uniformBuffer: GPUBuffer;
44
+
45
+ startFrame(device: GPUDevice, uniform: EngineUniform) {
46
+ this.#instanceIndex = 0;
47
+
48
+ this.#uniformValues.set(uniform);
49
+ this.#uniformValues.set({
50
+ viewProjection: uniform.viewProjectionMatrix,
51
+ resolution: [uniform.resolution.width, uniform.resolution.height],
52
+ });
53
+
54
+ // Write view projection matrix to uniform buffer
55
+ device.queue.writeBuffer(
56
+ this.#uniformBuffer,
57
+ 0,
58
+ this.#uniformValues.arrayBuffer,
59
+ );
60
+ }
61
+
62
+ processBatch(renderPass: GPURenderPassEncoder, nodes: SceneNode[]) {
63
+ renderPass.setPipeline(this.#pipeline);
64
+ const batchStartInstanceIndex = this.#instanceIndex;
65
+
66
+ // Count for the number of instances in the buffer...
67
+ let instanceCount = 0;
68
+
69
+ if (nodes.length > this.#instanceCount) {
70
+ throw new Error(
71
+ `ToodleInstanceCap: ${nodes.length} instances enqueued, max is ${this.#instanceCount} for ${this.label} shader`,
72
+ );
73
+ }
74
+
75
+ for (let i = 0; i < nodes.length; i++) {
76
+ if (!this.#instanceData) {
77
+ continue;
78
+ }
79
+ const instance = nodes[i];
80
+ assert(instance.renderComponent, "instance has no render component");
81
+ const floatOffset =
82
+ ((batchStartInstanceIndex + instanceCount) *
83
+ this.#instanceData.bufferLayout.arrayStride) /
84
+ Float32Array.BYTES_PER_ELEMENT;
85
+
86
+ instanceCount += instance.renderComponent.writeInstance(
87
+ instance,
88
+ this.#instanceData.cpuBuffer,
89
+ floatOffset,
90
+ );
91
+ }
92
+
93
+ if (this.#instanceData) {
94
+ const byteOffset =
95
+ batchStartInstanceIndex * this.#instanceData.bufferLayout.arrayStride;
96
+ const byteLength =
97
+ instanceCount * this.#instanceData.bufferLayout.arrayStride;
98
+
99
+ this.#device.queue.writeBuffer(
100
+ this.#instanceData.gpuBuffer,
101
+ byteOffset,
102
+ this.#instanceData.cpuBuffer,
103
+ byteOffset / Float32Array.BYTES_PER_ELEMENT,
104
+ byteLength / Float32Array.BYTES_PER_ELEMENT,
105
+ );
106
+
107
+ attachVertexInstanceBuffer(renderPass, this.#instanceData.gpuBuffer);
108
+
109
+ for (let i = 0; i < this.#bindGroups.length; i++) {
110
+ renderPass.setBindGroup(i, this.#bindGroups[i]);
111
+ }
112
+ }
113
+
114
+ this.#instanceIndex += instanceCount;
115
+
116
+ renderPass.draw(4, instanceCount, 0, batchStartInstanceIndex);
117
+ return 1;
118
+ }
119
+
120
+ endFrame() {}
121
+
122
+ constructor(
123
+ label: string,
124
+ assetManager: AssetManager,
125
+ device: GPUDevice,
126
+ presentationFormat: GPUTextureFormat,
127
+ userCode: string,
128
+ instanceCount: number,
129
+ blendMode?: GPUBlendState,
130
+ ) {
131
+ this.label = label;
132
+
133
+ // Combine user code with base quad shader code
134
+ const shaderDescriptor = combineShaderCode(label, quadWgsl, userCode);
135
+
136
+ // Create shader module from combined code
137
+ let module: GPUShaderModule;
138
+ try {
139
+ module = device.createShaderModule({
140
+ label,
141
+ code: shaderDescriptor.code,
142
+ });
143
+ } catch (e) {
144
+ console.error(codeWithLineNumbers(shaderDescriptor.code));
145
+ throw e;
146
+ }
147
+
148
+ // Store combined code for debugging
149
+ this.code = shaderDescriptor.code;
150
+
151
+ // Create blend state
152
+ const blend = blendMode ?? {
153
+ color: {
154
+ srcFactor: "src-alpha",
155
+ dstFactor: "one-minus-src-alpha",
156
+ operation: "add",
157
+ },
158
+ alpha: {
159
+ srcFactor: "one",
160
+ dstFactor: "one-minus-src-alpha",
161
+ operation: "add",
162
+ },
163
+ };
164
+
165
+ // Create instance data from shader code
166
+ const ast = new WgslReflect(shaderDescriptor.code);
167
+ const instanceStruct = ast.structs.find((s) =>
168
+ s.name.endsWith("InstanceData"),
169
+ );
170
+ if (!instanceStruct) {
171
+ console.error(codeWithLineNumbers(shaderDescriptor.code));
172
+ throw new Error(
173
+ "Quad shader has no instance struct. The wgsl is required to contain a struct ending in InstanceData.",
174
+ );
175
+ }
176
+ const bufferLayout = struct2BufferLayout(instanceStruct);
177
+ this.#instanceData = {
178
+ bufferLayout,
179
+ cpuBuffer: new Float32Array(
180
+ (bufferLayout.arrayStride * instanceCount) /
181
+ Float32Array.BYTES_PER_ELEMENT,
182
+ ),
183
+ gpuBuffer: device.createBuffer({
184
+ size: bufferLayout.arrayStride * instanceCount,
185
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
186
+ label: `${label} instance data`,
187
+ }),
188
+ };
189
+
190
+ // Create pipeline descriptor
191
+ const pipelineDescriptor = getGpuPipelineDescriptor(
192
+ shaderDescriptor,
193
+ module,
194
+ presentationFormat,
195
+ blend,
196
+ );
197
+
198
+ // Set vertex instance buffer layout
199
+ setVertexInstanceBufferLayout(
200
+ pipelineDescriptor,
201
+ this.#instanceData.bufferLayout,
202
+ );
203
+
204
+ // Create pipeline
205
+ this.#pipeline = createGpuPipeline(
206
+ device,
207
+ shaderDescriptor,
208
+ pipelineDescriptor,
209
+ );
210
+
211
+ // Reference texture atlas
212
+ const textureAtlas = assetManager.textureAtlas;
213
+
214
+ // Store device
215
+ this.#device = device;
216
+
217
+ // Create uniform buffer for engine uniforms (mat3x3 viewProjection)
218
+ const defs = makeShaderDataDefinitions(this.code);
219
+ this.#uniformValues = makeStructuredView(defs.uniforms.engineUniform);
220
+ this.#uniformBuffer = device.createBuffer({
221
+ label: `${label} engine uniform buffer`,
222
+ size: this.#uniformValues.arrayBuffer.byteLength,
223
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
224
+ });
225
+
226
+ // Create bind groups
227
+ this.#bindGroups = setQuadBindGroups(
228
+ label,
229
+ device,
230
+ this.#pipeline,
231
+ textureAtlas,
232
+ this.#uniformBuffer,
233
+ );
234
+
235
+ this.#instanceCount = instanceCount;
236
+ }
237
+ }
238
+
239
+ function setQuadBindGroups(
240
+ label: string,
241
+ device: GPUDevice,
242
+ pipeline: GPURenderPipeline,
243
+ textureAtlas: GPUTexture,
244
+ buffer: GPUBuffer,
245
+ ) {
246
+ const bindGroup = device.createBindGroup({
247
+ label: `${label} engine bind group`,
248
+ layout: pipeline.getBindGroupLayout(0),
249
+ entries: [
250
+ {
251
+ binding: 0,
252
+ resource: {
253
+ buffer,
254
+ },
255
+ },
256
+ {
257
+ binding: 1,
258
+ resource: device.createSampler(smoothSampler),
259
+ },
260
+ {
261
+ binding: 2,
262
+ resource: device.createSampler(pixelArtSampler),
263
+ },
264
+ ],
265
+ });
266
+
267
+ const atlasBindGroup = device.createBindGroup({
268
+ label: `${label} atlas bind group`,
269
+ layout: pipeline.getBindGroupLayout(1),
270
+ entries: [
271
+ {
272
+ binding: 0,
273
+ resource: textureAtlas.createView({
274
+ dimension: "2d-array",
275
+ arrayLayerCount: textureAtlas.depthOrArrayLayers,
276
+ }),
277
+ },
278
+ ],
279
+ });
280
+
281
+ return [bindGroup, atlasBindGroup];
282
+ }
283
+
284
+ type InstanceData = {
285
+ cpuBuffer: Float32Array<ArrayBuffer>;
286
+ gpuBuffer: GPUBuffer;
287
+ bufferLayout: GPUVertexBufferLayout;
288
+ };
@@ -0,0 +1,6 @@
1
+ export type ShaderDescriptor = {
2
+ label: string;
3
+ code: string;
4
+ vertexEntrypoint: string;
5
+ fragmentEntrypoint: string;
6
+ };
@@ -0,0 +1,5 @@
1
+ export * from "./EngineUniform";
2
+ export * from "./IShader";
3
+ export * from "./postprocess/mod";
4
+ export * from "./ShaderDescriptor";
5
+ export * from "./samplers";
@@ -0,0 +1,221 @@
1
+ import { type StructInfo, WgslReflect } from "wgsl_reflect";
2
+ import type { ShaderDescriptor } from "./ShaderDescriptor";
3
+
4
+ export function codeWithLineNumbers(code: string) {
5
+ return code
6
+ .split("\n")
7
+ .map((line, index) => `${index + 1}: ${line}`)
8
+ .join("\n");
9
+ }
10
+
11
+ export function combineShaderCode(
12
+ label: string,
13
+ base: string,
14
+ mod: string,
15
+ ): ShaderDescriptor {
16
+ let baseAst: WgslReflect;
17
+ let modAst: WgslReflect;
18
+
19
+ try {
20
+ baseAst = new WgslReflect(base);
21
+ } catch (e) {
22
+ console.error(codeWithLineNumbers(base));
23
+ throw e;
24
+ }
25
+ try {
26
+ modAst = new WgslReflect(mod);
27
+ } catch (e) {
28
+ console.error(codeWithLineNumbers(mod));
29
+ throw e;
30
+ }
31
+
32
+ if (modAst.structs.length > 1) {
33
+ throw new Error(
34
+ "Shader has more than one struct. Only one struct is supported for now.",
35
+ );
36
+ }
37
+
38
+ const hasInstanceStruct = modAst.structs.length;
39
+ const hasFragmentEntrypoint = modAst.entry.fragment.length > 0;
40
+ const hasVertexEntrypoint = modAst.entry.vertex.length > 0;
41
+
42
+ const fragmentEntrypoint = hasFragmentEntrypoint
43
+ ? modAst.entry.fragment[0]?.name
44
+ : baseAst.entry.fragment[0]?.name;
45
+ const vertexEntrypoint = hasVertexEntrypoint
46
+ ? modAst.entry.vertex[0]?.name
47
+ : baseAst.entry.vertex[0]?.name;
48
+
49
+ if (hasInstanceStruct) {
50
+ base = injectInstanceData(mod, base);
51
+ }
52
+
53
+ return {
54
+ label,
55
+ code: `${base}\n//==========\n\n${mod.trim()}`,
56
+ vertexEntrypoint,
57
+ fragmentEntrypoint,
58
+ };
59
+ }
60
+
61
+ function injectInstanceData(instanceStruct: string, code: string) {
62
+ const codeAst = new WgslReflect(code);
63
+ const snippetAst = new WgslReflect(instanceStruct);
64
+
65
+ const baseInstanceStruct = codeAst.structs.find((s) =>
66
+ s.name.endsWith("InstanceData"),
67
+ );
68
+ if (!baseInstanceStruct) {
69
+ throw new Error(
70
+ `No base instance struct found in code. Looking for a struct named ending in "InstanceData". Code:\n${code}`,
71
+ );
72
+ }
73
+
74
+ const baseFragmentStruct = codeAst.structs.find((s) =>
75
+ s.name.endsWith("VertexOutput"),
76
+ );
77
+ if (!baseFragmentStruct) {
78
+ throw new Error(
79
+ `No base fragment struct found in code. Looking for a struct named ending in "VertexOutput". Code:\n${code}`,
80
+ );
81
+ }
82
+
83
+ const struct = snippetAst.structs[0];
84
+ const slug = struct.name.toLowerCase();
85
+
86
+ const passthroughSnippet = struct.members
87
+ .map((m) => `output.${slug}_${m.name} = instance.${slug}_${m.name};`)
88
+ .join("\n");
89
+
90
+ const prefixedMembersSnippet = struct.members.map(
91
+ (m) =>
92
+ `${slug}_${m.name}: ${m.type.name}${m.format ? `<${m.format.name}>` : ""}`,
93
+ );
94
+
95
+ let startingVertexLocation = findStartingLocation(baseInstanceStruct);
96
+
97
+ const instanceInputSnippet = prefixedMembersSnippet
98
+ .map((snippet) => `@location(${startingVertexLocation++}) ${snippet},`)
99
+ .join("\n ");
100
+
101
+ let startingFragmentLocation = findStartingLocation(baseFragmentStruct);
102
+
103
+ const vertexOutputSnippet = prefixedMembersSnippet
104
+ .map(
105
+ (snippet) =>
106
+ `@location(${startingFragmentLocation++}) @interpolate(flat) ${snippet},`,
107
+ )
108
+ .join("\n ");
109
+
110
+ return code
111
+ .replace(/\/\/ @INSTANCE_DATA SNIPPET/, instanceInputSnippet)
112
+ .replace(/\/\/ @PASSTHROUGH_SNIPPET/, passthroughSnippet)
113
+ .replace(/\/\/ @VERTEX_OUTPUT SNIPPET/, vertexOutputSnippet);
114
+ }
115
+
116
+ function findStartingLocation(struct: StructInfo) {
117
+ let startingLocation = 0;
118
+ for (const member of struct.members) {
119
+ const locationAttr = (member.attributes || []).find(
120
+ (attr) => attr.name === "location",
121
+ );
122
+ if (locationAttr) {
123
+ const location = Number.parseInt(locationAttr.value as string);
124
+ startingLocation = Math.max(startingLocation, location);
125
+ }
126
+ }
127
+ return startingLocation + 1;
128
+ }
129
+
130
+ export function struct2BufferLayout(
131
+ struct: StructInfo,
132
+ stepMode: GPUVertexStepMode = "instance",
133
+ ): GPUVertexBufferLayout {
134
+ const hasBuiltin = struct.members.some((m) =>
135
+ m.attributes?.some((a) => a.name === "builtin"),
136
+ );
137
+ if (hasBuiltin) {
138
+ throw new Error(
139
+ "Can't generate buffer layout from struct with builtin attributes - they count towards size",
140
+ );
141
+ }
142
+
143
+ const unprocessedMembers = struct.members.filter(
144
+ (m) => !m.attributes || !m.attributes.some((a) => a.name === "location"),
145
+ );
146
+ for (const member of unprocessedMembers) {
147
+ console.error(
148
+ `Unprocessed member in struct ${struct.name}: ${member.name}`,
149
+ );
150
+ }
151
+
152
+ const membersWithAttributes = struct.members.filter((m) =>
153
+ m.attributes?.some((a) => a.name === "location"),
154
+ );
155
+
156
+ return {
157
+ arrayStride: struct.size,
158
+ attributes: membersWithAttributes.map((m) => {
159
+ const location = m.attributes!.find((a) => a.name === "location")?.value;
160
+ if (!location) {
161
+ throw new Error(`Location attribute not found for member: ${m.name}`);
162
+ }
163
+ if (Array.isArray(location)) {
164
+ throw new Error(`Location attribute is an array for member: ${m.name}`);
165
+ }
166
+
167
+ const shaderLocation = Number.parseInt(location);
168
+ if (Number.isNaN(shaderLocation)) {
169
+ throw new Error(
170
+ `Invalid location attribute: ${location} for member: ${m.name}`,
171
+ );
172
+ }
173
+
174
+ return {
175
+ shaderLocation,
176
+ offset: m.offset,
177
+
178
+ format: getGpuFormat(m.type.name),
179
+ } satisfies GPUVertexAttribute;
180
+ }),
181
+ stepMode,
182
+ } satisfies GPUVertexBufferLayout;
183
+ }
184
+
185
+ export function validateFragmentShader(shaderCode: string) {
186
+ const ast = new WgslReflect(shaderCode);
187
+ const exampleSnippet = `
188
+ @fragment
189
+ fn myFragmentShader(vertex: VertexOutput) -> @location(0) vec4<f32> {
190
+ let DEFAULT_COLOR = default_fragment_shader(vertex, nearestSampler);
191
+ return DEFAULT_COLOR;
192
+ }
193
+ `;
194
+
195
+ if (!ast.entry.fragment.length) {
196
+ throw new Error(`Shader code must have @fragment, e.g. ${exampleSnippet}`);
197
+ }
198
+ }
199
+
200
+ export function getGpuFormat(typeName: string): GPUVertexFormat {
201
+ // Remove <f32> or <u32> from type names
202
+ const baseType = typeName.replace(/<[fu]32>/, "");
203
+
204
+ const formatMap: Record<string, GPUVertexFormat> = {
205
+ vec2: "float32x2",
206
+ vec2f: "float32x2",
207
+ vec3: "float32x3",
208
+ vec3f: "float32x3",
209
+ vec4: "float32x4",
210
+ vec4f: "float32x4",
211
+ mat3x3: "float32x3",
212
+ u32: "uint32",
213
+ f32: "float32",
214
+ };
215
+
216
+ const format = formatMap[baseType.toLowerCase()];
217
+ if (!format) {
218
+ throw new Error(`Unsupported type: ${typeName}`);
219
+ }
220
+ return format;
221
+ }