glre 0.41.0 → 0.43.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 (144) hide show
  1. package/dist/addons.cjs +1 -1
  2. package/dist/addons.cjs.map +1 -1
  3. package/dist/addons.d.ts +379 -7
  4. package/dist/addons.js +1 -1
  5. package/dist/addons.js.map +1 -1
  6. package/dist/index.cjs +3 -3
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.js +3 -3
  10. package/dist/index.js.map +1 -1
  11. package/dist/native.d.ts +3 -0
  12. package/dist/node.cjs +12 -12
  13. package/dist/node.cjs.map +1 -1
  14. package/dist/node.d.ts +2 -1
  15. package/dist/node.js +12 -12
  16. package/dist/node.js.map +1 -1
  17. package/dist/react.d.ts +2 -0
  18. package/dist/solid.d.ts +2 -0
  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/index.ts +1 -0
  141. package/src/node/create.ts +2 -3
  142. package/src/node/utils/index.ts +2 -2
  143. package/src/types.ts +1 -0
  144. package/src/utils/webgl.ts +7 -0
@@ -0,0 +1,23 @@
1
+ import { Fn, Vec3, Float, vec3 } from '../../node'
2
+
3
+ export const icosahedronSDF = Fn(([p, radius]: [Vec3, Float]): Float => {
4
+ const phi = 2.61803398875 // Golden ratio constant (φ + 1)
5
+ const n1 = vec3(phi, 1, 0).normalize().toVar('n1')
6
+ const n2 = vec3(0.57735026919).toVar('n2') // 1/sqrt(3)
7
+
8
+ const normalizedP = p.abs().div(radius).toVar('normalizedP')
9
+
10
+ const a = normalizedP.dot(n1).toVar('a')
11
+ const b = normalizedP.dot(vec3(n1.z, n1.x, n1.y)).toVar('b')
12
+ const c = normalizedP.dot(vec3(n1.y, n1.z, n1.x)).toVar('c')
13
+ const d = normalizedP.dot(n2).sub(n1.x).toVar('d')
14
+
15
+ return a.max(b).max(c).sub(n1.x).max(d).mul(radius)
16
+ }).setLayout({
17
+ name: 'icosahedronSDF',
18
+ type: 'float',
19
+ inputs: [
20
+ { name: 'p', type: 'vec3' },
21
+ { name: 'radius', type: 'float' },
22
+ ],
23
+ })
@@ -1,7 +1,48 @@
1
+ export * from './arrowSDF'
2
+ export * from './boxFrameSDF'
3
+ export * from './capsuleSDF'
1
4
  export * from './circleSDF'
5
+ export * from './coneSDF'
6
+ export * from './crossSDF'
7
+ export * from './cubeSDF'
8
+ export * from './cylinderSDF'
9
+ export * from './dodecahedronSDF'
10
+ export * from './ellipsoidSDF'
11
+ export * from './flowerSDF'
12
+ export * from './gearSDF'
13
+ export * from './heartSDF'
14
+ export * from './hexPrismSDF'
15
+ export * from './icosahedronSDF'
16
+ export * from './juliaSDF'
17
+ export * from './kochSDF'
18
+ export * from './linkSDF'
19
+ export * from './mandelbulbSDF'
20
+ export * from './octahedronSDF'
21
+ export * from './octogonPrismSDF'
22
+ export * from './opElongate'
23
+ export * from './opExtrude'
24
+ export * from './opIntersection'
25
+ export * from './opOnion'
26
+ export * from './opRepeat'
27
+ export * from './opRevolve'
28
+ export * from './opRound'
29
+ export * from './opSubtraction'
30
+ export * from './opUnion'
31
+ export * from './planeSDF'
32
+ export * from './polySDF'
33
+ export * from './pyramidSDF'
34
+ export * from './raysSDF'
35
+ export * from './rhombSDF'
36
+ export * from './spiralSDF'
37
+ export * from './starSDF'
38
+ export * from './superShapeSDF'
39
+ export * from './tetrahedronSDF'
40
+ export * from './triPrismSDF'
2
41
  export * from './sphereSDF'
3
42
  export * from './rectSDF'
4
43
  export * from './boxSDF'
5
44
  export * from './lineSDF'
6
45
  export * from './hexSDF'
46
+ export * from './torusSDF'
7
47
  export * from './triSDF'
48
+ export * from './vesicaSDF'
@@ -0,0 +1,39 @@
1
+ import { Fn, Vec2, Float, vec2, float, Loop, If, Break } from '../../node'
2
+
3
+ export const juliaSDF = Fn(([st, center, c, r]: [Vec2, Vec2, Vec2, Float]): Float => {
4
+ const transformed = st.sub(0.5).mul(2).toVar('transformed')
5
+ const z = vec2(0).sub(transformed).mul(r).toVar('z')
6
+ const n = float(0).toVar('n')
7
+ const maxIter = 500
8
+
9
+ Loop(maxIter, ({ i }) => {
10
+ If(z.length().greaterThan(4), () => {
11
+ n.assign(i.toFloat().div(maxIter))
12
+ Break()
13
+ })
14
+ z.assign(vec2(z.x.pow(2).sub(z.y.pow(2)).add(c.x), z.x.mul(z.y).mul(2).add(c.y)))
15
+ })
16
+
17
+ return n
18
+ }).setLayout({
19
+ name: 'juliaSDF',
20
+ type: 'float',
21
+ inputs: [
22
+ { name: 'st', type: 'vec2' },
23
+ { name: 'center', type: 'vec2' },
24
+ { name: 'c', type: 'vec2' },
25
+ { name: 'r', type: 'float' },
26
+ ],
27
+ })
28
+
29
+ export const juliaSDFSimple = Fn(([st, c, r]: [Vec2, Vec2, Float]): Float => {
30
+ return juliaSDF(st, vec2(0.5), c, r)
31
+ }).setLayout({
32
+ name: 'juliaSDFSimple',
33
+ type: 'float',
34
+ inputs: [
35
+ { name: 'st', type: 'vec2' },
36
+ { name: 'c', type: 'vec2' },
37
+ { name: 'r', type: 'float' },
38
+ ],
39
+ })
@@ -0,0 +1,49 @@
1
+ import { Fn, Vec2, Int, Float, vec2, mat2, float, Loop, Break, If } from '../../node'
2
+
3
+ export const kochSDF = Fn(([st, center, N]: [Vec2, Vec2, Int]): Float => {
4
+ st = st.sub(center).toVar()
5
+ st.assign(st.mul(3))
6
+ const r3 = float(3).sqrt().toVar('r3')
7
+ st.assign(st.abs())
8
+ st.assign(st.add(r3.mul(vec2(st.y.negate(), st.x))))
9
+ st.assign(vec2(st.x, st.y.sub(1)))
10
+ const w = float(0.5).toVar('w')
11
+ const m = mat2(r3, 3, -3, r3).mul(0.5).toVar('m')
12
+
13
+ Loop(20, ({ i }) => {
14
+ If(i.toFloat().greaterThanEqual(N.toFloat()), () => {
15
+ Break()
16
+ })
17
+ st.assign(
18
+ vec2(r3.negate(), 3)
19
+ .mul(0.5)
20
+ .sub(m.mul(vec2(st.y, st.x.abs())))
21
+ )
22
+ w.assign(w.div(r3))
23
+ })
24
+
25
+ const d = st.y
26
+ .sign()
27
+ .mul(vec2(st.y, st.x.abs().sub(r3).max(0)).length())
28
+ .toVar('d')
29
+ return d.mul(w)
30
+ }).setLayout({
31
+ name: 'kochSDF',
32
+ type: 'float',
33
+ inputs: [
34
+ { name: 'st', type: 'vec2' },
35
+ { name: 'center', type: 'vec2' },
36
+ { name: 'N', type: 'int' },
37
+ ],
38
+ })
39
+
40
+ export const kochSDFSimple = Fn(([st, N]: [Vec2, Int]): Float => {
41
+ return kochSDF(st, vec2(0.5), N)
42
+ }).setLayout({
43
+ name: 'kochSDFSimple',
44
+ type: 'float',
45
+ inputs: [
46
+ { name: 'st', type: 'vec2' },
47
+ { name: 'N', type: 'int' },
48
+ ],
49
+ })
@@ -0,0 +1,15 @@
1
+ import { Fn, Vec3, Float, vec3, vec2 } from '../../node'
2
+
3
+ export const linkSDF = Fn(([p, le, r1, r2]: [Vec3, Float, Float, Float]): Float => {
4
+ const q = vec3(p.x, p.y.abs().sub(le).max(0), p.z).toVar('q')
5
+ return vec2(vec2(q.x, q.y).length().sub(r1), q.z).length().sub(r2)
6
+ }).setLayout({
7
+ name: 'linkSDF',
8
+ type: 'float',
9
+ inputs: [
10
+ { name: 'p', type: 'vec3' },
11
+ { name: 'le', type: 'float' },
12
+ { name: 'r1', type: 'float' },
13
+ { name: 'r2', type: 'float' },
14
+ ],
15
+ })
@@ -0,0 +1,41 @@
1
+ import { Fn, Vec3, Vec2, vec2, vec3, float, Loop, If, Break } from '../../node'
2
+ import { cart2polar3D } from '../space/cart2polar'
3
+
4
+ export const mandelbulbSDF = Fn(([st]: [Vec3]): Vec2 => {
5
+ const zeta = st.toVar('zeta')
6
+ const m = st.dot(st).toVar('m')
7
+ const dz = float(1).toVar('dz')
8
+ const n = float(8).toVar('n')
9
+ const maxiterations = 20
10
+ const iterations = float(0).toVar('iterations')
11
+ const r = float(0).toVar('r')
12
+ const dr = float(1).toVar('dr')
13
+
14
+ Loop(maxiterations, () => {
15
+ dz.assign(n.mul(m.pow(3.5)).mul(dz).add(1))
16
+ const sphericalZ = cart2polar3D(zeta).toVar('sphericalZ')
17
+ const newx = sphericalZ.x
18
+ .pow(n)
19
+ .mul(sphericalZ.y.mul(n).sin())
20
+ .mul(sphericalZ.z.mul(n).cos())
21
+ .toVar('newx')
22
+ const newy = sphericalZ.x
23
+ .pow(n)
24
+ .mul(sphericalZ.y.mul(n).sin())
25
+ .mul(sphericalZ.z.mul(n).sin())
26
+ .toVar('newy')
27
+ const newz = sphericalZ.x.pow(n).mul(sphericalZ.y.mul(n).cos()).toVar('newz')
28
+ zeta.assign(vec3(newx.add(st.x), newy.add(st.y), newz.add(st.z)))
29
+ m.assign(zeta.dot(zeta))
30
+ If(m.greaterThan(2), () => {
31
+ Break()
32
+ })
33
+ iterations.assign(iterations.add(1))
34
+ })
35
+
36
+ return vec2(float(0.25).mul(m.log()).mul(m.sqrt()).div(dz), iterations)
37
+ }).setLayout({
38
+ name: 'mandelbulbSDF',
39
+ type: 'vec2',
40
+ inputs: [{ name: 'st', type: 'vec3' }],
41
+ })
@@ -0,0 +1,30 @@
1
+ import { Fn, Vec3, Float } from '../../node'
2
+
3
+ export const octahedronSDF = Fn(([p, s]: [Vec3, Float]): Float => {
4
+ const pAbs = p.abs().toVar('pAbs')
5
+ const m = pAbs.x.add(pAbs.y).add(pAbs.z).sub(s).toVar('m')
6
+ return m.mul(0.57735027)
7
+ }).setLayout({
8
+ name: 'octahedronSDF',
9
+ type: 'float',
10
+ inputs: [
11
+ { name: 'p', type: 'vec3' },
12
+ { name: 's', type: 'float' },
13
+ ],
14
+ })
15
+
16
+ export const octahedronSDFExact = Fn(([p, s]: [Vec3, Float]): Float => {
17
+ const pAbs = p.abs().toVar('pAbs')
18
+ const m = pAbs.x.add(pAbs.y).add(pAbs.z).sub(s).toVar('m')
19
+ const o = pAbs.mul(3).sub(m).min(0).toVar('o')
20
+ o.assign(pAbs.mul(6).sub(m.mul(2)).sub(o.mul(3)).add(o.x.add(o.y).add(o.z)).max(0))
21
+ const oSum = o.x.add(o.y).add(o.z).toVar('oSum')
22
+ return pAbs.sub(s.mul(o).div(oSum)).length()
23
+ }).setLayout({
24
+ name: 'octahedronSDFExact',
25
+ type: 'float',
26
+ inputs: [
27
+ { name: 'p', type: 'vec3' },
28
+ { name: 's', type: 'float' },
29
+ ],
30
+ })
@@ -0,0 +1,19 @@
1
+ import { Fn, Vec3, Float, vec3, vec2 } from '../../node'
2
+
3
+ export const octogonPrismSDF = Fn(([p, r, h]: [Vec3, Float, Float]): Float => {
4
+ const k = vec3(-0.9238795325, 0.3826834323, 0.4142135623).toVar('k')
5
+ p.assign(p.abs())
6
+ p.assign(vec3(p.xy.sub(vec2(k.x, k.y).mul(vec2(k.x, k.y).dot(p.xy).min(0).mul(2))), p.z))
7
+ p.assign(vec3(p.xy.sub(vec2(k.x.negate(), k.y).mul(vec2(k.x.negate(), k.y).dot(p.xy).min(0).mul(2))), p.z))
8
+ p.assign(vec3(p.xy.sub(vec2(p.x.clamp(k.z.negate().mul(r), k.z.mul(r)), r)), p.z))
9
+ const d = vec2(p.xy.length().mul(p.y.sign()), p.z.sub(h)).toVar('d')
10
+ return d.x.max(d.y).min(0).add(d.max(0).length())
11
+ }).setLayout({
12
+ name: 'octogonPrismSDF',
13
+ type: 'float',
14
+ inputs: [
15
+ { name: 'p', type: 'vec3' },
16
+ { name: 'r', type: 'float' },
17
+ { name: 'h', type: 'float' },
18
+ ],
19
+ })
@@ -0,0 +1,35 @@
1
+ import { Fn, Vec2, Vec3, Vec4, vec4 } from '../../node'
2
+
3
+ export const opElongateVec2 = Fn(([p, h]: [Vec2, Vec2]): Vec2 => {
4
+ return p.sub(p.clamp(h.negate(), h))
5
+ }).setLayout({
6
+ name: 'opElongateVec2',
7
+ type: 'vec2',
8
+ inputs: [
9
+ { name: 'p', type: 'vec2' },
10
+ { name: 'h', type: 'vec2' }
11
+ ]
12
+ })
13
+
14
+ export const opElongateVec3 = Fn(([p, h]: [Vec3, Vec3]): Vec3 => {
15
+ return p.sub(p.clamp(h.negate(), h))
16
+ }).setLayout({
17
+ name: 'opElongateVec3',
18
+ type: 'vec3',
19
+ inputs: [
20
+ { name: 'p', type: 'vec3' },
21
+ { name: 'h', type: 'vec3' }
22
+ ]
23
+ })
24
+
25
+ export const opElongateVec4 = Fn(([p, h]: [Vec4, Vec4]): Vec4 => {
26
+ const q = p.abs().sub(h).toVar('q')
27
+ return vec4(q.max(0), q.x.max(q.y.max(q.z)).min(0))
28
+ }).setLayout({
29
+ name: 'opElongateVec4',
30
+ type: 'vec4',
31
+ inputs: [
32
+ { name: 'p', type: 'vec4' },
33
+ { name: 'h', type: 'vec4' }
34
+ ]
35
+ })
@@ -0,0 +1,14 @@
1
+ import { Fn, Vec3, Float, vec2 } from '../../node'
2
+
3
+ export const opExtrude = Fn(([p, sdf, h]: [Vec3, Float, Float]): Float => {
4
+ const w = vec2(sdf, p.z.abs().sub(h)).toVar('w')
5
+ return w.x.max(w.y).min(0).add(w.max(0).length())
6
+ }).setLayout({
7
+ name: 'opExtrude',
8
+ type: 'float',
9
+ inputs: [
10
+ { name: 'p', type: 'vec3' },
11
+ { name: 'sdf', type: 'float' },
12
+ { name: 'h', type: 'float' },
13
+ ],
14
+ })
@@ -0,0 +1,25 @@
1
+ import { Fn, Float, mix, float } from '../../node'
2
+
3
+ export const opIntersection = Fn(([d1, d2]: [Float, Float]): Float => {
4
+ return d1.max(d2)
5
+ }).setLayout({
6
+ name: 'opIntersection',
7
+ type: 'float',
8
+ inputs: [
9
+ { name: 'd1', type: 'float' },
10
+ { name: 'd2', type: 'float' },
11
+ ],
12
+ })
13
+
14
+ export const opIntersectionSmooth = Fn(([d1, d2, k]: [Float, Float, Float]): Float => {
15
+ const h = float(0.5).sub(d2.sub(d1).div(k).mul(0.5)).saturate().toVar('h')
16
+ return mix(d2, d1, h).add(k.mul(h).mul(h.oneMinus()))
17
+ }).setLayout({
18
+ name: 'opIntersectionSmooth',
19
+ type: 'float',
20
+ inputs: [
21
+ { name: 'd1', type: 'float' },
22
+ { name: 'd2', type: 'float' },
23
+ { name: 'k', type: 'float' },
24
+ ],
25
+ })
@@ -0,0 +1,12 @@
1
+ import { Fn, Float } from '../../node'
2
+
3
+ export const opOnion = Fn(([d, h]: [Float, Float]): Float => {
4
+ return d.abs().sub(h)
5
+ }).setLayout({
6
+ name: 'opOnion',
7
+ type: 'float',
8
+ inputs: [
9
+ { name: 'd', type: 'float' },
10
+ { name: 'h', type: 'float' },
11
+ ],
12
+ })
@@ -0,0 +1,49 @@
1
+ import { Fn, Vec2, Vec3, Float, mod } from '../../node'
2
+
3
+ export const opRepeatVec2 = Fn(([p, s]: [Vec2, Float]): Vec2 => {
4
+ return mod(p.add(s.mul(0.5)), s).sub(s.mul(0.5))
5
+ }).setLayout({
6
+ name: 'opRepeatVec2',
7
+ type: 'vec2',
8
+ inputs: [
9
+ { name: 'p', type: 'vec2' },
10
+ { name: 's', type: 'float' }
11
+ ]
12
+ })
13
+
14
+ export const opRepeatVec3 = Fn(([p, c]: [Vec3, Vec3]): Vec3 => {
15
+ return mod(p.add(c.mul(0.5)), c).sub(c.mul(0.5))
16
+ }).setLayout({
17
+ name: 'opRepeatVec3',
18
+ type: 'vec3',
19
+ inputs: [
20
+ { name: 'p', type: 'vec3' },
21
+ { name: 'c', type: 'vec3' }
22
+ ]
23
+ })
24
+
25
+ export const opRepeatVec2Limited = Fn(([p, lima, limb, s]: [Vec2, Vec2, Vec2, Float]): Vec2 => {
26
+ return p.sub(s.mul(p.div(s).floor().clamp(lima, limb)))
27
+ }).setLayout({
28
+ name: 'opRepeatVec2Limited',
29
+ type: 'vec2',
30
+ inputs: [
31
+ { name: 'p', type: 'vec2' },
32
+ { name: 'lima', type: 'vec2' },
33
+ { name: 'limb', type: 'vec2' },
34
+ { name: 's', type: 'float' }
35
+ ]
36
+ })
37
+
38
+ export const opRepeatVec3Limited = Fn(([p, lima, limb, s]: [Vec3, Vec3, Vec3, Float]): Vec3 => {
39
+ return p.sub(s.mul(p.div(s).floor().clamp(lima, limb)))
40
+ }).setLayout({
41
+ name: 'opRepeatVec3Limited',
42
+ type: 'vec3',
43
+ inputs: [
44
+ { name: 'p', type: 'vec3' },
45
+ { name: 'lima', type: 'vec3' },
46
+ { name: 'limb', type: 'vec3' },
47
+ { name: 's', type: 'float' }
48
+ ]
49
+ })
@@ -0,0 +1,12 @@
1
+ import { Fn, Vec3, Vec2, Float, vec2 } from '../../node'
2
+
3
+ export const opRevolve = Fn(([p, w]: [Vec3, Float]): Vec2 => {
4
+ return vec2(vec2(p.x, p.z).length().sub(w), p.y)
5
+ }).setLayout({
6
+ name: 'opRevolve',
7
+ type: 'vec2',
8
+ inputs: [
9
+ { name: 'p', type: 'vec3' },
10
+ { name: 'w', type: 'float' },
11
+ ],
12
+ })
@@ -0,0 +1,12 @@
1
+ import { Fn, Float } from '../../node'
2
+
3
+ export const opRound = Fn(([d, h]: [Float, Float]): Float => {
4
+ return d.sub(h)
5
+ }).setLayout({
6
+ name: 'opRound',
7
+ type: 'float',
8
+ inputs: [
9
+ { name: 'd', type: 'float' },
10
+ { name: 'h', type: 'float' },
11
+ ],
12
+ })
@@ -0,0 +1,50 @@
1
+ import { Fn, Float, Vec4, vec4, select } from '../../node'
2
+
3
+ export const opSubtraction = Fn(([d1, d2]: [Float, Float]): Float => {
4
+ return d1.negate().max(d2)
5
+ }).setLayout({
6
+ name: 'opSubtraction',
7
+ type: 'float',
8
+ inputs: [
9
+ { name: 'd1', type: 'float' },
10
+ { name: 'd2', type: 'float' }
11
+ ]
12
+ })
13
+
14
+ export const opSubtractionVec4 = Fn(([d1, d2]: [Vec4, Vec4]): Vec4 => {
15
+ return d1.negate().select(d2, d1.w.negate().greaterThan(d2.w))
16
+ }).setLayout({
17
+ name: 'opSubtractionVec4',
18
+ type: 'vec4',
19
+ inputs: [
20
+ { name: 'd1', type: 'vec4' },
21
+ { name: 'd2', type: 'vec4' }
22
+ ]
23
+ })
24
+
25
+ export const opSubtractionSmooth = Fn(([d1, d2, k]: [Float, Float, Float]): Float => {
26
+ const h = d2.add(d1).div(k).mul(0.5).sub(0.5).negate().clamp(0, 1).toVar('h')
27
+ return d2.mix(d1.negate(), h).add(k.mul(h).mul(h.oneMinus()))
28
+ }).setLayout({
29
+ name: 'opSubtractionSmooth',
30
+ type: 'float',
31
+ inputs: [
32
+ { name: 'd1', type: 'float' },
33
+ { name: 'd2', type: 'float' },
34
+ { name: 'k', type: 'float' }
35
+ ]
36
+ })
37
+
38
+ export const opSubtractionSmoothVec4 = Fn(([d1, d2, k]: [Vec4, Vec4, Float]): Vec4 => {
39
+ const h = d2.w.add(d1.w).div(k).mul(0.5).sub(0.5).negate().clamp(0, 1).toVar('h')
40
+ const result = d2.mix(d1.negate(), h).toVar('result')
41
+ return vec4(result.xyz, result.w.add(k.mul(h).mul(h.oneMinus())))
42
+ }).setLayout({
43
+ name: 'opSubtractionSmoothVec4',
44
+ type: 'vec4',
45
+ inputs: [
46
+ { name: 'd1', type: 'vec4' },
47
+ { name: 'd2', type: 'vec4' },
48
+ { name: 'k', type: 'float' }
49
+ ]
50
+ })
@@ -0,0 +1,39 @@
1
+ import { Fn, Float, Vec4, vec4 } from '../../node'
2
+
3
+ export const opUnion = Fn(([d1, d2]: [Float, Float]): Float => {
4
+ return d1.min(d2)
5
+ }).setLayout({
6
+ name: 'opUnion',
7
+ type: 'float',
8
+ inputs: [
9
+ { name: 'd1', type: 'float' },
10
+ { name: 'd2', type: 'float' },
11
+ ],
12
+ })
13
+
14
+ export const opUnionSmooth = Fn(([d1, d2, k]: [Float, Float, Float]): Float => {
15
+ const h = d2.sub(d1).div(k).mul(0.5).add(0.5).clamp(0, 1).toVar('h')
16
+ return d2.mix(d1, h).sub(k.mul(h).mul(h.oneMinus()))
17
+ }).setLayout({
18
+ name: 'opUnionSmooth',
19
+ type: 'float',
20
+ inputs: [
21
+ { name: 'd1', type: 'float' },
22
+ { name: 'd2', type: 'float' },
23
+ { name: 'k', type: 'float' },
24
+ ],
25
+ })
26
+
27
+ export const opUnionSmoothVec4 = Fn(([d1, d2, k]: [Vec4, Vec4, Float]): Vec4 => {
28
+ const h = d2.w.sub(d1.w).div(k).mul(0.5).add(0.5).clamp(0, 1).toVar('h')
29
+ const result = d2.mix(d1, h).toVar('result')
30
+ return vec4(result.xyz, result.w.sub(k.mul(h).mul(h.oneMinus())))
31
+ }).setLayout({
32
+ name: 'opUnionSmoothVec4',
33
+ type: 'vec4',
34
+ inputs: [
35
+ { name: 'd1', type: 'vec4' },
36
+ { name: 'd2', type: 'vec4' },
37
+ { name: 'k', type: 'float' },
38
+ ],
39
+ })
@@ -0,0 +1,21 @@
1
+ import { Fn, Vec3, Float } from '../../node'
2
+
3
+ export const planeSDF = Fn(([p]: [Vec3]): Float => {
4
+ return p.y
5
+ }).setLayout({
6
+ name: 'planeSDF',
7
+ type: 'float',
8
+ inputs: [{ name: 'p', type: 'vec3' }],
9
+ })
10
+
11
+ export const planeSDFNormal = Fn(([p, planePoint, planeNormal]: [Vec3, Vec3, Vec3]): Float => {
12
+ return planeNormal.dot(p).add(planeNormal.dot(planePoint)).div(planeNormal.length())
13
+ }).setLayout({
14
+ name: 'planeSDFNormal',
15
+ type: 'float',
16
+ inputs: [
17
+ { name: 'p', type: 'vec3' },
18
+ { name: 'planePoint', type: 'vec3' },
19
+ { name: 'planeNormal', type: 'vec3' },
20
+ ],
21
+ })
@@ -0,0 +1,32 @@
1
+ import { Fn, Vec2, Float, Int, atan2 } from '../../node'
2
+ import { PI, TAU } from '../math/const'
3
+
4
+ export const polySDF = Fn(([st, V]: [Vec2, Int]): Float => {
5
+ const p = st.mul(2).sub(1).toVar('p')
6
+ const a = atan2(p.y, p.x).add(PI).toVar('a')
7
+ const r = p.length().toVar('r')
8
+ const v = TAU.div(V.toFloat()).toVar('v')
9
+ return a.div(v).add(0.5).floor().mul(v).sub(a).cos().mul(r)
10
+ }).setLayout({
11
+ name: 'polySDF',
12
+ type: 'float',
13
+ inputs: [
14
+ { name: 'st', type: 'vec2' },
15
+ { name: 'V', type: 'int' }
16
+ ]
17
+ })
18
+
19
+ export const polySDFFloat = Fn(([st, V]: [Vec2, Float]): Float => {
20
+ const p = st.mul(2).sub(1).toVar('p')
21
+ const a = atan2(p.y, p.x).add(PI).toVar('a')
22
+ const r = p.length().toVar('r')
23
+ const v = TAU.div(V).toVar('v')
24
+ return a.div(v).add(0.5).floor().mul(v).sub(a).cos().mul(r)
25
+ }).setLayout({
26
+ name: 'polySDFFloat',
27
+ type: 'float',
28
+ inputs: [
29
+ { name: 'st', type: 'vec2' },
30
+ { name: 'V', type: 'float' }
31
+ ]
32
+ })
@@ -0,0 +1,29 @@
1
+ import { Fn, Vec3, Float, vec3, vec2, select, float } from '../../node'
2
+
3
+ export const pyramidSDF = Fn(([p, h]: [Vec3, Float]): Float => {
4
+ const m2 = h.mul(h).add(0.25).toVar('m2')
5
+ const pxz = vec2(p.x, p.z).abs().toVar('pxz')
6
+ const pxzSwapped = select(vec2(pxz.y, pxz.x), pxz, pxz.y.greaterThan(pxz.x)).toVar('pxzSwapped')
7
+ const pxzFinal = pxzSwapped.sub(0.5).toVar('pxzFinal')
8
+ p.assign(vec3(pxzFinal.x, p.y, pxzFinal.y))
9
+ const q = vec3(p.z, h.mul(p.y).sub(p.x.mul(0.5)), h.mul(p.x).add(p.y.mul(0.5))).toVar('q')
10
+ const s = q.x.negate().max(0).toVar('s')
11
+ const t = q.y.sub(p.z.mul(0.5)).div(m2.add(0.25)).clamp(0, 1).toVar('t')
12
+ const a = m2.mul(q.x.add(s)).mul(q.x.add(s)).add(q.y.mul(q.y)).toVar('a')
13
+ const b = m2
14
+ .mul(q.x.add(t.mul(0.5)))
15
+ .mul(q.x.add(t.mul(0.5)))
16
+ .add(q.y.sub(m2.mul(t)).mul(q.y.sub(m2.mul(t))))
17
+ .toVar('b')
18
+ const d2 = select(float(0), a.min(b), q.y.min(q.x.negate().mul(m2).sub(q.y.mul(0.5))).greaterThan(0))
19
+ .toFloat()
20
+ .toVar('d2')
21
+ return d2.add(q.z.mul(q.z)).div(m2).sqrt().mul(q.z.max(p.y.negate()).sign())
22
+ }).setLayout({
23
+ name: 'pyramidSDF',
24
+ type: 'float',
25
+ inputs: [
26
+ { name: 'p', type: 'vec3' },
27
+ { name: 'h', type: 'float' },
28
+ ],
29
+ })
@@ -0,0 +1,14 @@
1
+ import { Fn, Vec2, Int, Float, atan2 } from '../../node'
2
+ import { TAU } from '../math/const'
3
+
4
+ export const raysSDF = Fn(([st, N]: [Vec2, Int]): Float => {
5
+ const centered = st.sub(0.5).toVar('centered')
6
+ return atan2(centered.y, centered.x).div(TAU).mul(N.toFloat()).fract()
7
+ }).setLayout({
8
+ name: 'raysSDF',
9
+ type: 'float',
10
+ inputs: [
11
+ { name: 'st', type: 'vec2' },
12
+ { name: 'N', type: 'int' },
13
+ ],
14
+ })
@@ -0,0 +1,10 @@
1
+ import { Fn, Vec2, Float, vec2 } from '../../node'
2
+ import { triSDF } from './triSDF'
3
+
4
+ export const rhombSDF = Fn(([st]: [Vec2]): Float => {
5
+ return triSDF(st).max(triSDF(vec2(st.x, st.y.oneMinus())))
6
+ }).setLayout({
7
+ name: 'rhombSDF',
8
+ type: 'float',
9
+ inputs: [{ name: 'st', type: 'vec2' }],
10
+ })
@@ -0,0 +1,15 @@
1
+ import { Fn, Vec2, Float, atan2 } from '../../node'
2
+
3
+ export const spiralSDF = Fn(([st, t]: [Vec2, Float]): Float => {
4
+ const centeredSt = st.sub(0.5).toVar('centeredSt')
5
+ const r = centeredSt.dot(centeredSt).toVar('r')
6
+ const a = atan2(centeredSt.y, centeredSt.x).toVar('a')
7
+ return r.log().mul(t).add(a.mul(0.159)).fract().sin().abs()
8
+ }).setLayout({
9
+ name: 'spiralSDF',
10
+ type: 'float',
11
+ inputs: [
12
+ { name: 'st', type: 'vec2' },
13
+ { name: 't', type: 'float' },
14
+ ],
15
+ })