glre 0.40.0 → 0.42.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 (150) hide show
  1. package/dist/addons.cjs +1 -1
  2. package/dist/addons.cjs.map +1 -1
  3. package/dist/addons.d.ts +382 -10
  4. package/dist/addons.js +1 -1
  5. package/dist/addons.js.map +1 -1
  6. package/dist/index.cjs +6 -6
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.ts +9 -8
  9. package/dist/index.js +5 -5
  10. package/dist/index.js.map +1 -1
  11. package/dist/native.d.ts +12 -11
  12. package/dist/node.cjs +16 -16
  13. package/dist/node.cjs.map +1 -1
  14. package/dist/node.d.ts +6 -5
  15. package/dist/node.js +15 -15
  16. package/dist/node.js.map +1 -1
  17. package/dist/react.d.ts +9 -8
  18. package/dist/solid.d.ts +9 -8
  19. package/package.json +1 -1
  20. package/src/addons/color/blend/add.ts +35 -0
  21. package/src/addons/color/blend/average.ts +35 -0
  22. package/src/addons/color/blend/color.ts +28 -0
  23. package/src/addons/color/blend/colorBurn.ts +35 -0
  24. package/src/addons/color/blend/colorDodge.ts +39 -0
  25. package/src/addons/color/blend/darken.ts +35 -0
  26. package/src/addons/color/blend/difference.ts +35 -0
  27. package/src/addons/color/blend/exclusion.ts +35 -0
  28. package/src/addons/color/blend/glow.ts +36 -0
  29. package/src/addons/color/blend/hardLight.ts +36 -0
  30. package/src/addons/color/blend/hardMix.ts +39 -0
  31. package/src/addons/color/blend/hue.ts +29 -0
  32. package/src/addons/color/blend/index.ts +28 -0
  33. package/src/addons/color/blend/lighten.ts +35 -0
  34. package/src/addons/color/blend/linearBurn.ts +39 -0
  35. package/src/addons/color/blend/linearDodge.ts +39 -0
  36. package/src/addons/color/blend/linearLight.ts +44 -0
  37. package/src/addons/color/blend/luminosity.ts +28 -0
  38. package/src/addons/color/blend/multiply.ts +35 -0
  39. package/src/addons/color/blend/negation.ts +35 -0
  40. package/src/addons/color/blend/overlay.ts +38 -0
  41. package/src/addons/color/blend/phoenix.ts +35 -0
  42. package/src/addons/color/blend/pinLight.ts +40 -0
  43. package/src/addons/color/blend/reflect.ts +35 -0
  44. package/src/addons/color/blend/saturation.ts +28 -0
  45. package/src/addons/color/blend/screen.ts +39 -0
  46. package/src/addons/color/blend/softLight.ts +63 -0
  47. package/src/addons/color/blend/subtract.ts +37 -0
  48. package/src/addons/color/blend/vividLight.ts +44 -0
  49. package/src/addons/color/composite/compositeXor.ts +40 -0
  50. package/src/addons/color/composite/destinationAtop.ts +42 -0
  51. package/src/addons/color/composite/destinationIn.ts +42 -0
  52. package/src/addons/color/composite/destinationOut.ts +42 -0
  53. package/src/addons/color/composite/destinationOver.ts +42 -0
  54. package/src/addons/color/composite/index.ts +9 -0
  55. package/src/addons/color/composite/sourceAtop.ts +42 -0
  56. package/src/addons/color/composite/sourceIn.ts +40 -0
  57. package/src/addons/color/composite/sourceOut.ts +40 -0
  58. package/src/addons/color/composite/sourceOver.ts +40 -0
  59. package/src/addons/color/palette/macbeth.ts +31 -33
  60. package/src/addons/draw/arrows.ts +34 -48
  61. package/src/addons/draw/axis.ts +24 -42
  62. package/src/addons/draw/bridge.ts +4 -4
  63. package/src/addons/draw/char.ts +235 -18
  64. package/src/addons/draw/circle.ts +22 -1
  65. package/src/addons/draw/colorChecker.ts +42 -0
  66. package/src/addons/draw/colorPicker.ts +66 -0
  67. package/src/addons/draw/digits.ts +334 -0
  68. package/src/addons/draw/index.ts +4 -0
  69. package/src/addons/draw/matrix.ts +26 -0
  70. package/src/addons/draw/point.ts +24 -11
  71. package/src/addons/geometry/triangle/closestPoint.ts +7 -7
  72. package/src/addons/index.ts +3 -0
  73. package/src/addons/math/const.ts +4 -4
  74. package/src/addons/math/mod289.ts +1 -6
  75. package/src/addons/math/powFast.ts +4 -10
  76. package/src/addons/math/quartic.ts +6 -11
  77. package/src/addons/math/quat/quatLerp.ts +3 -3
  78. package/src/addons/math/quintic.ts +7 -12
  79. package/src/addons/math/rotate2d.ts +1 -6
  80. package/src/addons/math/rotate3d.ts +4 -10
  81. package/src/addons/math/rotate3dX.ts +3 -12
  82. package/src/addons/math/rotate3dY.ts +3 -12
  83. package/src/addons/math/rotate3dZ.ts +3 -12
  84. package/src/addons/math/rotate4d.ts +4 -10
  85. package/src/addons/math/rotate4dX.ts +3 -13
  86. package/src/addons/math/rotate4dY.ts +1 -6
  87. package/src/addons/math/rotate4dZ.ts +3 -13
  88. package/src/addons/math/scale2d.ts +16 -32
  89. package/src/addons/math/toMat3.ts +1 -6
  90. package/src/addons/math/toMat4.ts +1 -6
  91. package/src/addons/sdf/arrowSDF.ts +61 -0
  92. package/src/addons/sdf/boxFrameSDF.ts +31 -0
  93. package/src/addons/sdf/boxSDF.ts +4 -6
  94. package/src/addons/sdf/capsuleSDF.ts +17 -0
  95. package/src/addons/sdf/coneSDF.ts +60 -0
  96. package/src/addons/sdf/crossSDF.ts +4 -7
  97. package/src/addons/sdf/cubeSDF.ts +13 -0
  98. package/src/addons/sdf/cylinderSDF.ts +65 -0
  99. package/src/addons/sdf/dodecahedronSDF.ts +32 -0
  100. package/src/addons/sdf/ellipsoidSDF.ts +14 -0
  101. package/src/addons/sdf/flowerSDF.ts +16 -0
  102. package/src/addons/sdf/gearSDF.ts +22 -0
  103. package/src/addons/sdf/heartSDF.ts +17 -0
  104. package/src/addons/sdf/hexPrismSDF.ts +15 -0
  105. package/src/addons/sdf/hexSDF.ts +8 -15
  106. package/src/addons/sdf/icosahedronSDF.ts +23 -0
  107. package/src/addons/sdf/index.ts +41 -0
  108. package/src/addons/sdf/juliaSDF.ts +39 -0
  109. package/src/addons/sdf/kochSDF.ts +49 -0
  110. package/src/addons/sdf/linkSDF.ts +15 -0
  111. package/src/addons/sdf/mandelbulbSDF.ts +41 -0
  112. package/src/addons/sdf/octahedronSDF.ts +30 -0
  113. package/src/addons/sdf/octogonPrismSDF.ts +19 -0
  114. package/src/addons/sdf/opElongate.ts +35 -0
  115. package/src/addons/sdf/opExtrude.ts +14 -0
  116. package/src/addons/sdf/opIntersection.ts +25 -0
  117. package/src/addons/sdf/opOnion.ts +12 -0
  118. package/src/addons/sdf/opRepeat.ts +49 -0
  119. package/src/addons/sdf/opRevolve.ts +12 -0
  120. package/src/addons/sdf/opRound.ts +12 -0
  121. package/src/addons/sdf/opSubtraction.ts +50 -0
  122. package/src/addons/sdf/opUnion.ts +39 -0
  123. package/src/addons/sdf/planeSDF.ts +21 -0
  124. package/src/addons/sdf/polySDF.ts +32 -0
  125. package/src/addons/sdf/pyramidSDF.ts +29 -0
  126. package/src/addons/sdf/raysSDF.ts +14 -0
  127. package/src/addons/sdf/rhombSDF.ts +10 -0
  128. package/src/addons/sdf/spiralSDF.ts +15 -0
  129. package/src/addons/sdf/starSDF.ts +47 -0
  130. package/src/addons/sdf/superShapeSDF.ts +73 -0
  131. package/src/addons/sdf/tetrahedronSDF.ts +21 -0
  132. package/src/addons/sdf/torusSDF.ts +27 -0
  133. package/src/addons/sdf/triPrismSDF.ts +13 -0
  134. package/src/addons/sdf/triSDF.ts +19 -11
  135. package/src/addons/sdf/vesicaSDF.ts +23 -0
  136. package/src/addons/space/bracketing.ts +1 -2
  137. package/src/addons/space/kaleidoscope.ts +1 -2
  138. package/src/addons/space/scale.ts +42 -7
  139. package/src/addons/space/windmillTile.ts +2 -1
  140. package/src/node/create.ts +2 -3
  141. package/src/node/scope.ts +3 -2
  142. package/src/node/types.ts +1 -1
  143. package/src/node/utils/index.ts +2 -1
  144. package/src/node/utils/infer.ts +2 -1
  145. package/src/node/utils/utils.ts +6 -11
  146. package/src/types.ts +4 -3
  147. package/src/utils/helpers.ts +25 -8
  148. package/src/utils/program.ts +11 -4
  149. package/src/utils/webgl.ts +9 -3
  150. package/src/utils/webgpu.ts +12 -4
@@ -0,0 +1,47 @@
1
+ import { Fn, Vec2, Int, Float, vec2, atan2, step, float } from '../../node'
2
+ import { TAU } from '../math/const'
3
+ import { scale2dWithCenter } from '../space/scale'
4
+
5
+ export function starSDF(st: Vec2, V: Int, s: Float): Float
6
+ export function starSDF(st: Vec2, V: Int): Float
7
+ export function starSDF(st: Vec2, V: any, s?: any): any {
8
+ if (s !== undefined) {
9
+ return starSDFWithScale(st, V, s)
10
+ } else {
11
+ return starSDFSimple(st, V)
12
+ }
13
+ }
14
+
15
+ export const starSDFWithScale = Fn(([st, V, s]: [Vec2, Int, Float]): Float => {
16
+ const centeredSt = st.sub(0.5).mul(2).toVar('centeredSt')
17
+ const a = atan2(centeredSt.y, centeredSt.x).div(TAU).toVar('a')
18
+ const seg = a.mul(V.toFloat()).toVar('seg')
19
+ const finalA = seg
20
+ .floor()
21
+ .add(0.5)
22
+ .div(V.toFloat())
23
+ .add(s.mix(s.negate(), step(0.5, seg.fract())))
24
+ .mul(TAU)
25
+ .toVar('finalA')
26
+ return vec2(finalA.cos(), finalA.sin()).dot(centeredSt).abs()
27
+ }).setLayout({
28
+ name: 'starSDFWithScale',
29
+ type: 'float',
30
+ inputs: [
31
+ { name: 'st', type: 'vec2' },
32
+ { name: 'V', type: 'int' },
33
+ { name: 's', type: 'float' },
34
+ ],
35
+ })
36
+
37
+ export const starSDFSimple = Fn(([st, V]: [Vec2, Int]): Float => {
38
+ const scaledSt = scale2dWithCenter(st, V.toFloat().reciprocal().mul(12), vec2(0.5))
39
+ return starSDFWithScale(scaledSt as any, V, float(0.1))
40
+ }).setLayout({
41
+ name: 'starSDFSimple',
42
+ type: 'float',
43
+ inputs: [
44
+ { name: 'st', type: 'vec2' },
45
+ { name: 'V', type: 'int' },
46
+ ],
47
+ })
@@ -0,0 +1,73 @@
1
+ import { Fn, Vec2, Float, vec2, cos, sin, pow, abs, float } from '../../node'
2
+ import { cart2polar } from '../space/cart2polar'
3
+
4
+ export const superShapeSDFCenter = Fn(
5
+ ([st, center, s, a, b, n1, n2, n3, m]: [
6
+ Vec2,
7
+ Vec2,
8
+ Float,
9
+ Float,
10
+ Float,
11
+ Float,
12
+ Float,
13
+ Float,
14
+ Float
15
+ ]): Float => {
16
+ st.assign(st.sub(center))
17
+ const polar = cart2polar(st).toVar('polar')
18
+ const d = polar.y.mul(5).toVar('d')
19
+ const theta = polar.x.toVar('theta')
20
+ const t1 = abs(
21
+ float(1)
22
+ .div(a)
23
+ .mul(cos(m.mul(theta).mul(0.25)))
24
+ ).toVar('t1')
25
+ t1.assign(pow(t1, n2))
26
+ const t2 = abs(
27
+ float(1)
28
+ .div(b)
29
+ .mul(sin(m.mul(theta).mul(0.25)))
30
+ ).toVar('t2')
31
+ t2.assign(pow(t2, n3))
32
+ const t3 = t1.add(t2).toVar('t3')
33
+ const r = pow(t3, float(-1).div(n1)).toVar('r')
34
+ const q = s
35
+ .mul(r)
36
+ .mul(vec2(cos(theta), sin(theta)))
37
+ .toVar('q')
38
+ return d.sub(q.length())
39
+ }
40
+ ).setLayout({
41
+ name: 'superShapeSDFCenter',
42
+ type: 'float',
43
+ inputs: [
44
+ { name: 'st', type: 'vec2' },
45
+ { name: 'center', type: 'vec2' },
46
+ { name: 's', type: 'float' },
47
+ { name: 'a', type: 'float' },
48
+ { name: 'b', type: 'float' },
49
+ { name: 'n1', type: 'float' },
50
+ { name: 'n2', type: 'float' },
51
+ { name: 'n3', type: 'float' },
52
+ { name: 'm', type: 'float' },
53
+ ],
54
+ })
55
+
56
+ export const superShapeSDF = Fn(
57
+ ([st, s, a, b, n1, n2, n3, m]: [Vec2, Float, Float, Float, Float, Float, Float, Float]): Float => {
58
+ return superShapeSDFCenter(st, vec2(0.5), s, a, b, n1, n2, n3, m)
59
+ }
60
+ ).setLayout({
61
+ name: 'superShapeSDF',
62
+ type: 'float',
63
+ inputs: [
64
+ { name: 'st', type: 'vec2' },
65
+ { name: 's', type: 'float' },
66
+ { name: 'a', type: 'float' },
67
+ { name: 'b', type: 'float' },
68
+ { name: 'n1', type: 'float' },
69
+ { name: 'n2', type: 'float' },
70
+ { name: 'n3', type: 'float' },
71
+ { name: 'm', type: 'float' },
72
+ ],
73
+ })
@@ -0,0 +1,21 @@
1
+ import { Fn, Vec3, Float, vec2 } from '../../node'
2
+
3
+ export const tetrahedronSDF = Fn(([p, h]: [Vec3, Float]): Float => {
4
+ const q = p.abs().toVar('q')
5
+ const y = p.y.toVar('y')
6
+ const d1 = q.z.sub(y.max(0)).toVar('d1')
7
+ const d2 = q.x
8
+ .mul(0.5)
9
+ .add(y.mul(0.5))
10
+ .max(0)
11
+ .sub(h.min(h.add(y)))
12
+ .toVar('d2')
13
+ return vec2(d1, d2).max(0.005).length().add(d1.max(d2).min(0))
14
+ }).setLayout({
15
+ name: 'tetrahedronSDF',
16
+ type: 'float',
17
+ inputs: [
18
+ { name: 'p', type: 'vec3' },
19
+ { name: 'h', type: 'float' },
20
+ ],
21
+ })
@@ -0,0 +1,27 @@
1
+ import { Fn, Vec3, Vec2, Float, vec2, select } from '../../node'
2
+
3
+ export const torusSDF = Fn(([p, t]: [Vec3, Vec2]): Float => {
4
+ return vec2(vec2(p.x, p.z).length().sub(t.x), p.y).length().sub(t.y)
5
+ }).setLayout({
6
+ name: 'torusSDF',
7
+ type: 'float',
8
+ inputs: [
9
+ { name: 'p', type: 'vec3' },
10
+ { name: 't', type: 'vec2' },
11
+ ],
12
+ })
13
+
14
+ export const torusSDFSector = Fn(([p, sc, ra, rb]: [Vec3, Vec2, Float, Float]): Float => {
15
+ const px = p.x.abs().toVar('px')
16
+ const k = select(vec2(px, p.y).length(), vec2(px, p.y).dot(sc), sc.y.mul(px).greaterThan(sc.x.mul(p.y)))
17
+ return p.dot(p).add(ra.mul(ra)).sub(ra.mul(k).mul(2)).sqrt().sub(rb)
18
+ }).setLayout({
19
+ name: 'torusSDFSector',
20
+ type: 'float',
21
+ inputs: [
22
+ { name: 'p', type: 'vec3' },
23
+ { name: 'sc', type: 'vec2' },
24
+ { name: 'ra', type: 'float' },
25
+ { name: 'rb', type: 'float' },
26
+ ],
27
+ })
@@ -0,0 +1,13 @@
1
+ import { Fn, Vec3, Vec2, Float } from '../../node'
2
+
3
+ export const triPrismSDF = Fn(([p, h]: [Vec3, Vec2]): Float => {
4
+ const q = p.abs().toVar('q')
5
+ return q.z.sub(h.y).max(q.x.mul(0.866025).add(p.y.mul(0.5)).max(p.y.negate()).sub(h.x.mul(0.5)))
6
+ }).setLayout({
7
+ name: 'triPrismSDF',
8
+ type: 'float',
9
+ inputs: [
10
+ { name: 'p', type: 'vec3' },
11
+ { name: 'h', type: 'vec2' },
12
+ ],
13
+ })
@@ -1,14 +1,22 @@
1
- import { Fn, Vec2, Float, max, abs, float } from '../../node'
1
+ import { Fn, Vec2, Float } from '../../node'
2
2
 
3
3
  export const triSDF = Fn(([st]: [Vec2]): Float => {
4
- const normalized = st.sub(0.5).mul(5).toVar()
5
- const sqrt3_2 = float(0.866025) // sqrt(3)/2
6
- return max(
7
- abs(normalized.x).mul(sqrt3_2).add(normalized.y.div(2)),
8
- normalized.y.div(-2)
9
- )
4
+ const centered = st.sub(0.5).mul(5).toVar('centered')
5
+ return centered.x.abs().mul(0.866025).add(centered.y.mul(0.5)).max(centered.y.negate().mul(0.5))
10
6
  }).setLayout({
11
- name: 'triSDF',
12
- type: 'float',
13
- inputs: [{ name: 'st', type: 'vec2' }],
14
- })
7
+ name: 'triSDF',
8
+ type: 'float',
9
+ inputs: [{ name: 'st', type: 'vec2' }],
10
+ })
11
+
12
+ export const triSDFCenter = Fn(([st, center]: [Vec2, Vec2]): Float => {
13
+ const centered = st.sub(center).mul(5).toVar('centered')
14
+ return centered.x.abs().mul(0.866025).add(centered.y.mul(0.5)).max(centered.y.negate().mul(0.5))
15
+ }).setLayout({
16
+ name: 'triSDFCenter',
17
+ type: 'float',
18
+ inputs: [
19
+ { name: 'st', type: 'vec2' },
20
+ { name: 'center', type: 'vec2' },
21
+ ],
22
+ })
@@ -0,0 +1,23 @@
1
+ import { Fn, Vec2, Float, vec2, float } from '../../node'
2
+
3
+ export const vesicaSDF = Fn(([st, w]: [Vec2, Float]): Float => {
4
+ const offset = vec2(w.mul(0.5), 0)
5
+ const circle1 = st.sub(offset).length().sub(0.5)
6
+ const circle2 = st.add(offset).length().sub(0.5)
7
+ return circle1.max(circle2)
8
+ }).setLayout({
9
+ name: 'vesicaSDF',
10
+ type: 'float',
11
+ inputs: [
12
+ { name: 'st', type: 'vec2' },
13
+ { name: 'w', type: 'float' },
14
+ ],
15
+ })
16
+
17
+ export const vesicaSDFDefault = Fn(([st]: [Vec2]): Float => {
18
+ return vesicaSDF(st, float(0.5))
19
+ }).setLayout({
20
+ name: 'vesicaSDFDefault',
21
+ type: 'float',
22
+ inputs: [{ name: 'st', type: 'vec2' }],
23
+ })
@@ -1,7 +1,6 @@
1
1
  import { Fn, Vec2, Float, mat2, atan2, cos, sin, mod, vec2, float } from '../../node'
2
+ import { PI, TWO_PI } from '../math/const'
2
3
 
3
- const PI = float(3.1415926535897932384626433832795)
4
- const TWO_PI = float(6.283185307179586476925286766559)
5
4
  const BRACKETING_ANGLE_DELTA = PI.div(20.0)
6
5
 
7
6
  export const bracketingAxis0 = Fn(([dir]: [Vec2]): Vec2 => {
@@ -1,6 +1,5 @@
1
1
  import { Fn, Vec2, Float, vec2, float, length, atan2, floor, min, max, cos, sin } from '../../node'
2
-
3
- const TWO_PI = 6.283185307179586
2
+ import { TWO_PI } from '../math/const'
4
3
 
5
4
  const kaleidoscopeCore = (coord: Vec2, segmentCount: Float, phase: Float) => {
6
5
  const uv = coord.sub(0.5).toVar('uv')
@@ -1,13 +1,48 @@
1
- import { Fn, vec2, vec3, vec4, Float, Vec2, Vec3, Vec4, X } from '../../node'
1
+ import { Fn, Vec2, Vec3, Float, vec2, vec3 } from '../../node'
2
2
 
3
- export const scale = Fn(([st, s, center]: [X, X, X]): X => {
3
+ export const scale2d = Fn(([st, s]: [Vec2, Float]): Vec2 => {
4
+ return st.sub(vec2(0.5)).mul(s).add(vec2(0.5))
5
+ }).setLayout({
6
+ name: 'scale2d',
7
+ type: 'vec2',
8
+ inputs: [
9
+ { name: 'st', type: 'vec2' },
10
+ { name: 's', type: 'float' },
11
+ ],
12
+ })
13
+
14
+ export const scale2dWithCenter = Fn(([st, s, center]: [Vec2, Float, Vec2]): Vec2 => {
4
15
  return st.sub(center).mul(s).add(center)
5
16
  }).setLayout({
6
- name: 'scale',
7
- type: 'auto',
17
+ name: 'scale2dWithCenter',
18
+ type: 'vec2',
19
+ inputs: [
20
+ { name: 'st', type: 'vec2' },
21
+ { name: 's', type: 'float' },
22
+ { name: 'center', type: 'vec2' },
23
+ ],
24
+ })
25
+
26
+ export const scale2dVec = Fn(([st, s]: [Vec2, Vec2]): Vec2 => {
27
+ return st.sub(vec2(0.5)).mul(s).add(vec2(0.5))
28
+ }).setLayout({
29
+ name: 'scale2dVec',
30
+ type: 'vec2',
31
+ inputs: [
32
+ { name: 'st', type: 'vec2' },
33
+ { name: 's', type: 'vec2' },
34
+ ],
35
+ })
36
+
37
+ export const scale3d = Fn(([st, s]: [Vec3, Float]): Vec3 => {
38
+ return st.sub(vec3(0.5)).mul(s).add(vec3(0.5))
39
+ }).setLayout({
40
+ name: 'scale3d',
41
+ type: 'vec3',
8
42
  inputs: [
9
- { name: 'st', type: 'auto' },
10
- { name: 's', type: 'auto' },
11
- { name: 'center', type: 'auto' },
43
+ { name: 'st', type: 'vec3' },
44
+ { name: 's', type: 'float' },
12
45
  ],
13
46
  })
47
+
48
+ export const scale = scale2dVec
@@ -1,4 +1,5 @@
1
1
  import { Fn, Vec2, Vec4, Float, mod, abs, vec4 } from '../../node'
2
+ import { TWO_PI } from '../math'
2
3
  import { rotate2DBasic } from './rotate'
3
4
  import { sqTile } from './sqTile'
4
5
 
@@ -20,7 +21,7 @@ export const windmillTileDefault = Fn(([t]: [Vec4]): Vec4 => {
20
21
  const a = abs(mod(t.z, 2).sub(mod(t.w, 2)))
21
22
  .add(mod(t.w, 2).mul(2))
22
23
  .mul(0.25)
23
- return vec4(rotate2DBasic(t.xy, a.mul(6.283185307179586)), t.zw)
24
+ return vec4(rotate2DBasic(t.xy, a.mul(TWO_PI)), t.zw)
24
25
  }).setLayout({
25
26
  name: 'windmillTileDefault',
26
27
  type: 'vec4',
@@ -2,7 +2,7 @@ import { compute, fragment, vertex } from './build'
2
2
  import { addToScope, assign, toVar } from './scope'
3
3
  import { code, getConstant, isConversion, isFunction, isOperator, getId, isArrayAccess } from './utils'
4
4
  import { is } from '../utils/helpers'
5
- import type { Constants as C, Functions, NodeProps, NodeTypes, Operators, X, Y } from './types'
5
+ import type { Bool, Constants as C, Functions, NodeProps, NodeTypes, Operators, X, Y } from './types'
6
6
 
7
7
  const toPrimitive = (x: Y, hint: string) => {
8
8
  if (hint === 'string') return code(x as any, null)
@@ -15,7 +15,6 @@ export const create = <T extends C>(type: NodeTypes, props?: NodeProps | null, .
15
15
  const get = (_: unknown, key: string | Symbol) => {
16
16
  if (key === 'type') return type
17
17
  if (key === 'props') return props
18
- if (key === '__nodeType') return undefined // Will be inferred by TypeScript
19
18
  if (key === 'toVar') return toVar.bind(null, x)
20
19
  if (key === 'isProxy') return true
21
20
  if (key === 'toString') return code.bind(null, x)
@@ -70,7 +69,7 @@ export const member = <T extends C>(x: X, index: Y) => create<T>('member', null,
70
69
  export const element = <T extends C>(x: X, index: Y) => create<T>('element', null, x, index)
71
70
  export const gather = <T extends C>(x: X, index: Y) => create<T>('gather', null, x, index)
72
71
  export const scatter = <T extends C>(x: X, index: Y) => create<T>('scatter', null, x, index)
73
- export const select = <T extends C>(x: Y, y: Y, z: Y) => create<T>('ternary', null, x, y, z) // z ? x : y @TODO REMOVE
72
+ export const select = <T extends C>(x: Y<T>, y: Y<T>, z: Bool) => create<T>('ternary', null, x, y, z) // z ? x : y @TODO REMOVE
74
73
  export const operator = <T extends C>(key: Operators, ...x: Y[]) => create<T>('operator', null, key, ...x)
75
74
  export const function_ = <T extends C>(key: Functions, ...x: Y[]) => create<T>('function', null, key, ...x)
76
75
  export const conversion = <T extends C>(key: T, ...x: Y[]) => create<T>('conversion', null, key, ...x)
package/src/node/scope.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { getId } from './utils'
2
1
  import { conversion, create } from './create'
3
2
  import type {
4
3
  FnLayout,
@@ -12,6 +11,7 @@ import type {
12
11
  X,
13
12
  Y,
14
13
  } from './types'
14
+ import { getId } from './utils'
15
15
 
16
16
  let scope: X | null = null
17
17
  let define: X | null = null
@@ -122,8 +122,9 @@ export const Switch = (x: Y) => {
122
122
  }
123
123
 
124
124
  export function Fn<T extends X | Struct | void, Args extends any[]>(fun: (args: Args) => T, layout?: FnLayout) {
125
+ const defaultId = getId()
125
126
  const ret = (...args: any[]) => {
126
- const id = layout?.name || getId()
127
+ const id = layout?.name || defaultId
127
128
  const paramVars: X[] = []
128
129
  const paramDefs: NodeProps[] = []
129
130
  for (let i = 0; i < args.length; i++) {
package/src/node/types.ts CHANGED
@@ -224,7 +224,7 @@ type XImpl<T extends C> = _X<T> & {
224
224
  type C = Constants
225
225
 
226
226
  export type X<T extends C = C> = T extends keyof ConstantsToType ? ConstantsToType[T] : _X<T>
227
- export type Y<T extends C = C> = number | number[] | string | boolean | undefined | X<T>
227
+ export type Y<T extends C = C> = number | number[] | string | boolean | undefined | HTMLElement | X<T>
228
228
 
229
229
  type Methods =
230
230
  | Functions
@@ -17,7 +17,7 @@ import {
17
17
  parseUniformHead,
18
18
  parseVaryingHead,
19
19
  } from './parse'
20
- import { getBluiltin, getConversions, getOperator, initNodeContext, setupEvent } from './utils'
20
+ import { getBluiltin, getConversions, getOperator, initNodeContext, isElement, isX, setupEvent } from './utils'
21
21
  import { is } from '../../utils/helpers'
22
22
  import { mod } from '..'
23
23
  import type { Constants as C, NodeContext, Y } from '../types'
@@ -38,6 +38,7 @@ export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string
38
38
  }
39
39
  if (is.bol(target)) return target ? 'true' : 'false'
40
40
  if (!target) return ''
41
+ if (!isX(target)) return ''
41
42
  const { type, props = {} } = target
42
43
  const { id = 'i', children = [], fields, initialValues } = props
43
44
  const [x, y, z, w] = children
@@ -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,
@@ -24,6 +24,7 @@ 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
+ if (isElement(x)) return 'texture' as T
27
28
  return 'void' as T
28
29
  }
29
30
 
@@ -8,17 +8,7 @@ import {
8
8
  WGSL_TO_GLSL_BUILTIN,
9
9
  } from './const'
10
10
  import { is } from '../../utils/helpers'
11
- import type {
12
- Constants as C,
13
- Conversions,
14
- Functions,
15
- NodeContext,
16
- NodeTypes,
17
- Operators,
18
- Swizzles,
19
- X,
20
- Y,
21
- } from '../types'
11
+ import type { Constants as C, Conversions, Functions, NodeContext, Operators, Swizzles, X, Y } from '../types'
22
12
  import { storageSize } from '../../utils/program'
23
13
 
24
14
  export const isSwizzle = (key: unknown): key is Swizzles => {
@@ -33,6 +23,11 @@ export const isFunction = (key: unknown): key is Functions => {
33
23
  return FUNCTIONS.includes(key as Functions)
34
24
  }
35
25
 
26
+ export const isElement = (x: unknown): x is Element => {
27
+ if (is.obj(x)) return false
28
+ return x instanceof Element
29
+ }
30
+
36
31
  export const isConversion = (key: unknown): key is Conversions => {
37
32
  return CONVERSIONS.includes(key as Conversions)
38
33
  }
package/src/types.ts CHANGED
@@ -58,9 +58,9 @@ export type GL = EventState<{
58
58
  _uniform?(key: string, value: Uniform, isMatrix?: boolean): GL
59
59
  uniform(key: string, value: Uniform, isMatrix?: boolean): GL
60
60
  uniform(target: { [key: string]: Uniform }): GL
61
- _texture?(key: string, value: string): GL
62
- texture(key: string, value: string): GL
63
- 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
64
64
  _attribute?(key: string, value: Attribute, iboValue?: Attribute): GL
65
65
  attribute(key: string, value: Attribute, iboValue?: Attribute): GL
66
66
  attribute(target: { [key: string]: Attribute }): GL
@@ -73,6 +73,7 @@ export type GL = EventState<{
73
73
  }>
74
74
 
75
75
  type Uniform = number | number[] | Float32Array
76
+ type Texture = string | HTMLImageElement | HTMLVideoElement
76
77
  type Attribute = number[] | Float32Array
77
78
  type Storage = number[] | Float32Array
78
79
 
@@ -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,16 +47,35 @@ 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--
59
- })
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 })
60
65
  }
61
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)
77
+ })
78
+ }
62
79
  const isValidStride = (stride: number) => [1, 2, 3, 4, 9, 16].includes(stride)
63
80
 
64
81
  const calcStride = (arrayLength: number, count = 3) => {
@@ -67,14 +67,15 @@ export const updateUniform = (c: WebGL2RenderingContext, loc: WebGLUniformLocati
67
67
 
68
68
  export const createTexture = (
69
69
  c: WebGL2RenderingContext,
70
- img: HTMLImageElement,
70
+ el: HTMLImageElement | HTMLVideoElement,
71
71
  loc: WebGLUniformLocation,
72
- unit: number
72
+ unit: number,
73
+ isVideo = false
73
74
  ) => {
74
75
  const texture = c.createTexture()
75
76
  c.bindTexture(c.TEXTURE_2D, texture)
76
- c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, c.RGBA, c.UNSIGNED_BYTE, img)
77
- c.generateMipmap(c.TEXTURE_2D)
77
+ c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, c.RGBA, c.UNSIGNED_BYTE, el)
78
+ if (!isVideo) c.generateMipmap(c.TEXTURE_2D)
78
79
  c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MIN_FILTER, c.LINEAR)
79
80
  c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MAG_FILTER, c.LINEAR)
80
81
  c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_S, c.CLAMP_TO_EDGE)
@@ -83,6 +84,12 @@ export const createTexture = (
83
84
  c.uniform1i(loc, unit)
84
85
  c.activeTexture(c.TEXTURE0 + unit)
85
86
  c.bindTexture(c.TEXTURE_2D, texture)
87
+ if (isVideo)
88
+ return () => {
89
+ c.activeTexture(c.TEXTURE0 + unit)
90
+ c.bindTexture(c.TEXTURE_2D, texture)
91
+ c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, c.RGBA, c.UNSIGNED_BYTE, el)
92
+ }
86
93
  }
87
94
 
88
95
  /**
@@ -1,5 +1,5 @@
1
1
  import { nested as cached } from 'reev'
2
- import { is, loadingImage, getStride, GLSL_VS, GLSL_FS } from './helpers'
2
+ import { is, getStride, GLSL_VS, GLSL_FS, loadingTexture } from './helpers'
3
3
  import {
4
4
  createArrayBuffer,
5
5
  cleanStorage,
@@ -105,9 +105,13 @@ export const webgl = async (gl: GL) => {
105
105
  }
106
106
 
107
107
  const _texture = (key: string, src: string) => {
108
+ gl.loading++
108
109
  c.useProgram(pg)
109
- loadingImage(gl, src, (source) => {
110
- createTexture(c, source, uniforms(key)!, units(key))
110
+ loadingTexture(src, (source, isVideo) => {
111
+ const unit = units(key)
112
+ const loop = createTexture(c, source, uniforms(key)!, unit, isVideo)
113
+ if (loop) gl({ loop })
114
+ gl.loading--
111
115
  })
112
116
  }
113
117
 
@@ -128,8 +132,10 @@ export const webgl = async (gl: GL) => {
128
132
  }
129
133
 
130
134
  if (gl.isDepth) {
135
+ c.enable(c.DEPTH_TEST)
131
136
  c.depthFunc(c.LEQUAL)
132
137
  c.enable(c.CULL_FACE)
138
+ c.cullFace(c.BACK)
133
139
  }
134
140
 
135
141
  const webgl: WebGLState = { context: c, program: pg, storages: cp?.storages }
@@ -1,5 +1,5 @@
1
1
  import { nested as cached } from 'reev'
2
- import { is, loadingImage, getStride, WGSL_FS, WGSL_VS } from './helpers'
2
+ import { is, getStride, WGSL_FS, WGSL_VS, loadingTexture } from './helpers'
3
3
  import {
4
4
  createArrayBuffer,
5
5
  createBindGroup,
@@ -105,10 +105,18 @@ export const webgpu = async (gl: GL) => {
105
105
  }
106
106
 
107
107
  const _texture = (key: string, src: string) => {
108
- loadingImage(gl, src, (source) => {
109
- const { width, height } = source
108
+ gl.loading++
109
+ loadingTexture(src, (source, isVideo) => {
110
+ const [width, height] = isVideo
111
+ ? [source.videoWidth, source.videoHeight]
112
+ : [source.width, source.height]
110
113
  const { texture } = textures(key, width, height)
111
- device.queue.copyExternalImageToTexture({ source }, { texture }, { width, height })
114
+ const loop = () => {
115
+ device.queue.copyExternalImageToTexture({ source }, { texture }, { width, height })
116
+ }
117
+ loop()
118
+ if (isVideo) gl({ loop })
119
+ gl.loading--
112
120
  })
113
121
  }
114
122