glre 0.45.0 → 0.46.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 (52) hide show
  1. package/README.md +4 -26
  2. package/dist/addons.d.ts +35 -50
  3. package/dist/index.cjs +6 -6
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +37 -90
  6. package/dist/index.js +6 -6
  7. package/dist/index.js.map +1 -1
  8. package/dist/native.cjs +1 -1
  9. package/dist/native.cjs.map +1 -1
  10. package/dist/native.d.ts +45 -93
  11. package/dist/native.js +1 -1
  12. package/dist/native.js.map +1 -1
  13. package/dist/node.cjs +15 -15
  14. package/dist/node.cjs.map +1 -1
  15. package/dist/node.d.ts +35 -50
  16. package/dist/node.js +14 -14
  17. package/dist/node.js.map +1 -1
  18. package/dist/react.cjs +1 -1
  19. package/dist/react.cjs.map +1 -1
  20. package/dist/react.d.ts +37 -91
  21. package/dist/react.js +1 -1
  22. package/dist/react.js.map +1 -1
  23. package/dist/solid.cjs +1 -1
  24. package/dist/solid.cjs.map +1 -1
  25. package/dist/solid.d.ts +37 -91
  26. package/dist/solid.js +1 -1
  27. package/dist/solid.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/{utils/helpers.ts → helpers.ts} +10 -32
  30. package/src/index.ts +45 -42
  31. package/src/native.ts +6 -7
  32. package/src/node/build.ts +3 -19
  33. package/src/node/create.ts +2 -4
  34. package/src/node/index.ts +8 -20
  35. package/src/node/types.ts +2 -0
  36. package/src/node/utils/index.ts +1 -1
  37. package/src/node/utils/infer.ts +4 -12
  38. package/src/node/utils/parse.ts +18 -34
  39. package/src/node/utils/utils.ts +3 -3
  40. package/src/react.ts +9 -12
  41. package/src/solid.ts +3 -10
  42. package/src/types.ts +30 -22
  43. package/src/webgl/compute.ts +56 -0
  44. package/src/webgl/graphic.ts +65 -0
  45. package/src/webgl/index.ts +21 -0
  46. package/src/{utils/program.ts → webgl/utils.ts} +30 -8
  47. package/src/webgpu/compute.ts +39 -0
  48. package/src/webgpu/graphic.ts +89 -0
  49. package/src/webgpu/index.ts +42 -0
  50. package/src/{utils/pipeline.ts → webgpu/utils.ts} +75 -78
  51. package/src/utils/webgl.ts +0 -135
  52. package/src/utils/webgpu.ts +0 -178
@@ -1,135 +0,0 @@
1
- import { nested as cached } from 'reev'
2
- import { is, getStride, GLSL_VS, GLSL_FS, loadingTexture } from './helpers'
3
- import { createArrayBuffer, cleanStorage, createAttachment, createProgram, createStorage, createTexture, setArrayBuffer, storageSize, updateAttrib, updateInstance, updateUniform } from './program'
4
- import type { GL } from '../types'
5
-
6
- const computeProgram = (gl: GL, c: WebGL2RenderingContext) => {
7
- if (!gl.cs) return null // ignore if no compute shader
8
- c.getExtension('EXT_color_buffer_float')
9
-
10
- let activeUnit = 0 // for texture units
11
- let currentNum = 0 // for storage buffers
12
-
13
- const units = cached(() => activeUnit++)
14
- const cs = is.str(gl.cs) ? gl.cs : gl.cs!.compute({ isWebGL: true, gl, units })
15
- const pg = createProgram(c, cs, GLSL_VS, gl)!
16
- const size = storageSize(gl.particleCount)
17
-
18
- const uniforms = cached((key) => c.getUniformLocation(pg, key)!)
19
- const storages = cached((key) => {
20
- const array = new Float32Array(size.x * size.y * 4) // RGBA texture data
21
- const ping = { texture: c.createTexture(), buffer: c.createFramebuffer() }
22
- const pong = { texture: c.createTexture(), buffer: c.createFramebuffer() }
23
- return { ping, pong, array, loc: uniforms(key), unit: units(key) }
24
- })
25
-
26
- const _uniform = (key: string, value: number | number[]) => {
27
- c.useProgram(pg)
28
- updateUniform(c, uniforms(key), value)
29
- }
30
-
31
- const _storage = (key: string, value: number[]) => {
32
- const { ping, pong, unit, array } = storages(key)
33
- createStorage(c, value, size.x, size.y, ping, pong, unit, array)
34
- }
35
-
36
- const clean = () => {
37
- c.deleteProgram(pg)
38
- cleanStorage(c, storages.map.values())
39
- }
40
-
41
- const render = () => {
42
- c.useProgram(pg)
43
- const attachments = storages.map.values().map(({ ping, pong, loc, unit }, index) => {
44
- const [i, o] = currentNum % 2 ? [ping, pong] : [pong, ping]
45
- return createAttachment(c, i, o, loc, unit, index)
46
- })
47
- c.drawBuffers(attachments)
48
- c.drawArrays(c.TRIANGLES, 0, 3)
49
- c.bindFramebuffer(c.FRAMEBUFFER, null)
50
- currentNum++
51
- }
52
-
53
- return { render, clean, _uniform, _storage, storages }
54
- }
55
-
56
- export const webgl = async (gl: GL) => {
57
- const config = { isWebGL: true, gl }
58
- const c = (gl.webgl.context = gl.el!.getContext('webgl2')!)
59
- const cp = computeProgram(gl, c)
60
- const fs = gl.fs ? (is.str(gl.fs) ? gl.fs : gl.fs!.fragment(config)) : GLSL_FS
61
- const vs = gl.vs ? (is.str(gl.vs) ? gl.vs : gl.vs!.vertex(config)) : GLSL_VS
62
- const pg = (gl.webgl.program = createProgram(c, fs, vs, gl)!)
63
- c.useProgram(pg)
64
-
65
- let activeUnit = 0 // for texture units
66
-
67
- const units = cached(() => activeUnit++)
68
- const uniforms = (gl.webgl.uniforms = cached((key) => c.getUniformLocation(pg, key)))
69
-
70
- const attribs = cached((key, value: number[], isInstance = false) => {
71
- const stride = getStride(value.length, isInstance ? gl.instanceCount : gl.count, gl.error)
72
- const location = c.getAttribLocation(pg, key)
73
- const { array, buffer } = createArrayBuffer(c, value)
74
- return { array, buffer, location, stride }
75
- })
76
-
77
- const _attribute = (key = '', value: number[]) => {
78
- const { array, buffer, location, stride } = attribs(key, value)
79
- setArrayBuffer(c, array, buffer, value)
80
- updateAttrib(c, location, stride, buffer)
81
- }
82
-
83
- const _instance = (key: string, value: number[]) => {
84
- const { array, buffer, location, stride } = attribs(key, value, true)
85
- setArrayBuffer(c, array, buffer, value)
86
- updateInstance(c, location, stride, buffer)
87
- }
88
-
89
- const _uniform = (key: string, value: number | number[]) => {
90
- c.useProgram(pg)
91
- updateUniform(c, uniforms(key)!, value)
92
- cp?._uniform(key, value)
93
- }
94
-
95
- const _texture = (key: string, src: string) => {
96
- gl.loading++
97
- c.useProgram(pg)
98
- loadingTexture(src, (source, isVideo) => {
99
- const unit = units(key)
100
- const loop = createTexture(c, source, uniforms(key)!, unit, isVideo)
101
- if (loop) gl({ loop })
102
- gl.loading--
103
- })
104
- }
105
-
106
- const clean = () => {
107
- cp?.clean()
108
- c.deleteProgram(pg)
109
- c.getExtension('WEBGL_lose_context')?.loseContext()
110
- }
111
-
112
- const render = () => {
113
- cp?.render()
114
- c.useProgram(pg)
115
- c.viewport(0, 0, ...gl.size)
116
- if (gl.instanceCount > 1) {
117
- c.drawArraysInstanced(c.TRIANGLES, 0, gl.count, gl.instanceCount)
118
- } else c.drawArrays(c.TRIANGLES, 0, gl.count)
119
- c.bindFramebuffer(c.FRAMEBUFFER, null)
120
- }
121
-
122
- if (gl.isDepth) {
123
- c.enable(c.DEPTH_TEST)
124
- c.depthFunc(c.LEQUAL)
125
- c.enable(c.CULL_FACE)
126
- c.cullFace(c.BACK)
127
- }
128
-
129
- if (gl.wireframe) {
130
- const ext = c.getExtension('WEBGL_polygon_mode')
131
- ext.polygonModeWEBGL(c.FRONT_AND_BACK, ext.LINE_WEBGL)
132
- }
133
-
134
- return { render, clean, _attribute, _instance, _uniform, _texture, _storage: cp?._storage }
135
- }
@@ -1,178 +0,0 @@
1
- import { nested as cached } from 'reev'
2
- import { is, getStride, WGSL_FS, WGSL_VS, loadingTexture } from './helpers'
3
- import {
4
- createArrayBuffer,
5
- createBindGroup,
6
- createBindings,
7
- createComputePipeline,
8
- createDepthTexture,
9
- createDescriptor,
10
- createDevice,
11
- createPipeline,
12
- createTextureSampler,
13
- createVertexBuffers,
14
- workgroupCount,
15
- } from './pipeline'
16
- import type { GL, WebGPUState } from '../types'
17
-
18
- const computeProgram = (gl: GL, device: GPUDevice, bindings: any) => {
19
- let flush = (_pass: GPUComputePassEncoder) => {}
20
-
21
- const storages = cached((_key, value: number[] | Float32Array) => {
22
- const { array, buffer } = createArrayBuffer(device, value, 'storage')
23
- const { binding, group } = bindings.storage()
24
- return { array, buffer, binding, group }
25
- })
26
-
27
- const _storage = (key: string, value: number[] | Float32Array) => {
28
- const { array, buffer } = storages(key, value)
29
- device.queue.writeBuffer(buffer, 0, array as any)
30
- }
31
-
32
- const update = (bindGroups: GPUBindGroup[], bindGroupLayouts: GPUBindGroupLayout[], comp: string) => {
33
- const pipeline = createComputePipeline(device, bindGroupLayouts, comp!)
34
- flush = (pass) => {
35
- pass.setPipeline(pipeline)
36
- bindGroups.forEach((v, i) => pass.setBindGroup(i, v))
37
- const { x, y, z } = workgroupCount(gl.particleCount)
38
- pass.dispatchWorkgroups(x, y, z)
39
- pass.end()
40
- }
41
- }
42
-
43
- const render = (pass: GPUComputePassEncoder) => {
44
- flush(pass)
45
- }
46
-
47
- const clean = () => {
48
- for (const { buffer } of storages.map.values()) buffer.destroy()
49
- }
50
-
51
- return { storages, _storage, update, render, clean }
52
- }
53
-
54
- export const webgpu = async (gl: GL) => {
55
- const context = gl.el!.getContext('webgpu') as GPUCanvasContext
56
- const { device, format } = await createDevice(context, gl.error)
57
- const bindings = createBindings()
58
- const cp = computeProgram(gl, device, bindings)
59
- let frag: string
60
- let comp: string
61
- let vert: string
62
- let flush = (_pass: GPURenderPassEncoder) => {}
63
- let needsUpdate = true
64
- let depthTexture: GPUTexture
65
-
66
- const attribs = cached((_key, value: number[], isInstance = false) => {
67
- needsUpdate = true
68
- const stride = getStride(value.length, isInstance ? gl.instanceCount : gl.count)
69
- const { location } = bindings.attrib()
70
- const { array, buffer } = createArrayBuffer(device, value, 'attrib')
71
- return { array, buffer, location, stride, isInstance }
72
- })
73
-
74
- const uniforms = cached((_key, value: number[]) => {
75
- needsUpdate = true
76
- const { binding, group } = bindings.uniform()
77
- const { array, buffer } = createArrayBuffer(device, value, 'uniform')
78
- return { array, buffer, binding, group }
79
- })
80
-
81
- const textures = cached((_key, width = 0, height = 0) => {
82
- needsUpdate = true
83
- const { binding, group } = bindings.texture()
84
- const { texture, sampler } = createTextureSampler(device, width, height)
85
- return { texture, sampler, binding, group, view: texture.createView() }
86
- })
87
-
88
- const _attribute = (key = '', value: number[]) => {
89
- const { array, buffer } = attribs(key, value)
90
- array.set(value)
91
- device.queue.writeBuffer(buffer, 0, array as any)
92
- }
93
-
94
- const _instance = (key: string, value: number[]) => {
95
- const { array, buffer } = attribs(key, value, true)
96
- array.set(value)
97
- device.queue.writeBuffer(buffer, 0, array as any)
98
- }
99
-
100
- const _uniform = (key: string, value: number | number[]) => {
101
- if (is.num(value)) value = [value]
102
- const { array, buffer } = uniforms(key, value)
103
- array.set(value)
104
- device.queue.writeBuffer(buffer, 0, array as any)
105
- }
106
-
107
- const _texture = (key: string, src: string) => {
108
- gl.loading++
109
- loadingTexture(src, (source, isVideo) => {
110
- const [width, height] = isVideo
111
- ? [source.videoWidth, source.videoHeight]
112
- : [source.width, source.height]
113
- const { texture } = textures(key, width, height)
114
- const loop = () => {
115
- device.queue.copyExternalImageToTexture({ source }, { texture }, { width, height })
116
- }
117
- loop()
118
- if (isVideo) gl({ loop })
119
- gl.loading--
120
- })
121
- }
122
-
123
- const update = () => {
124
- const { vertexBuffers, bufferLayouts } = createVertexBuffers(attribs.map.values())
125
- const { bindGroups, bindGroupLayouts } = createBindGroup(
126
- device,
127
- uniforms.map.values(),
128
- textures.map.values(),
129
- cp.storages.map.values()
130
- )
131
- const pipeline = createPipeline(device, format, bufferLayouts, bindGroupLayouts, vert, frag)
132
- flush = (pass) => {
133
- pass.setPipeline(pipeline)
134
- bindGroups.forEach((v, i) => pass.setBindGroup(i, v))
135
- vertexBuffers.forEach((v, i) => pass.setVertexBuffer(i, v))
136
- pass.draw(gl.count, gl.instanceCount, 0, 0)
137
- pass.end()
138
- }
139
- if (gl.cs) cp.update(bindGroups, bindGroupLayouts, comp)
140
- }
141
-
142
- const render = () => {
143
- if (!frag || !vert) {
144
- const config = { isWebGL: false, gl }
145
- frag = gl.fs ? (is.str(gl.fs) ? gl.fs : gl.fs.fragment(config)) : WGSL_FS
146
- vert = gl.vs ? (is.str(gl.vs) ? gl.vs : gl.vs.vertex(config)) : WGSL_VS
147
- comp = gl.cs ? (is.str(gl.cs) ? gl.cs : gl.cs.compute(config)) : ''
148
- }
149
- if (gl.loading) return // MEMO: loading after build node
150
- if (needsUpdate) update()
151
- needsUpdate = false
152
- const encoder = device.createCommandEncoder()
153
- if (gl.cs) cp.render(encoder.beginComputePass())
154
- flush(encoder.beginRenderPass(createDescriptor(context, depthTexture)))
155
- device.queue.submit([encoder.finish()])
156
- }
157
-
158
- const resize = () => {
159
- const canvas = gl.el as HTMLCanvasElement
160
- depthTexture?.destroy()
161
- depthTexture = createDepthTexture(device, canvas.width, canvas.height)
162
- }
163
-
164
- const clean = () => {
165
- device.destroy()
166
- depthTexture?.destroy()
167
- for (const { texture } of textures.map.values()) texture.destroy()
168
- for (const { buffer } of uniforms.map.values()) buffer.destroy()
169
- for (const { buffer } of attribs.map.values()) buffer.destroy()
170
- cp.clean()
171
- }
172
-
173
- resize()
174
-
175
- const webgpu = { device, uniforms, textures, attribs, storages: cp.storages } as WebGPUState
176
-
177
- return { webgpu, render, resize, clean, _attribute, _instance, _uniform, _texture, _storage: cp._storage }
178
- }