glre 0.37.0 → 0.39.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 (49) hide show
  1. package/dist/addons.cjs +2 -0
  2. package/dist/addons.cjs.map +1 -0
  3. package/dist/addons.d.ts +457 -0
  4. package/dist/addons.js +2 -0
  5. package/dist/addons.js.map +1 -0
  6. package/dist/index.cjs +31 -40
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.ts +170 -1791
  9. package/dist/index.js +31 -40
  10. package/dist/index.js.map +1 -1
  11. package/dist/native.cjs +1 -45
  12. package/dist/native.cjs.map +1 -1
  13. package/dist/native.d.ts +511 -11
  14. package/dist/native.js +1 -45
  15. package/dist/native.js.map +1 -1
  16. package/dist/node.cjs +40 -0
  17. package/dist/node.cjs.map +1 -0
  18. package/dist/node.d.ts +614 -0
  19. package/dist/node.js +40 -0
  20. package/dist/node.js.map +1 -0
  21. package/dist/react.cjs +1 -45
  22. package/dist/react.cjs.map +1 -1
  23. package/dist/react.d.ts +506 -4
  24. package/dist/react.js +1 -45
  25. package/dist/react.js.map +1 -1
  26. package/dist/solid.cjs +1 -45
  27. package/dist/solid.cjs.map +1 -1
  28. package/dist/solid.d.ts +506 -4
  29. package/dist/solid.js +1 -45
  30. package/dist/solid.js.map +1 -1
  31. package/package.json +56 -3
  32. package/src/addons/index.ts +6 -0
  33. package/src/index.ts +6 -22
  34. package/src/node/{core.ts → build.ts} +3 -7
  35. package/src/node/create.ts +73 -0
  36. package/src/node/index.ts +63 -47
  37. package/src/node/scope.ts +65 -50
  38. package/src/node/types.ts +222 -164
  39. package/src/node/utils/const.ts +64 -3
  40. package/src/node/utils/index.ts +8 -5
  41. package/src/node/utils/infer.ts +23 -35
  42. package/src/node/utils/parse.ts +15 -18
  43. package/src/node/utils/utils.ts +13 -12
  44. package/src/types.ts +5 -7
  45. package/src/utils/pipeline.ts +3 -3
  46. package/src/utils/program.ts +7 -2
  47. package/src/{webgl.ts → utils/webgl.ts} +24 -14
  48. package/src/{webgpu.ts → utils/webgpu.ts} +28 -7
  49. package/src/node/node.ts +0 -64
package/src/node/index.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { hex2rgb } from './utils'
2
- import { builtin as b, conversion as c, function_ as f, uniform as u } from './node'
2
+ import { builtin as b, conversion as c, function_ as f, uniform as u } from './create'
3
3
  import { is } from '../utils/helpers'
4
- import type { Constants as C, X, NodeProxy } from './types'
5
- export * from './core'
6
- export * from './node'
4
+ import type { Constants as C, Float, X, Y } from './types'
5
+ export * from './build'
6
+ export * from './create'
7
7
  export * from './scope'
8
8
  export * from './types'
9
9
 
@@ -29,28 +29,28 @@ export const screenCoordinate = b<'vec2'>('screenCoordinate')
29
29
  export const screenUV = b<'vec2'>('screenUV')
30
30
 
31
31
  // Type constructors with proper type inference
32
- export const float = (x?: X) => c('float', x)
33
- export const int = (x?: X) => c('int', x)
34
- export const uint = (x?: X) => c('uint', x)
35
- export const bool = (x?: X) => c('bool', x)
36
- export const vec2 = (x?: X, y?: X) => c('vec2', x, y)
37
- export const vec3 = (x?: X, y?: X, z?: X) => c('vec3', x, y, z)
38
- export const vec4 = (x?: X, y?: X, z?: X, w?: X) => c('vec4', x, y, z, w)
39
- export const mat2 = (...args: X[]) => c('mat2', ...args)
40
- export const mat3 = (...args: X[]) => c('mat3', ...args)
41
- export const mat4 = (...args: X[]) => c('mat4', ...args)
42
- export const ivec2 = (x?: X, y?: X) => c('ivec2', x, y)
43
- export const ivec3 = (x?: X, y?: X, z?: X) => c('ivec3', x, y, z)
44
- export const ivec4 = (x?: X, y?: X, z?: X, w?: X) => c('ivec4', x, y, z, w)
45
- export const uvec2 = (x?: X, y?: X) => c('uvec2', x, y)
46
- export const uvec3 = (x?: X, y?: X, z?: X) => c('uvec3', x, y, z)
47
- export const uvec4 = (x?: X, y?: X, z?: X, w?: X) => c('uvec4', x, y, z, w)
48
- export const bvec2 = (x?: X, y?: X) => c('bvec2', x, y)
49
- export const bvec3 = (x?: X, y?: X, z?: X) => c('bvec3', x, y, z)
50
- export const bvec4 = (x?: X, y?: X, z?: X, w?: X) => c('bvec4', x, y, z, w)
51
- export const texture2D = (x?: X) => c('texture', x)
32
+ export const float = (x?: Y) => c('float', x)
33
+ export const int = (x?: Y) => c('int', x)
34
+ export const uint = (x?: Y) => c('uint', x)
35
+ export const bool = (x?: Y) => c('bool', x)
36
+ export const vec2 = (x?: Y, y?: Y) => c('vec2', x, y)
37
+ export const vec3 = (x?: Y, y?: Y, z?: Y) => c('vec3', x, y, z)
38
+ export const vec4 = (x?: Y, y?: Y, z?: Y, w?: Y) => c('vec4', x, y, z, w)
39
+ export const mat2 = (...args: Y[]) => c('mat2', ...args)
40
+ export const mat3 = (...args: Y[]) => c('mat3', ...args)
41
+ export const mat4 = (...args: Y[]) => c('mat4', ...args)
42
+ export const ivec2 = (x?: Y, y?: Y) => c('ivec2', x, y)
43
+ export const ivec3 = (x?: Y, y?: Y, z?: Y) => c('ivec3', x, y, z)
44
+ export const ivec4 = (x?: Y, y?: Y, z?: Y, w?: Y) => c('ivec4', x, y, z, w)
45
+ export const uvec2 = (x?: Y, y?: Y) => c('uvec2', x, y)
46
+ export const uvec3 = (x?: Y, y?: Y, z?: Y) => c('uvec3', x, y, z)
47
+ export const uvec4 = (x?: Y, y?: Y, z?: Y, w?: Y) => c('uvec4', x, y, z, w)
48
+ export const bvec2 = (x?: Y, y?: Y) => c('bvec2', x, y)
49
+ export const bvec3 = (x?: Y, y?: Y, z?: Y) => c('bvec3', x, y, z)
50
+ export const bvec4 = (x?: Y, y?: Y, z?: Y, w?: Y) => c('bvec4', x, y, z, w)
51
+ export const texture2D = (x?: Y) => c('texture', x)
52
52
  export const sampler2D = () => c('sampler2D')
53
- export const color = (r?: X, g?: X, b?: X) => {
53
+ export const color = (r?: Y, g?: Y, b?: Y) => {
54
54
  if (is.num(r) && is.und(g) && is.und(b)) return vec3(...hex2rgb(r))
55
55
  return vec3(r, g, b)
56
56
  }
@@ -64,20 +64,26 @@ export const uv = position.xy.div(iResolution)
64
64
  /**
65
65
  * 1.1. unified with:
66
66
  * 2.1. const.ts BUILTIN_VARIABLES and
67
- * 3.1. types.ts BaseNodeProxy
67
+ * 3.1. types.ts _N
68
68
  */
69
69
  // 0. Always return bool
70
70
  export const all = <T extends C>(x: X<T>) => f<'bool'>('all', x)
71
71
  export const any = <T extends C>(x: X<T>) => f<'bool'>('any', x)
72
72
 
73
- // 2. Always return float
74
- export const length = (x: X) => f<'float'>('length', x)
73
+ // 2. Always return float with WGSL-compliant type constraints and unified parameter types
74
+ export const determinant = <T extends 'mat2' | 'mat3' | 'mat4'>(x: X<T>) => f<'float'>('determinant', x)
75
+ export const distance = <T extends 'vec2' | 'vec3' | 'vec4', U extends C>(x: X<T>, y: number | X<U>) =>
76
+ f<'float'>('distance', x, y)
77
+ export const dot = <T extends 'vec2' | 'vec3' | 'vec4' | 'ivec2' | 'ivec3' | 'ivec4', U extends C>(
78
+ x: X<T>,
79
+ y: number | X<U>
80
+ ) => f<T extends `ivec${string}` ? 'int' : 'float'>('dot', x, y)
81
+ export const length = <T extends 'vec2' | 'vec3' | 'vec4'>(x: X<T>) => f<'float'>('length', x)
75
82
  export const lengthSq = (x: X) => f<'float'>('lengthSq', x)
76
- export const distance = (x: X, y: X) => f<'float'>('distance', x, y)
77
- export const dot = (x: X, y: X) => f<'float'>('dot', x, y)
83
+ export const luminance = (x: X) => f<'float'>('luminance', x)
78
84
 
79
- // 3. Always return vec3
80
- export const cross = (x: X<'vec3'>, y: X<'vec3'>) => f<'vec3'>('cross', x, y)
85
+ // 3. Always return vec3 with vec3 constraint and unified parameter types
86
+ export const cross = <U extends C = 'vec3'>(x: X<'vec3'>, y: number | X<U>) => f<'vec3'>('cross', x, y)
81
87
 
82
88
  // 4. Always return vec4
83
89
  export const cubeTexture = (x: X, y: X, z?: X) => f<'vec4'>('cubeTexture', x, y, z)
@@ -88,7 +94,7 @@ export const textureLod = (x: X, y: X, z?: X) => f<'vec4'>('textureLod', x, y, z
88
94
  /**
89
95
  * 1.2. unified with:
90
96
  * 2.2. const.ts FUNCTIONS and
91
- * 3.2. types.ts BaseNodeProxy
97
+ * 3.2. types.ts _N
92
98
  */
93
99
  // 0. Component-wise functions
94
100
  export const abs = <T extends C>(x: X<T>) => f<T>('abs', x)
@@ -113,7 +119,7 @@ export const inverseSqrt = <T extends C>(x: X<T>) => f<T>('inverseSqrt', x)
113
119
  export const log = <T extends C>(x: X<T>) => f<T>('log', x)
114
120
  export const log2 = <T extends C>(x: X<T>) => f<T>('log2', x)
115
121
  export const negate = <T extends C>(x: X<T>) => f<T>('negate', x)
116
- export const normalize = <T extends C>(x: X<T>) => f<T>('normalize', x)
122
+ export const normalize = <T extends 'vec2' | 'vec3' | 'vec4'>(x: X<T>) => f<T>('normalize', x)
117
123
  export const oneMinus = <T extends C>(x: X<T>) => f<T>('oneMinus', x)
118
124
  export const radians = <T extends C>(x: X<T>) => f<T>('radians', x)
119
125
  export const reciprocal = <T extends C>(x: X<T>) => f<T>('reciprocal', x)
@@ -127,17 +133,27 @@ export const tan = <T extends C>(x: X<T>) => f<T>('tan', x)
127
133
  export const tanh = <T extends C>(x: X<T>) => f<T>('tanh', x)
128
134
  export const trunc = <T extends C>(x: X<T>) => f<T>('trunc', x)
129
135
 
130
- // 1. Functions where first argument determines return type
131
- export const atan2 = <T extends C>(x: X<T>, y: X) => f<T>('atan2', x, y)
132
- export const clamp = <T extends C>(x: X<T>, y: X, z: X) => f<T>('clamp', x, y, z)
133
- export const max = <T extends C>(x: X<T>, y: X) => f<T>('max', x, y)
134
- export const min = <T extends C>(x: X<T>, y: X) => f<T>('min', x, y)
135
- export const mix = <T extends C>(x: X<T>, y: X, a: X) => f<T>('mix', x, y, a)
136
- export const pow = <T extends C>(x: X<T>, y: X) => f<T>('pow', x, y)
137
- export const reflect = <T extends C>(I: X<T>, N: X) => f<T>('reflect', I, N)
138
- export const refract = <T extends C>(I: X<T>, N: X, eta: X) => f<T>('refract', I, N, eta)
136
+ // 1. Functions where first argument determines return type with unified parameter types
137
+ export const atan2 = <T extends C, U extends C>(x: X<T>, y: number | X<U>) => f<T>('atan2', x, y)
138
+ export const clamp = <T extends C, U extends C>(x: X<T>, min: number | X<U>, max: number | X<U>) =>
139
+ f<T>('clamp', x, min, max)
140
+ export const max = <T extends C, U extends C>(x: X<T>, y: number | X<U>) => f<T>('max', x, y)
141
+ export const min = <T extends C, U extends C>(x: X<T>, y: number | X<U>) => f<T>('min', x, y)
142
+ export const mix = <T extends C, U extends C>(x: X<T>, y: number | X<U>, a: number | Float | X<U>) =>
143
+ f<T>('mix', x, y, a)
144
+ export const pow = <T extends C, U extends C>(x: X<T>, y: number | X<U>) => f<T>('pow', x, y)
145
+ export const reflect = <T extends 'vec2' | 'vec3' | 'vec4', U extends C>(I: X<T>, N: number | X<U>) =>
146
+ f<T>('reflect', I, N)
147
+ export const refract = <T extends 'vec2' | 'vec3' | 'vec4', U extends C>(
148
+ I: X<T>,
149
+ N: number | X<U>,
150
+ eta: number | Float
151
+ ) => f<T>('refract', I, N, eta)
139
152
 
140
- // 2. Functions where not first argument determines return type
141
- export const smoothstep = <T extends C>(e0: X, e1: X, x: X<T>) => f<T>('smoothstep', e0, e1, x)
142
- export const step = <T extends C>(edge: X, x: X<T>) => f<T>('step', edge, x)
143
- export const mod = <T extends C>(x: NodeProxy<T>, y: X<T>) => x.sub(x.div(y).toFloat().floor().mul(y))
153
+ // 2. Functions where not first argument determines return type with unified parameter types
154
+ export const smoothstep = <T extends C, U extends C>(e0: number | X<U>, e1: number | X<U>, x: X<T>) =>
155
+ f<T>('smoothstep', e0, e1, x)
156
+ export const step = <T extends C, U extends C>(edge: number | X<U>, x: X<T>) => f<T>('step', edge, x)
157
+ export const mod = <T extends C, U extends C>(x: X<T>, y: number | X<U>) => {
158
+ return (x as any).sub((x as any).div(y).floor().mul(y)) as X<T>
159
+ }
package/src/node/scope.ts CHANGED
@@ -1,51 +1,69 @@
1
1
  import { getId } from './utils'
2
- import { conversion, node } from './node'
3
- import type { FnLayout, NodeProps, NodeProxy, X, Constants, Int } from './types'
2
+ import { conversion, create } from './create'
3
+ import type {
4
+ FnLayout,
5
+ FnType,
6
+ Constants as C,
7
+ Int,
8
+ NodeProps,
9
+ Struct,
10
+ StructFactory,
11
+ StructFields,
12
+ X,
13
+ Y,
14
+ } from './types'
4
15
 
5
- let scope: NodeProxy | null = null
6
- let define: NodeProxy | null = null
16
+ let scope: X | null = null
17
+ let define: X | null = null
7
18
 
8
- const addToScope = (x: NodeProxy) => {
19
+ export const addToScope = <T extends C>(x: X<T>) => {
9
20
  if (!scope) return
10
21
  if (!scope.props.children) scope.props.children = []
11
22
  scope.props.children.push(x)
12
- if (x.type !== 'return' || !define) return
13
- // define nodes
23
+ if (x.type !== 'return' || !define) return x
14
24
  const { props } = define
15
25
  if (!props.inferFrom) props.inferFrom = []
16
26
  props.inferFrom.push(x)
27
+ return x
17
28
  }
18
29
 
19
- export const toVar = <T extends Constants>(x: X<T>, id?: string): NodeProxy<T> => {
30
+ export function toVar<T extends StructFields>(x: Struct<T>, id?: string): Struct<T>
31
+ export function toVar<T extends C>(x: X<T>, id?: string): X<T> {
20
32
  if (!id) id = getId()
21
- const y = node<T>('variable', { id, inferFrom: [x] })
22
- const z = node('declare', null, x, y)
33
+ const y = create<T>('variable', { id, inferFrom: [x] })
34
+ const z = create<T>('declare', null, x as X, y)
23
35
  addToScope(z)
24
36
  return y
25
37
  }
26
38
 
27
- export const assign = <T extends Constants>(x: NodeProxy<T>, isScatter = false, y: X<T>): X<T> => {
28
- const z = node(isScatter ? 'scatter' : 'assign', null, x, y)
39
+ export const assign = <T extends C>(x: X<T>, isScatter = false, y: Y<T>): X<T> => {
40
+ const z = create(isScatter ? 'scatter' : 'assign', null, x, y)
29
41
  addToScope(z)
30
42
  return x
31
43
  }
32
44
 
33
- export const Return = <T extends Constants>(x: X<T>): NodeProxy<T> => {
34
- const y = node<T>('return', { inferFrom: [x] }, x)
35
- addToScope(y)
36
- return y
45
+ export const Return = <T extends C>(x: Y<T>): Y<T> => {
46
+ return addToScope(create<T>('return', { inferFrom: [x] }, x))
47
+ }
48
+
49
+ export const Break = (): Y => {
50
+ return addToScope(create('break'))
51
+ }
52
+
53
+ export const Continue = (): Y => {
54
+ return addToScope(create('continue'))
37
55
  }
38
56
 
39
- export const struct = <T extends Record<string, NodeProxy>>(fields: T, id = getId()) => {
40
- return (initialValues: T = {} as T, instanceId = getId()) => {
41
- const x = node('variable', { id: instanceId, inferFrom: [id] })
42
- const y = node('struct', { id, fields, initialValues }, x)
57
+ export const struct = <T extends StructFields>(fields: T, id = getId()): StructFactory<T> => {
58
+ return (initialValues: StructFields = {}, instanceId = getId()) => {
59
+ const x = create('variable', { id: instanceId, inferFrom: [id] })
60
+ const y = create('struct', { id, fields, initialValues }, x)
43
61
  addToScope(y)
44
- return x
62
+ return x as Struct<T>
45
63
  }
46
64
  }
47
65
 
48
- const scoped = (x: NodeProxy, fun: () => NodeProxy | void, y = define) => {
66
+ export const scoped = (x: X, fun: () => X | void, y = define) => {
49
67
  const [_scope, _define] = [scope, define]
50
68
  ;[scope, define] = [x, y]
51
69
  const z = fun()
@@ -53,20 +71,20 @@ const scoped = (x: NodeProxy, fun: () => NodeProxy | void, y = define) => {
53
71
  ;[scope, define] = [_scope, _define]
54
72
  }
55
73
 
56
- export const If = (x: NodeProxy, fun: () => void) => {
57
- const y = node('scope')
74
+ export const If = (x: Y, fun: () => void) => {
75
+ const y = create('scope')
58
76
  scoped(y, fun)
59
- const ifNode = node('if', null, x, y)
77
+ const ifNode = create('if', null, x, y)
60
78
  addToScope(ifNode)
61
79
  const ret = () => ({
62
80
  ElseIf: (_x: X, _fun: () => void) => {
63
- const _y = node('scope')
81
+ const _y = create('scope')
64
82
  scoped(_y, _fun)
65
83
  ifNode.props.children!.push(_x, _y)
66
84
  return ret()
67
85
  },
68
86
  Else: (_fun: () => void) => {
69
- const _x = node('scope')
87
+ const _x = create('scope')
70
88
  scoped(_x, _fun)
71
89
  ifNode.props.children!.push(_x)
72
90
  },
@@ -74,29 +92,28 @@ export const If = (x: NodeProxy, fun: () => void) => {
74
92
  return ret()
75
93
  }
76
94
 
77
- export const Loop = (x: NodeProxy, fun: (params: { i: Int }) => void) => {
78
- const y = node('scope')
95
+ export const Loop = (x: Y, fun: (params: { i: Int }) => void) => {
96
+ const y = create('scope')
79
97
  const id = getId()
80
- scoped(y, () => fun({ i: node<'int'>('variable', { id, inferFrom: [conversion('int', 0)] }) }))
81
- const ret = node('loop', { id }, x, y)
82
- addToScope(ret)
83
- return ret
98
+ scoped(y, () => fun({ i: create<'int'>('variable', { id, inferFrom: [conversion('int', 0)] }) }))
99
+ const ret = create('loop', { id }, x, y)
100
+ return addToScope(ret)
84
101
  }
85
102
 
86
- export const Switch = (x: NodeProxy) => {
87
- const switchNode = node('switch', null, x)
103
+ export const Switch = (x: Y) => {
104
+ const switchNode = create('switch', null, x)
88
105
  addToScope(switchNode)
89
106
  const ret = () => ({
90
107
  Case: (...values: X[]) => {
91
108
  return (fun: () => void) => {
92
- const y = node('scope')
109
+ const y = create('scope')
93
110
  scoped(y, fun)
94
111
  for (const _x of values) switchNode.props.children!.push(_x, y)
95
112
  return ret()
96
113
  }
97
114
  },
98
115
  Default: (fun: () => void) => {
99
- const scope = node('scope')
116
+ const scope = create('scope')
100
117
  scoped(scope, fun)
101
118
  switchNode.props.children!.push(scope)
102
119
  },
@@ -104,32 +121,30 @@ export const Switch = (x: NodeProxy) => {
104
121
  return ret()
105
122
  }
106
123
 
107
- export const Fn = <ReturnType extends Constants, Args extends Constants[]>(
108
- fun: (paramVars: NodeProxy[]) => NodeProxy<ReturnType> | void,
109
- defaultId = getId()
110
- ) => {
124
+ export function Fn<T extends X | Struct | void, Args extends any[]>(fun: (args: Args) => T, defaultId = getId()) {
111
125
  let layout: FnLayout
112
- const ret = (...args: X<Args[number]>[]): NodeProxy<ReturnType> => {
126
+ const ret = (...args: any[]) => {
113
127
  const id = layout?.name || defaultId
114
- const x = node('scope')
115
- const paramVars: NodeProxy[] = []
128
+ const x = create('scope')
129
+ const paramVars: X[] = []
116
130
  const paramDefs: NodeProps[] = []
117
- if (layout?.inputs)
131
+ if (layout?.inputs) {
118
132
  for (const input of layout.inputs) {
119
133
  paramDefs.push({ id: input.name, inferFrom: [conversion(input.type)] })
120
134
  }
121
- else
135
+ } else {
122
136
  for (let i = 0; i < args.length; i++) {
123
137
  paramDefs.push({ id: `p${i}`, inferFrom: [args[i]] })
124
138
  }
125
- for (const props of paramDefs) paramVars.push(node('variable', props))
126
- const y = node<ReturnType>('define', { id, layout }, x, ...args)
127
- scoped(x, () => fun(paramVars), y)
139
+ }
140
+ for (const props of paramDefs) paramVars.push(create('variable', props))
141
+ const y = create('define', { id, layout }, x, ...args)
142
+ scoped(x, () => fun(paramVars as Args) as any, y)
128
143
  return y
129
144
  }
130
145
  ret.setLayout = (_layout: FnLayout) => {
131
146
  layout = _layout
132
147
  return ret
133
148
  }
134
- return ret
149
+ return ret as unknown as Args extends readonly unknown[] ? FnType<T, Args> : never
135
150
  }