glre 0.39.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/README.md +8 -4
  2. package/dist/addons.cjs +1 -1
  3. package/dist/addons.cjs.map +1 -1
  4. package/dist/addons.d.ts +853 -22
  5. package/dist/addons.js +1 -1
  6. package/dist/addons.js.map +1 -1
  7. package/dist/index.cjs +8 -8
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.ts +47 -28
  10. package/dist/index.js +8 -8
  11. package/dist/index.js.map +1 -1
  12. package/dist/native.d.ts +60 -33
  13. package/dist/node.cjs +59 -30
  14. package/dist/node.cjs.map +1 -1
  15. package/dist/node.d.ts +39 -26
  16. package/dist/node.js +59 -30
  17. package/dist/node.js.map +1 -1
  18. package/dist/react.d.ts +47 -28
  19. package/dist/solid.d.ts +47 -28
  20. package/package.json +24 -24
  21. package/src/addons/animation/easing/backIn.ts +10 -0
  22. package/src/addons/animation/easing/backInOut.ts +12 -0
  23. package/src/addons/animation/easing/backOut.ts +10 -0
  24. package/src/addons/animation/easing/bounceIn.ts +10 -0
  25. package/src/addons/animation/easing/bounceInOut.ts +13 -0
  26. package/src/addons/animation/easing/bounceOut.ts +30 -0
  27. package/src/addons/animation/easing/circularIn.ts +9 -0
  28. package/src/addons/animation/easing/circularInOut.ts +11 -0
  29. package/src/addons/animation/easing/circularOut.ts +9 -0
  30. package/src/addons/animation/easing/cubicIn.ts +9 -0
  31. package/src/addons/animation/easing/cubicInOut.ts +11 -0
  32. package/src/addons/animation/easing/cubicOut.ts +10 -0
  33. package/src/addons/animation/easing/elasticIn.ts +10 -0
  34. package/src/addons/animation/easing/elasticInOut.ts +21 -0
  35. package/src/addons/animation/easing/elasticOut.ts +12 -0
  36. package/src/addons/animation/easing/exponentialIn.ts +9 -0
  37. package/src/addons/animation/easing/exponentialInOut.ts +13 -0
  38. package/src/addons/animation/easing/exponentialOut.ts +9 -0
  39. package/src/addons/animation/easing/index.ts +33 -0
  40. package/src/addons/animation/easing/linearIn.ts +9 -0
  41. package/src/addons/animation/easing/linearInOut.ts +9 -0
  42. package/src/addons/animation/easing/linearOut.ts +9 -0
  43. package/src/addons/animation/easing/quadraticIn.ts +9 -0
  44. package/src/addons/animation/easing/quadraticInOut.ts +10 -0
  45. package/src/addons/animation/easing/quadraticOut.ts +9 -0
  46. package/src/addons/animation/easing/quarticIn.ts +9 -0
  47. package/src/addons/animation/easing/quarticInOut.ts +11 -0
  48. package/src/addons/animation/easing/quarticOut.ts +10 -0
  49. package/src/addons/animation/easing/quinticIn.ts +9 -0
  50. package/src/addons/animation/easing/quinticInOut.ts +11 -0
  51. package/src/addons/animation/easing/quinticOut.ts +9 -0
  52. package/src/addons/animation/easing/sineIn.ts +10 -0
  53. package/src/addons/animation/easing/sineInOut.ts +10 -0
  54. package/src/addons/animation/easing/sineOut.ts +10 -0
  55. package/src/addons/color/palette/macbeth.ts +42 -0
  56. package/src/addons/color/space/cmyk2rgb.ts +12 -0
  57. package/src/addons/color/space/gamma2linear.ts +19 -0
  58. package/src/addons/color/space/hsl2rgb.ts +20 -0
  59. package/src/addons/color/space/hsv2rgb.ts +18 -0
  60. package/src/addons/color/space/hue2rgb.ts +12 -0
  61. package/src/addons/color/space/index.ts +29 -0
  62. package/src/addons/color/space/lab2lch.ts +22 -0
  63. package/src/addons/color/space/lab2rgb.ts +19 -0
  64. package/src/addons/color/space/lab2xyz.ts +32 -0
  65. package/src/addons/color/space/lch2lab.ts +21 -0
  66. package/src/addons/color/space/lch2rgb.ts +22 -0
  67. package/src/addons/color/space/linear2gamma.ts +19 -0
  68. package/src/addons/color/space/oklab2rgb.ts +35 -0
  69. package/src/addons/color/space/rgb2cmyk.ts +13 -0
  70. package/src/addons/color/space/rgb2hcv.ts +29 -0
  71. package/src/addons/color/space/rgb2hsl.ts +23 -0
  72. package/src/addons/color/space/rgb2hsv.ts +36 -0
  73. package/src/addons/color/space/rgb2hue.ts +29 -0
  74. package/src/addons/color/space/rgb2lab.ts +19 -0
  75. package/src/addons/color/space/rgb2lch.ts +22 -0
  76. package/src/addons/color/space/rgb2oklab.ts +45 -0
  77. package/src/addons/color/space/rgb2srgb.ts +34 -0
  78. package/src/addons/color/space/rgb2xyz.ts +20 -0
  79. package/src/addons/color/space/rgb2yiq.ts +22 -0
  80. package/src/addons/color/space/rgb2yuv.ts +32 -0
  81. package/src/addons/color/space/srgb2rgb.ts +34 -0
  82. package/src/addons/color/space/xyz2lab.ts +27 -0
  83. package/src/addons/color/space/xyz2rgb.ts +30 -0
  84. package/src/addons/color/space/yiq2rgb.ts +22 -0
  85. package/src/addons/color/space/yuv2rgb.ts +32 -0
  86. package/src/addons/draw/arrows.ts +75 -0
  87. package/src/addons/draw/axis.ts +57 -0
  88. package/src/addons/draw/bridge.ts +81 -0
  89. package/src/addons/draw/char.ts +30 -0
  90. package/src/addons/draw/circle.ts +29 -0
  91. package/src/addons/draw/fill.ts +25 -0
  92. package/src/addons/draw/flip.ts +45 -0
  93. package/src/addons/draw/hex.ts +29 -0
  94. package/src/addons/draw/index.ts +13 -0
  95. package/src/addons/draw/line.ts +16 -0
  96. package/src/addons/draw/point.ts +30 -0
  97. package/src/addons/draw/rect.ts +52 -0
  98. package/src/addons/draw/stroke.ts +31 -0
  99. package/src/addons/draw/tri.ts +29 -0
  100. package/src/addons/generative/cnoise.ts +239 -0
  101. package/src/addons/generative/curl.ts +64 -0
  102. package/src/addons/generative/fbm.ts +69 -0
  103. package/src/addons/generative/gerstnerWave.ts +21 -0
  104. package/src/addons/generative/gnoise.ts +113 -0
  105. package/src/addons/generative/index.ts +15 -0
  106. package/src/addons/generative/noised.ts +139 -0
  107. package/src/addons/generative/pnoise.ts +249 -0
  108. package/src/addons/generative/psrdnoise.ts +277 -0
  109. package/src/addons/generative/random.ts +136 -0
  110. package/src/addons/generative/snoise.ts +199 -0
  111. package/src/addons/generative/srandom.ts +90 -0
  112. package/src/addons/generative/voronoi.ts +134 -0
  113. package/src/addons/generative/voronoise.ts +69 -0
  114. package/src/addons/generative/wavelet.ts +77 -0
  115. package/src/addons/generative/worley.ts +99 -0
  116. package/src/addons/geometry/aabb/aabb.ts +8 -0
  117. package/src/addons/geometry/aabb/centroid.ts +10 -0
  118. package/src/addons/geometry/aabb/contain.ts +19 -0
  119. package/src/addons/geometry/aabb/diagonal.ts +10 -0
  120. package/src/addons/geometry/aabb/expand.ts +16 -0
  121. package/src/addons/geometry/aabb/index.ts +7 -0
  122. package/src/addons/geometry/aabb/intersect.ts +20 -0
  123. package/src/addons/geometry/aabb/square.ts +17 -0
  124. package/src/addons/geometry/index.ts +2 -0
  125. package/src/addons/geometry/triangle/area.ts +10 -0
  126. package/src/addons/geometry/triangle/barycentric.ts +50 -0
  127. package/src/addons/geometry/triangle/centroid.ts +10 -0
  128. package/src/addons/geometry/triangle/closestPoint.ts +85 -0
  129. package/src/addons/geometry/triangle/contain.ts +19 -0
  130. package/src/addons/geometry/triangle/distanceSq.ts +38 -0
  131. package/src/addons/geometry/triangle/index.ts +10 -0
  132. package/src/addons/geometry/triangle/intersect.ts +49 -0
  133. package/src/addons/geometry/triangle/normal.ts +12 -0
  134. package/src/addons/geometry/triangle/signedDistance.ts +31 -0
  135. package/src/addons/geometry/triangle/triangle.ts +9 -0
  136. package/src/addons/index.ts +8 -6
  137. package/src/addons/lighting/ray.ts +8 -0
  138. package/src/addons/math/aafloor.ts +13 -0
  139. package/src/addons/math/aafract.ts +38 -0
  140. package/src/addons/math/aamirror.ts +12 -0
  141. package/src/addons/math/aastep.ts +14 -0
  142. package/src/addons/math/absi.ts +9 -0
  143. package/src/addons/math/adaptiveThreshold.ts +24 -0
  144. package/src/addons/math/bump.ts +20 -0
  145. package/src/addons/math/const.ts +19 -0
  146. package/src/addons/math/cubic.ts +101 -0
  147. package/src/addons/math/cubicMix.ts +49 -0
  148. package/src/addons/math/decimate.ts +12 -0
  149. package/src/addons/math/dist.ts +143 -0
  150. package/src/addons/math/fcos.ts +11 -0
  151. package/src/addons/math/frac.ts +9 -0
  152. package/src/addons/math/gain.ts +14 -0
  153. package/src/addons/math/gaussian.ts +14 -0
  154. package/src/addons/math/grad4.ts +19 -0
  155. package/src/addons/math/hammersley.ts +54 -0
  156. package/src/addons/math/highPass.ts +12 -0
  157. package/src/addons/math/index.ts +63 -0
  158. package/src/addons/math/inside.ts +68 -0
  159. package/src/addons/math/invCubic.ts +9 -0
  160. package/src/addons/math/invQuartic.ts +9 -0
  161. package/src/addons/math/inverse.ts +9 -0
  162. package/src/addons/math/lengthSq.ts +10 -0
  163. package/src/addons/math/map.ts +27 -0
  164. package/src/addons/math/mirror.ts +12 -0
  165. package/src/addons/math/mmax.ts +27 -0
  166. package/src/addons/math/mmin.ts +28 -0
  167. package/src/addons/math/mmix.ts +47 -0
  168. package/src/addons/math/mod2.ts +44 -0
  169. package/src/addons/math/mod289.ts +46 -0
  170. package/src/addons/math/modi.ts +15 -0
  171. package/src/addons/math/nyquist.ts +15 -0
  172. package/src/addons/math/pack.ts +15 -0
  173. package/src/addons/math/parabola.ts +12 -0
  174. package/src/addons/math/permute.ts +42 -0
  175. package/src/addons/math/pow2.ts +10 -0
  176. package/src/addons/math/pow3.ts +9 -0
  177. package/src/addons/math/pow5.ts +10 -0
  178. package/src/addons/math/pow7.ts +12 -0
  179. package/src/addons/math/powFast.ts +18 -0
  180. package/src/addons/math/quartic.ts +15 -0
  181. package/src/addons/math/quat/index.ts +14 -0
  182. package/src/addons/math/quat/quat2mat3.ts +28 -0
  183. package/src/addons/math/quat/quat2mat4.ts +16 -0
  184. package/src/addons/math/quat/quatAdd.ts +18 -0
  185. package/src/addons/math/quat/quatConj.ts +14 -0
  186. package/src/addons/math/quat/quatDiv.ts +18 -0
  187. package/src/addons/math/quat/quatIdentity.ts +9 -0
  188. package/src/addons/math/quat/quatInverse.ts +17 -0
  189. package/src/addons/math/quat/quatLength.ts +15 -0
  190. package/src/addons/math/quat/quatLengthSq.ts +14 -0
  191. package/src/addons/math/quat/quatLerp.ts +40 -0
  192. package/src/addons/math/quat/quatMul.ts +38 -0
  193. package/src/addons/math/quat/quatNeg.ts +14 -0
  194. package/src/addons/math/quat/quatNorm.ts +16 -0
  195. package/src/addons/math/quat/quatSub.ts +18 -0
  196. package/src/addons/math/quintic.ts +16 -0
  197. package/src/addons/math/rotate2d.ts +16 -0
  198. package/src/addons/math/rotate3d.ts +37 -0
  199. package/src/addons/math/rotate3dX.ts +20 -0
  200. package/src/addons/math/rotate3dY.ts +20 -0
  201. package/src/addons/math/rotate3dZ.ts +20 -0
  202. package/src/addons/math/rotate4d.ts +41 -0
  203. package/src/addons/math/rotate4dX.ts +21 -0
  204. package/src/addons/math/rotate4dY.ts +16 -0
  205. package/src/addons/math/rotate4dZ.ts +21 -0
  206. package/src/addons/math/saturateMediump.ts +11 -0
  207. package/src/addons/math/scale2d.ts +44 -0
  208. package/src/addons/math/scale3d.ts +17 -0
  209. package/src/addons/math/scale4d.ts +50 -0
  210. package/src/addons/math/smootherstep.ts +16 -0
  211. package/src/addons/math/taylorInvSqrt.ts +9 -0
  212. package/src/addons/math/toMat3.ts +14 -0
  213. package/src/addons/math/toMat4.ts +14 -0
  214. package/src/addons/math/translate4d.ts +31 -0
  215. package/src/addons/math/unpack.ts +88 -0
  216. package/src/addons/sdf/boxSDF.ts +24 -0
  217. package/src/addons/sdf/circleSDF.ts +20 -0
  218. package/src/addons/sdf/crossSDF.ts +17 -0
  219. package/src/addons/sdf/hexSDF.ts +18 -0
  220. package/src/addons/sdf/index.ts +7 -0
  221. package/src/addons/sdf/lineSDF.ts +33 -0
  222. package/src/addons/sdf/rectSDF.ts +46 -0
  223. package/src/addons/sdf/sphereSDF.ts +20 -0
  224. package/src/addons/sdf/triSDF.ts +14 -0
  225. package/src/addons/space/aspect.ts +14 -0
  226. package/src/addons/space/bracketing.ts +44 -0
  227. package/src/addons/space/brickTile.ts +44 -0
  228. package/src/addons/space/cart2polar.ts +20 -0
  229. package/src/addons/space/center.ts +32 -0
  230. package/src/addons/space/checkerTile.ts +41 -0
  231. package/src/addons/space/depth2viewZ.ts +43 -0
  232. package/src/addons/space/displace.ts +55 -0
  233. package/src/addons/space/equirect2xyz.ts +17 -0
  234. package/src/addons/space/eulerView.ts +19 -0
  235. package/src/addons/space/fisheye2xyz.ts +18 -0
  236. package/src/addons/space/flipY.ts +25 -0
  237. package/src/addons/space/hexTile.ts +18 -0
  238. package/src/addons/space/index.ts +38 -0
  239. package/src/addons/space/kaleidoscope.ts +48 -0
  240. package/src/addons/space/linearizeDepth.ts +17 -0
  241. package/src/addons/space/lookAt.ts +49 -0
  242. package/src/addons/space/lookAtView.ts +40 -0
  243. package/src/addons/space/mirrorTile.ts +73 -0
  244. package/src/addons/space/nearest.ts +13 -0
  245. package/src/addons/space/orthographic.ts +25 -0
  246. package/src/addons/space/parallaxMapping.ts +149 -0
  247. package/src/addons/space/perspective.ts +24 -0
  248. package/src/addons/space/polar2cart.ts +24 -0
  249. package/src/addons/space/ratio.ts +14 -0
  250. package/src/addons/space/rotate.ts +37 -0
  251. package/src/addons/space/rotateX.ts +54 -0
  252. package/src/addons/space/rotateY.ts +54 -0
  253. package/src/addons/space/rotateZ.ts +54 -0
  254. package/src/addons/space/scale.ts +13 -0
  255. package/src/addons/space/sprite.ts +16 -0
  256. package/src/addons/space/sqTile.ts +20 -0
  257. package/src/addons/space/tbn.ts +26 -0
  258. package/src/addons/space/translate.ts +12 -0
  259. package/src/addons/space/triTile.ts +32 -0
  260. package/src/addons/space/uncenter.ts +32 -0
  261. package/src/addons/space/unratio.ts +12 -0
  262. package/src/addons/space/viewZ2depth.ts +25 -0
  263. package/src/addons/space/windmillTile.ts +58 -0
  264. package/src/addons/space/xyz2equirect.ts +10 -0
  265. package/src/index.ts +5 -2
  266. package/src/node/build.ts +62 -52
  267. package/src/node/create.ts +3 -0
  268. package/src/node/index.ts +1 -2
  269. package/src/node/scope.ts +27 -25
  270. package/src/node/types.ts +16 -12
  271. package/src/node/utils/const.ts +12 -11
  272. package/src/node/utils/index.ts +15 -12
  273. package/src/node/utils/infer.ts +17 -6
  274. package/src/node/utils/parse.ts +37 -13
  275. package/src/node/utils/utils.ts +40 -22
  276. package/src/types.ts +13 -5
  277. package/src/utils/helpers.ts +80 -7
  278. package/src/utils/pipeline.ts +21 -5
  279. package/src/utils/program.ts +68 -42
  280. package/src/utils/webgl.ts +47 -37
  281. package/src/utils/webgpu.ts +30 -38
@@ -3,20 +3,20 @@ export const SWIZZLES = ['x', 'y', 'z', 'w', 'r', 'g', 'b', 'a', 's', 't', 'p',
3
3
  // Unified order with TYPE_MAPPING array
4
4
  export const CONVERSIONS = [
5
5
  'toBool',
6
- 'toUint',
6
+ 'toUInt',
7
7
  'toInt',
8
8
  'toFloat',
9
- 'toBvec2',
10
- 'toIvec2',
11
- 'toUvec2',
9
+ 'toBVec2',
10
+ 'toIVec2',
11
+ 'toUVec2',
12
12
  'toVec2',
13
- 'toBvec3',
14
- 'toIvec3',
15
- 'toUvec3',
13
+ 'toBVec3',
14
+ 'toIVec3',
15
+ 'toUVec3',
16
16
  'toVec3',
17
- 'toBvec4',
18
- 'toIvec4',
19
- 'toUvec4',
17
+ 'toBVec4',
18
+ 'toIVec4',
19
+ 'toUVec4',
20
20
  'toVec4',
21
21
  'toColor',
22
22
  'toMat2',
@@ -232,6 +232,7 @@ export const FUNCTIONS = [
232
232
  'floor',
233
233
  'fract',
234
234
  'fwidth',
235
+ 'inverse',
235
236
  'inverseSqrt',
236
237
  'log',
237
238
  'log2',
@@ -241,7 +242,6 @@ export const FUNCTIONS = [
241
242
  'radians',
242
243
  'reciprocal',
243
244
  'round',
244
- 'saturate',
245
245
  'sign',
246
246
  'sin',
247
247
  'sinh',
@@ -249,6 +249,7 @@ export const FUNCTIONS = [
249
249
  'tan',
250
250
  'tanh',
251
251
  'trunc',
252
+ 'saturate',
252
253
  // 1. Functions where first argument determines return type
253
254
  'atan2',
254
255
  'clamp',
@@ -7,6 +7,7 @@ import {
7
7
  parseDefine,
8
8
  parseGather,
9
9
  parseIf,
10
+ parseLoop,
10
11
  parseScatter,
11
12
  parseStorageHead,
12
13
  parseStruct,
@@ -16,8 +17,9 @@ import {
16
17
  parseUniformHead,
17
18
  parseVaryingHead,
18
19
  } from './parse'
19
- import { getBluiltin, getConversions, getEventFun, getOperator, initNodeContext, safeEventCall } from './utils'
20
+ import { getBluiltin, getConversions, getOperator, initNodeContext, isElement, setupEvent } from './utils'
20
21
  import { is } from '../../utils/helpers'
22
+ import { mod } from '..'
21
23
  import type { Constants as C, NodeContext, Y } from '../types'
22
24
 
23
25
  export * from './utils'
@@ -35,6 +37,7 @@ export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string
35
37
  return ret + '.0'
36
38
  }
37
39
  if (is.bol(target)) return target ? 'true' : 'false'
40
+ if (isElement(target)) throw `` // IGNORE
38
41
  if (!target) return ''
39
42
  const { type, props = {} } = target
40
43
  const { id = 'i', children = [], fields, initialValues } = props
@@ -62,14 +65,21 @@ export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string
62
65
  if (type === 'conversion') return `${getConversions(x, c)}(${parseArray(children.slice(1), c)})`
63
66
  if (type === 'operator') {
64
67
  if (x === 'not' || x === 'bitNot') return `!${code(y, c)}`
68
+ if (x === 'mod') return code(mod(y, z), c)
65
69
  if (x.endsWith('Assign')) return `${code(y, c)} ${getOperator(x)} ${code(z, c)};`
66
70
  return `(${code(y, c)} ${getOperator(x)} ${code(z, c)})`
67
71
  }
68
72
  if (type === 'function') {
69
73
  if (x === 'negate') return `(-${code(y, c)})`
74
+ if (x === 'reciprocal') return `(1.0 / ${code(y, c)})`
70
75
  if (x === 'oneMinus') return `(1.0-${code(y, c)})`
76
+ if (x === 'saturate') return `clamp(${code(y, c)}, 0.0, 1.0)`
71
77
  if (x === 'texture') return parseTexture(c, y, z, w)
72
78
  if (x === 'atan2' && c.isWebGL) return `atan(${code(y, c)}, ${code(z, c)})`
79
+ if (!c.isWebGL) {
80
+ if (x === 'dFdx') return `dpdx(${code(y, c)})`
81
+ if (x === 'dFdy') return `dpdy(${code(y, c)})`
82
+ }
73
83
  return `${x}(${parseArray(children.slice(1), c)})`
74
84
  }
75
85
  /**
@@ -80,10 +90,7 @@ export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string
80
90
  if (type === 'return') return `return ${code(x, c)};`
81
91
  if (type === 'break') return 'break;'
82
92
  if (type === 'continue') return 'continue;'
83
- if (type === 'loop')
84
- return c.isWebGL
85
- ? `for (int ${id} = 0; ${id} < ${code(x, c)}; ${id} += 1) {\n${code(y, c)}\n}`
86
- : `for (var ${id}: i32 = 0; ${id} < ${code(x, c)}; ${id}++) {\n${code(y, c)}\n}`
93
+ if (type === 'loop') return parseLoop(c, x, y, id)
87
94
  if (type === 'if') return parseIf(c, x, y, children)
88
95
  if (type === 'switch') return parseSwitch(c, x, children)
89
96
  if (type === 'declare') return parseDeclare(c, x, y)
@@ -115,10 +122,8 @@ export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string
115
122
  else if (c.label === 'vert') c.code?.vertInputs.set(id, field)
116
123
  return `in.${id}`
117
124
  }
118
- if (type === 'attribute') {
119
- const fun = getEventFun(c, id, true)
120
- safeEventCall(x, fun)
121
- target.listeners.add(fun)
125
+ if (type === 'attribute' || type === 'instance') {
126
+ setupEvent(c, id, type, target, x)
122
127
  c.code?.vertInputs.set(id, parseAttribHead(c, id, infer(target, c)))
123
128
  return c.isWebGL ? `${id}` : `in.${id}`
124
129
  }
@@ -126,9 +131,7 @@ export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string
126
131
  let head = ''
127
132
  if (type === 'uniform') {
128
133
  const varType = infer(target, c)
129
- const fun = getEventFun(c, id, false, varType === 'texture')
130
- safeEventCall(x, fun)
131
- target.listeners.add(fun)
134
+ setupEvent(c, id, varType, target, x)
132
135
  head = parseUniformHead(c, id, varType)
133
136
  }
134
137
  if (type === 'storage') head = parseStorageHead(c, id, infer(target, c))
@@ -1,4 +1,4 @@
1
- import { isConstants, isX, isSwizzle } from './utils'
1
+ import { isConstants, isElement, isX, isSwizzle } from './utils'
2
2
  import {
3
3
  BUILTIN_TYPES,
4
4
  COMPONENT_COUNT_TO_TYPE,
@@ -6,7 +6,7 @@ import {
6
6
  getOperatorResultType,
7
7
  validateOperatorTypes,
8
8
  } from './const'
9
- import { is } from '../../utils/helpers'
9
+ import { is, getStride } from '../../utils/helpers'
10
10
  import type { Constants as C, NodeContext, X, Y } from '../types'
11
11
 
12
12
  const inferBuiltin = <T extends C>(id: string | undefined) => {
@@ -24,11 +24,15 @@ export const inferPrimitiveType = <T extends C>(x: Y<T>) => {
24
24
  if (is.str(x)) return 'texture' as T
25
25
  if (is.num(x)) return 'float' as T // @TODO FIX: Number.isInteger(x) ? 'int' : 'float'
26
26
  if (is.arr(x)) return COMPONENT_COUNT_TO_TYPE[x.length as keyof typeof COMPONENT_COUNT_TO_TYPE] as T
27
- return 'float' as T
27
+ if (isElement(x)) return 'texture' as T
28
+ return 'void' as T
28
29
  }
29
30
 
30
31
  const inferFromCount = <T extends C>(count: number) => {
31
- return COMPONENT_COUNT_TO_TYPE[count as keyof typeof COMPONENT_COUNT_TO_TYPE] as T
32
+ const ret = COMPONENT_COUNT_TO_TYPE[count as keyof typeof COMPONENT_COUNT_TO_TYPE] as T
33
+ if (!ret)
34
+ throw `glre node system error: Cannot infer type from array length ${count}. Check your data size. Supported: 1(float), 2(vec2), 3(vec3), 4(vec4), 9(mat3), 16(mat4)`
35
+ return ret
32
36
  }
33
37
 
34
38
  const inferFromArray = <T extends C>(arr: Y<T>[], c: NodeContext) => {
@@ -37,7 +41,7 @@ const inferFromArray = <T extends C>(arr: Y<T>[], c: NodeContext) => {
37
41
  if (is.str(x)) return x as T // for struct
38
42
  const ret = infer(x, c)
39
43
  // for (const x of arr.slice(1))
40
- // if (ret !== infer(x, c)) throw new Error(`glre node system error: defined scope return mismatch`)
44
+ // if (ret !== infer(x, c)) throw `glre node system error: defined scope return mismatch`
41
45
  return ret
42
46
  }
43
47
 
@@ -58,7 +62,14 @@ export const inferImpl = <T extends C>(target: X<T>, c: NodeContext): T => {
58
62
  if (!inferFrom || inferFrom.length === 0) return 'void' as T
59
63
  return inferFromArray(inferFrom, c)
60
64
  }
61
- if (type === 'attribute' && is.arr(x) && c.gl?.count) return inferFromCount(x.length / c.gl.count)
65
+ if (type === 'attribute' && is.arr(x)) {
66
+ const stride = getStride(x.length, c.gl?.count, c.gl?.error)
67
+ return inferFromCount(stride)
68
+ }
69
+ if (type === 'instance' && is.arr(x)) {
70
+ const stride = getStride(x.length, c.gl?.instanceCount, c.gl?.error)
71
+ return inferFromCount(stride)
72
+ }
62
73
  if (type === 'member') {
63
74
  if (isSwizzle(y)) return inferFromCount(y.length)
64
75
  if (isX(x)) {
@@ -3,6 +3,7 @@ import { infer } from './infer'
3
3
  import { getConversions, addDependency } from './utils'
4
4
  import { is } from '../../utils/helpers'
5
5
  import type { Constants, NodeContext, NodeProps, StructFields, Y } from '../types'
6
+ import { storageSize } from '../../utils/program'
6
7
 
7
8
  export const parseArray = (children: Y[], c: NodeContext) => {
8
9
  return children
@@ -22,9 +23,9 @@ export const parseGather = (c: NodeContext, x: Y, y: Y, target: Y) => {
22
23
  throw new Error(`Unsupported storage scatter type: ${valueType}`)
23
24
  }
24
25
  const indexVar = code(y, c)
25
- const texSize = Math.floor(Math.sqrt(c.gl?.particles || 1024))
26
- const coordX = `int(${indexVar}) % ${texSize}`
27
- const coordY = `int(${indexVar}) / ${texSize}`
26
+ const size = storageSize(c.gl?.particleCount)
27
+ const coordX = `int(${indexVar}) % ${size.x}`
28
+ const coordY = `int(${indexVar}) / ${size.x}`
28
29
  return `texelFetch(${code(x, c)}, ivec2(${coordX}, ${coordY}), 0)${parseSwizzle()}`
29
30
  }
30
31
 
@@ -123,16 +124,13 @@ export const parseStruct = (c: NodeContext, id: string, instanceId = '', initial
123
124
  export const parseDefine = (c: NodeContext, props: NodeProps, target: Y) => {
124
125
  const { id, children = [], layout } = props
125
126
  const [x, ...args] = children
126
- const argParams: [name: string, type: string][] = []
127
+ const argParams: [name: string, type: Constants][] = []
127
128
  const params: string[] = []
128
- if (layout?.inputs)
129
- for (const input of layout.inputs) {
130
- argParams.push([input.name, input.type])
131
- }
132
- else
133
- for (let i = 0; i < args.length; i++) {
134
- argParams.push([`p${i}`, infer(args[i], c)])
135
- }
129
+ for (let i = 0; i < args.length; i++) {
130
+ const input = layout?.inputs?.[i]
131
+ if (!input) argParams.push([`p${i}`, infer(args[i], c)])
132
+ else argParams.push([input.name, input.type === 'auto' ? infer(args[i], c) : input.type])
133
+ }
136
134
  const scopeCode = code(x, c) // build struct headers before inferring returnType
137
135
  const returnType = infer(target, c)
138
136
  const ret = []
@@ -158,7 +156,7 @@ export const parseDefine = (c: NodeContext, props: NodeProps, target: Y) => {
158
156
  /**
159
157
  * headers
160
158
  */
161
- export const parseVaryingHead = (c: NodeContext, id: string, type: string) => {
159
+ export const parseVaryingHead = (c: NodeContext, id: string, type: Constants) => {
162
160
  return c.isWebGL
163
161
  ? `${type} ${id};`
164
162
  : `@location(${c.code?.vertVaryings?.size || 0}) ${id}: ${getConversions(type, c)}`
@@ -201,6 +199,32 @@ export const parseStorageHead = (c: NodeContext, id: string, type: Constants) =>
201
199
  return `@group(${group}) @binding(${binding}) var<storage, read_write> ${id}: array<${wgslType}>;`
202
200
  }
203
201
 
202
+ export const parseLoop = (c: NodeContext, x: Y, y: Y, id: string) => {
203
+ const conditionType = infer(x, c)
204
+ const bodyCode = code(y, c)
205
+ const conditionCode = code(x, c)
206
+ if (c.isWebGL) {
207
+ if (conditionType === 'int')
208
+ return `for (int ${id} = 0; ${id} < ${conditionCode}; ${id} += 1) {\n${bodyCode}\n}`
209
+ if (conditionType === 'float')
210
+ return `for (float ${id} = 0.0; ${id} < ${conditionCode}; ${id} += 1.0) {\n${bodyCode}\n}`
211
+ if (conditionType === 'vec2')
212
+ return `for (vec2 ${id} = vec2(0.0); ${id}.x < ${conditionCode}.x && ${id}.y < ${conditionCode}.y; ${id} += vec2(1.0)) {\n${bodyCode}\n}`
213
+ if (conditionType === 'vec3')
214
+ return `for (vec3 ${id} = vec3(0.0); ${id}.x < ${conditionCode}.x && ${id}.y < ${conditionCode}.y && ${id}.z < ${conditionCode}.z; ${id} += vec3(1.0)) {\n${bodyCode}\n}`
215
+ return `for (int ${id} = 0; ${id} < ${conditionCode}; ${id} += 1) {\n${bodyCode}\n}`
216
+ }
217
+ if (conditionType === 'int')
218
+ return `for (var ${id}: i32 = 0; ${id} < ${conditionCode}; ${id}++) {\n${bodyCode}\n}`
219
+ if (conditionType === 'float')
220
+ return `for (var ${id}: f32 = 0.0; ${id} < ${conditionCode}; ${id} += 1.0) {\n${bodyCode}\n}`
221
+ if (conditionType === 'vec2')
222
+ return `for (var ${id}: vec2f = vec2f(0.0); ${id}.x < ${conditionCode}.x && ${id}.y < ${conditionCode}.y; ${id} += vec2f(1.0)) {\n${bodyCode}\n}`
223
+ if (conditionType === 'vec3')
224
+ return `for (var ${id}: vec3f = vec3f(0.0); ${id}.x < ${conditionCode}.x && ${id}.y < ${conditionCode}.y && ${id}.z < ${conditionCode}.z; ${id} += vec3f(1.0)) {\n${bodyCode}\n}`
225
+ return `for (var ${id}: i32 = 0; ${id} < ${conditionCode}; ${id}++) {\n${bodyCode}\n}`
226
+ }
227
+
204
228
  export const parseConstantHead = (c: NodeContext, id: string, type: Constants, value: string) => {
205
229
  return c.isWebGL ? `const ${type} ${id} = ${value};` : `const ${id}: ${getConversions(type, c)} = ${value};`
206
230
  }
@@ -9,6 +9,7 @@ import {
9
9
  } from './const'
10
10
  import { is } from '../../utils/helpers'
11
11
  import type { Constants as C, Conversions, Functions, NodeContext, Operators, Swizzles, X, Y } from '../types'
12
+ import { storageSize } from '../../utils/program'
12
13
 
13
14
  export const isSwizzle = (key: unknown): key is Swizzles => {
14
15
  return is.str(key) && /^[xyzwrgbastpq]{1,4}$/.test(key)
@@ -22,6 +23,11 @@ export const isFunction = (key: unknown): key is Functions => {
22
23
  return FUNCTIONS.includes(key as Functions)
23
24
  }
24
25
 
26
+ export const isElement = (x: unknown): x is Element => {
27
+ if (is.obj(x)) return false
28
+ return x instanceof Element
29
+ }
30
+
25
31
  export const isConversion = (key: unknown): key is Conversions => {
26
32
  return CONVERSIONS.includes(key as Conversions)
27
33
  }
@@ -50,8 +56,8 @@ export const getId = () => `x${count++}`
50
56
 
51
57
  export const getBluiltin = (c: NodeContext, id: string) => {
52
58
  if (id === 'global_invocation_id') {
53
- const size = Math.floor(Math.sqrt(c.gl?.particles || 1024))
54
- return `uvec3(uint(gl_FragCoord.y) * uint(${size}) + uint(gl_FragCoord.x), 0u, 0u)`
59
+ const size = storageSize(c.gl?.particleCount)
60
+ return `uvec3(uint(gl_FragCoord.y) * uint(${size.x}) + uint(gl_FragCoord.x), 0u, 0u)`
55
61
  }
56
62
  const ret = WGSL_TO_GLSL_BUILTIN[id as keyof typeof WGSL_TO_GLSL_BUILTIN]
57
63
  if (!ret) throw new Error(`Error: unknown builtin variable ${id}`)
@@ -73,26 +79,6 @@ export const getConstant = (conversionKey: string): C => {
73
79
  return index !== -1 ? CONSTANTS[index] : 'float'
74
80
  }
75
81
 
76
- export const getEventFun = (c: NodeContext, id: string, isAttribute = false, isTexture = false) => {
77
- if (c.isWebGL) {
78
- if (isAttribute) return (value: any) => c.gl?.attribute?.(id, value)
79
- if (isTexture) return (value: any) => c.gl?.texture?.(id, value)
80
- return (value: any) => c.gl?.uniform?.(id, value)
81
- }
82
- if (isAttribute) return (value: any) => c.gl?._attribute?.(id, value)
83
- if (isTexture) return (value: any) => c.gl?._texture?.(id, value)
84
- return (value: any) => c.gl?._uniform?.(id, value)
85
- }
86
-
87
- export const safeEventCall = <T extends C>(x: X<T>, fun: (value: unknown) => void) => {
88
- if (is.und(x)) return
89
- if (!isX(x)) return fun(x) // for uniform(0) or uniform([0, 1])
90
- if (x.type !== 'conversion') return
91
- const args = x.props.children?.slice(1)
92
- if (is.und(args?.[0])) return // ignore if uniform(vec2())
93
- fun(args.map((x) => x ?? args[0])) // for uniform(vec2(1)) or uniform(vec2(1, 1))
94
- }
95
-
96
82
  export const initNodeContext = (c: NodeContext) => {
97
83
  if (c.code) return c
98
84
  c.code = {
@@ -119,3 +105,35 @@ export const addDependency = (c: NodeContext, id = '', type: string) => {
119
105
  if (!c.code?.dependencies?.has(id)) c.code!.dependencies.set(id, new Set())
120
106
  if (!isConstants(type)) c.code!.dependencies.get(id)!.add(type)
121
107
  }
108
+
109
+ /**
110
+ * uniform ant attribute event listeners
111
+ */
112
+ const getEventFun = (c: NodeContext, id: string, type: string) => {
113
+ if (c.isWebGL) {
114
+ if (type === 'attribute') return (value: any) => c.gl?.attribute?.(id, value)
115
+ if (type === 'instance') return (value: any) => c.gl?.instance?.(id, value)
116
+ if (type === 'texture') return (value: any) => c.gl?.texture?.(id, value)
117
+ return (value: any) => c.gl?.uniform?.(id, value)
118
+ }
119
+ if (type === 'attribute') return (value: any) => c.gl?._attribute?.(id, value)
120
+ if (type === 'instance') return (value: any) => c.gl?._instance?.(id, value)
121
+ if (type === 'texture') return (value: any) => c.gl?._texture?.(id, value)
122
+ return (value: any) => c.gl?._uniform?.(id, value)
123
+ }
124
+
125
+ const safeEventCall = <T extends C>(x: X<T>, fun: (value: unknown) => void) => {
126
+ if (is.und(x)) return
127
+ if (!isX(x)) return fun(x) // for uniform(0) or uniform([0, 1])
128
+ if (x.type !== 'conversion') return
129
+ const args = x.props.children?.slice(1)
130
+ if (is.und(args?.[0])) return // ignore if uniform(vec2())
131
+ fun(args.map((x) => x ?? args[0])) // for uniform(vec2(1)) or uniform(vec2(1, 1))
132
+ }
133
+
134
+ export const setupEvent = (c: NodeContext, id: string, type: string, target: X, child: X) => {
135
+ const fun = getEventFun(c, id, type)
136
+ safeEventCall(child, fun)
137
+ target.listeners.add(fun)
138
+ return fun
139
+ }
package/src/types.ts CHANGED
@@ -10,14 +10,17 @@ export type GL = EventState<{
10
10
  isWebGL: boolean
11
11
  isError: boolean
12
12
  isLoop: boolean
13
+ isDebug: boolean
14
+ isDepth: boolean
13
15
  isGL: true
14
16
  width?: number
15
17
  height?: number
16
18
  size: [number, number]
17
19
  mouse: [number, number]
18
20
  count: number
21
+ instanceCount: number
22
+ particleCount: number | [number, number] | [number, number, number]
19
23
  loading: number
20
- particles: 64 | 256 | 576 | 1024 | 1600 | 2304 | 3136 | 4096 | 4096 | 5184 | 6400 // (8k)^2
21
24
  el: HTMLCanvasElement
22
25
  vs?: string | Vec4
23
26
  cs?: string | Void
@@ -46,7 +49,7 @@ export type GL = EventState<{
46
49
  error(e?: string): void
47
50
  render(): void
48
51
  resize(e?: Event): void
49
- mousemove(e: Event): void
52
+ mousemove(e: MouseEvent): void
50
53
  loop(): void
51
54
 
52
55
  /**
@@ -55,18 +58,22 @@ export type GL = EventState<{
55
58
  _uniform?(key: string, value: Uniform, isMatrix?: boolean): GL
56
59
  uniform(key: string, value: Uniform, isMatrix?: boolean): GL
57
60
  uniform(target: { [key: string]: Uniform }): GL
58
- _texture?(key: string, value: string): GL
59
- texture(key: string, value: string): GL
60
- texture(target: { [key: string]: string }): GL
61
+ _texture?(key: string, value: Texture): GL
62
+ texture(key: string, value: Texture): GL
63
+ texture(target: { [key: string]: Texture }): GL
61
64
  _attribute?(key: string, value: Attribute, iboValue?: Attribute): GL
62
65
  attribute(key: string, value: Attribute, iboValue?: Attribute): GL
63
66
  attribute(target: { [key: string]: Attribute }): GL
67
+ _instance?(key: string, value: Attribute, at?: number): GL
68
+ instance(key: string, value: Attribute, at?: number): GL
69
+ instance(target: { [key: string]: Attribute }): GL
64
70
  _storage?(key: string, value: Storage): GL
65
71
  storage(key: string, value: Storage): GL
66
72
  storage(target: { [key: string]: Storage }): GL
67
73
  }>
68
74
 
69
75
  type Uniform = number | number[] | Float32Array
76
+ type Texture = string | HTMLImageElement | HTMLVideoElement
70
77
  type Attribute = number[] | Float32Array
71
78
  type Storage = number[] | Float32Array
72
79
 
@@ -93,6 +100,7 @@ export interface AttribData {
93
100
  buffer: GPUBuffer
94
101
  location: number
95
102
  stride: number
103
+ isInstance?: boolean
96
104
  }
97
105
 
98
106
  export interface StorageData {
@@ -1,5 +1,3 @@
1
- import type { GL } from './../types'
2
-
3
1
  export const is = {
4
2
  arr: Array.isArray,
5
3
  bol: (a: unknown): a is boolean => typeof a === 'boolean',
@@ -49,12 +47,87 @@ export const isFloat32 = (value: unknown): value is Float32Array => {
49
47
  return value instanceof Float32Array
50
48
  }
51
49
 
52
- export const loadingImage = (gl: GL, src: string, fun: (source: HTMLImageElement) => void) => {
53
- gl.loading++
50
+ const loadingImage = (src: string, fun: (source: HTMLImageElement) => void) => {
54
51
  const source = new Image()
55
52
  Object.assign(source, { src, crossOrigin: 'anonymous' })
56
- source.decode().then(() => {
57
- fun(source)
58
- gl.loading--
53
+ source.decode().then(() => fun(source))
54
+ }
55
+
56
+ const loadingVideo = (src: string, fun: (source: HTMLVideoElement) => void) => {
57
+ const source = document.createElement('video')
58
+ source.crossOrigin = 'anonymous'
59
+ source.muted = true
60
+ source.loop = true
61
+ source.src = src
62
+ source.load()
63
+ source.play()
64
+ source.addEventListener('canplay', fun.bind(null, source), { once: true })
65
+ }
66
+
67
+ export function loadingTexture(src: string, fun: (source: HTMLVideoElement, isVideo: true) => void): void
68
+
69
+ export function loadingTexture(src: string, fun: (source: HTMLImageElement, isVideo: false) => void): void
70
+
71
+ export function loadingTexture(src: string | HTMLImageElement | HTMLVideoElement, fun: Function) {
72
+ if (!is.str(src)) return fun(src, src instanceof HTMLVideoElement)
73
+ const isVideo = /\.(mp4|webm|ogg|avi|mov)$/i.test(src)
74
+ const loader = isVideo ? loadingVideo : loadingImage
75
+ loader(src, (el: HTMLImageElement | HTMLVideoElement) => {
76
+ fun(el as HTMLVideoElement, isVideo)
59
77
  })
60
78
  }
79
+ const isValidStride = (stride: number) => [1, 2, 3, 4, 9, 16].includes(stride)
80
+
81
+ const calcStride = (arrayLength: number, count = 3) => {
82
+ if (arrayLength % count === 0) return Math.floor(arrayLength / count)
83
+ return -1
84
+ }
85
+
86
+ export const getStride = (arrayLength: number, count = 1, error = console.warn) => {
87
+ const ret = calcStride(arrayLength, count)
88
+ if (!isValidStride(ret))
89
+ error(
90
+ `glre attribute error: Invalid attribute length ${arrayLength}. Must divide by vertex count (${count}) with valid stride (1,2,3,4,9,16)`
91
+ )
92
+ return ret
93
+ }
94
+
95
+ export const GLSL_FS = /* cpp */ `
96
+ #version 300 es
97
+ precision mediump float;
98
+ out vec4 fragColor;
99
+ uniform vec2 iResolution;
100
+ void main() {
101
+ fragColor = vec4(fract((gl_FragCoord.xy / iResolution)), 0.0, 1.0);
102
+ }
103
+ `
104
+
105
+ export const GLSL_VS = /* cpp */ `
106
+ #version 300 es
107
+ void main() {
108
+ float x = float(gl_VertexID % 2) * 4.0 - 1.0;
109
+ float y = float(gl_VertexID / 2) * 4.0 - 1.0;
110
+ gl_Position = vec4(x, y, 0.0, 1.0);
111
+ }`
112
+
113
+ export const WGSL_VS = /* rust */ `
114
+ struct In { @builtin(vertex_index) vertex_index: u32 }
115
+ struct Out { @builtin(position) position: vec4f }
116
+ @vertex
117
+ fn main(in: In) -> Out {
118
+ var out: Out;
119
+ var x = f32(in.vertex_index % 2) * 4.0 - 1.0;
120
+ var y = f32(in.vertex_index / 2) * 4.0 - 1.0;
121
+ out.position = vec4f(x, y, 0.0, 1.0);
122
+ return out;
123
+ }
124
+ `.trim()
125
+
126
+ export const WGSL_FS = /* rust */ `
127
+ struct Out { @builtin(position) position: vec4f }
128
+ @group(0) @binding(0) var<uniform> iResolution: vec2f;
129
+ @fragment
130
+ fn main(out: Out) -> @location(0) vec4f {
131
+ return vec4f(fract((out.position.xy / iResolution)), 0.0, 1.0);
132
+ }
133
+ `
@@ -1,4 +1,4 @@
1
- import { isFloat32 } from './helpers'
1
+ import { is, isFloat32 } from './helpers'
2
2
  import type { AttribData, TextureData, UniformData, StorageData } from '../types'
3
3
 
4
4
  /**
@@ -58,18 +58,21 @@ const getVertexFormat = (stride: number): GPUVertexFormat => {
58
58
  return 'float32'
59
59
  }
60
60
 
61
- export const createVertexBuffers = (attribs: Iterable<AttribData>) => {
61
+ export const createVertexBuffers = (attribs: Iterable<AttribData & { isInstance?: boolean }>) => {
62
62
  const vertexBuffers: GPUBuffer[] = []
63
63
  const bufferLayouts: GPUVertexBufferLayout[] = []
64
- for (const { buffer, location, stride } of attribs) {
64
+ for (const { buffer, location, stride, isInstance } of attribs) {
65
65
  vertexBuffers[location] = buffer
66
+ const componentSize = Math.min(Math.max(Math.floor(stride), 1), 4)
67
+ const arrayStride = Math.max(4, Math.ceil((componentSize * 4) / 4) * 4)
66
68
  bufferLayouts[location] = {
67
- arrayStride: stride * 4,
69
+ arrayStride,
70
+ stepMode: isInstance ? 'instance' : 'vertex',
68
71
  attributes: [
69
72
  {
70
73
  shaderLocation: location,
71
74
  offset: 0,
72
- format: getVertexFormat(stride),
75
+ format: getVertexFormat(componentSize),
73
76
  },
74
77
  ],
75
78
  }
@@ -203,3 +206,16 @@ export const createDepthTexture = (device: GPUDevice, width: number, height: num
203
206
  usage: GPUTextureUsage.RENDER_ATTACHMENT,
204
207
  })
205
208
  }
209
+
210
+ /**
211
+ * utils
212
+ */
213
+ export const workgroupCount = (particleCount: number | number[], workgroupSize = 32) => {
214
+ if (is.num(particleCount)) particleCount = [particleCount]
215
+ const [x, y = 1, z = 1] = particleCount
216
+ return {
217
+ x: Math.min((x * y * z) / workgroupSize, 65535),
218
+ y: 1,
219
+ z: 1,
220
+ }
221
+ }