glre 0.25.0 → 0.26.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glre",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "author": "tseijp",
5
5
  "license": "MIT",
6
6
  "private": false,
package/src/index.ts CHANGED
@@ -40,7 +40,7 @@ export const createGL = (props?: Partial<GL>) => {
40
40
  isGL: true,
41
41
  size: [0, 0],
42
42
  mouse: [0, 0],
43
- count: 3,
43
+ count: 6,
44
44
  webgl: {},
45
45
  webgpu: {},
46
46
  }) as EventState<GL>
package/src/types.ts CHANGED
@@ -29,12 +29,10 @@ export interface WebGLState {
29
29
  }
30
30
 
31
31
  export interface WebGPUState {
32
- uniforms: any
33
- textures: any
34
32
  device: GPUDevice
35
33
  context: GPUContext
36
- groups: any[]
37
34
  pipeline: GPUPipeline
35
+ groups: any[]
38
36
  resources: any[]
39
37
  loadingImg: number
40
38
  needsUpdate: boolean
@@ -33,19 +33,19 @@ export const createDevive = async (c: GPUContext) => {
33
33
  export const createPipeline = (
34
34
  device: GPUDevice,
35
35
  format: string,
36
- buffers: any[],
37
- layouts: any[],
36
+ bufferLayouts: any[],
37
+ bindGroupLayouts: any[],
38
38
  vs: string | X = defaultVertexWGSL,
39
39
  fs: string | X = defaultFragmentWGSL
40
40
  ) => {
41
41
  if (is.obj(fs)) fs = wgsl(fs)
42
42
  if (is.obj(vs)) vs = wgsl(vs)
43
- const layout = device.createPipelineLayout({ bindGroupLayouts: layouts })
43
+ const layout = device.createPipelineLayout({ bindGroupLayouts })
44
44
  return device.createRenderPipeline({
45
45
  vertex: {
46
46
  module: device.createShaderModule({ code: vs.trim() }),
47
47
  entryPoint: 'main',
48
- buffers,
48
+ buffers: bufferLayouts,
49
49
  },
50
50
  fragment: {
51
51
  module: device.createShaderModule({ code: fs.trim() }),
@@ -73,7 +73,7 @@ export const createBindGroup = (device: GPUDevice, resources: any[]) => {
73
73
  })
74
74
  const layout = device.createBindGroupLayout({ entries: entries0 })
75
75
  const bindGroup = device.createBindGroup({ layout, entries: entries1 })
76
- return [layout, bindGroup]
76
+ return { layout, bindGroup }
77
77
  }
78
78
 
79
79
  export const createDescriptor = (c: GPUContext) => {
@@ -91,6 +91,12 @@ export const createDescriptor = (c: GPUContext) => {
91
91
 
92
92
  export const alignTo256 = (size: number) => Math.ceil(size / 256) * 256
93
93
 
94
+ export const createVertexBuffer = (device: GPUDevice, value: number[]) => {
95
+ const array = new Float32Array(value)
96
+ const buffer = device.createBuffer({ size: array.byteLength, usage: 40 }) // 40 === // GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
97
+ return { array, buffer }
98
+ }
99
+
94
100
  export const createUniformBuffer = (device: GPUDevice, value: number[]) => {
95
101
  const array = new Float32Array(value)
96
102
  const size = alignTo256(array.byteLength)
@@ -101,12 +107,30 @@ export const createUniformBuffer = (device: GPUDevice, value: number[]) => {
101
107
  export const createTextureSampler = (device: GPUDevice, width = 1280, height = 800) => {
102
108
  const texture = device.createTexture({ size: [width, height], format: 'rgba8unorm', usage: 22 })
103
109
  const sampler = device.createSampler({ magFilter: 'linear', minFilter: 'linear' })
104
- return [texture, sampler] as const
110
+ return { texture, sampler }
111
+ }
112
+
113
+ const getVertexStride = (dataLength: number, vertexCount: number) => {
114
+ return dataLength / vertexCount
115
+ }
116
+
117
+ const getVertexFormat = (stride: number) => {
118
+ if (stride === 2) return 'float32x2'
119
+ if (stride === 3) return 'float32x3'
120
+ if (stride === 4) return 'float32x4'
121
+ return 'float32'
105
122
  }
106
123
 
107
- // export const createVertexBuffer = (device: GPUDevice, value: number[]) => {
108
- // const array = new Float32Array(value)
109
- // const buffer = device.createBuffer({ size: array.byteLength, usage: 0x20 | 0x4 })
110
- // device.queue.writeBuffer(buffer, 0, array)
111
- // return buffer as Buffer
112
- // }
124
+ export const createBufferLayout = (shaderLocation: number, dataLength: number, count = 6) => {
125
+ const stride = getVertexStride(dataLength, count)
126
+ return {
127
+ arrayStride: stride * 4,
128
+ attributes: [
129
+ {
130
+ shaderLocation,
131
+ offset: 0,
132
+ format: getVertexFormat(stride),
133
+ },
134
+ ],
135
+ }
136
+ }
package/src/webgl.ts CHANGED
@@ -10,10 +10,9 @@ export const webgl = async (gl: Partial<GL>) => {
10
10
  c.useProgram(pg)
11
11
 
12
12
  let _activeUnit = 0
13
- const activeUnits = cached(() => _activeUnit++)
14
-
15
- const uniformLocations = cached((key) => c.getUniformLocation(pg, key))
16
- const attribLocations = cached((key) => c.getAttribLocation(pg, key))
13
+ const uniforms = cached((key) => c.getUniformLocation(pg, key))
14
+ const attribs = cached((key) => c.getAttribLocation(pg, key))
15
+ const units = cached(() => _activeUnit++)
17
16
 
18
17
  const clean = () => c.deleteProgram(pg)
19
18
 
@@ -24,7 +23,7 @@ export const webgl = async (gl: Partial<GL>) => {
24
23
  }
25
24
 
26
25
  const _attribute = (key = '', value: number[], iboValue: number[]) => {
27
- const loc = attribLocations(key, true)
26
+ const loc = attribs(key, true)
28
27
  const vbo = createVbo(c, value)
29
28
  const ibo = createIbo(c, iboValue)
30
29
  const str = getStride(gl.count!, value, iboValue)
@@ -32,7 +31,7 @@ export const webgl = async (gl: Partial<GL>) => {
32
31
  }
33
32
 
34
33
  const _uniform = (key: string, value: number | number[]) => {
35
- const loc = uniformLocations(key)
34
+ const loc = uniforms(key)
36
35
  if (is.num(value)) return c.uniform1f(loc, value)
37
36
  let l = value.length
38
37
  if (l <= 4) return c[`uniform${l as 2}fv`](loc, value)
@@ -40,12 +39,12 @@ export const webgl = async (gl: Partial<GL>) => {
40
39
  c[`uniformMatrix${l as 2}fv`](loc, false, value)
41
40
  }
42
41
 
43
- const _texture = (alt: string, src: string) => {
42
+ const _texture = (key: string, src: string) => {
44
43
  const image = new Image()
45
- Object.assign(image, { src, alt, crossOrigin: 'anonymous' })
44
+ Object.assign(image, { src, crossOrigin: 'anonymous' })
46
45
  image.decode().then(() => {
47
- const loc = uniformLocations(image.alt)
48
- const unit = activeUnits(image.alt)
46
+ const loc = uniforms(key)
47
+ const unit = units(key)
49
48
  createTexture(c, image, loc, unit)
50
49
  })
51
50
  }
package/src/webgpu.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { nested as cached } from 'reev'
1
2
  import { is } from './utils/helpers'
2
3
  import {
3
4
  createDevive,
@@ -6,6 +7,8 @@ import {
6
7
  createUniformBuffer,
7
8
  createBindGroup,
8
9
  createTextureSampler,
10
+ createVertexBuffer,
11
+ createBufferLayout,
9
12
  } from './utils/pipeline'
10
13
  import type { GL, WebGPUState } from './types'
11
14
 
@@ -15,38 +18,47 @@ export const webgpu = async (gl: Partial<GL>) => {
15
18
  const state = {
16
19
  device,
17
20
  context: c,
18
- uniforms: {},
19
- textures: {},
20
21
  resources: [[], []],
21
22
  loadingImg: 0,
22
23
  needsUpdate: true,
23
24
  } as WebGPUState
24
25
 
25
- const initUniform = (value: number[]) => {
26
+ const bindGroups = [] as any[]
27
+ const vertexBuffers = [] as any[]
28
+ const bufferLayouts = [] as any[]
29
+
30
+ const attributes = cached((_, value: number[]) => {
31
+ const { array, buffer } = createVertexBuffer(device, value)
32
+ vertexBuffers.push(buffer)
33
+ bufferLayouts.push(createBufferLayout(bufferLayouts.length, array.length, gl.count))
34
+ state.needsUpdate = true
35
+ return { array, buffer }
36
+ })
37
+
38
+ const uniforms = cached((_, value: number[]) => {
26
39
  const { array, buffer } = createUniformBuffer(device, value)
27
40
  state.resources[0].push({ buffer })
28
41
  state.needsUpdate = true
29
42
  return { array, buffer }
30
- }
43
+ })
31
44
 
32
- const initTexutre = (source: HTMLImageElement) => {
33
- const { width, height } = source
34
- const [texture, sampler] = createTextureSampler(device, width, height)
45
+ const textures = cached((_, { width, height }: HTMLImageElement) => {
46
+ const { texture, sampler } = createTextureSampler(device, width, height)
35
47
  state.resources[1].push(sampler, texture.createView())
36
48
  state.needsUpdate = true
37
49
  return { texture, width, height }
38
- }
50
+ })
39
51
 
40
52
  const update = () => {
41
- const layouts = [] as any
42
- state.groups = []
53
+ const bindGroupLayouts = [] as any
54
+ bindGroups.length = 0
43
55
  state.resources.forEach((resource) => {
44
56
  if (!resource.length) return
45
- const [layout, group] = createBindGroup(device, resource)
46
- layouts.push(layout)
47
- state.groups.push(group)
57
+ const { layout, bindGroup } = createBindGroup(device, resource)
58
+ bindGroupLayouts.push(layout)
59
+ bindGroups.push(bindGroup)
48
60
  })
49
- state.pipeline = createPipeline(device, format, [], layouts, gl.vs, gl.fs)
61
+ state.pipeline = createPipeline(device, format, bufferLayouts, bindGroupLayouts, gl.vs, gl.fs)
50
62
  }
51
63
 
52
64
  const render = () => {
@@ -56,7 +68,8 @@ export const webgpu = async (gl: Partial<GL>) => {
56
68
  const encoder = device.createCommandEncoder()
57
69
  const pass = encoder.beginRenderPass(createDescriptor(c))
58
70
  pass.setPipeline(state.pipeline)
59
- state.groups.forEach((v, i) => pass.setBindGroup(i, v))
71
+ bindGroups.forEach((v, i) => pass.setBindGroup(i, v))
72
+ vertexBuffers.forEach((v, i) => pass.setVertexBuffer(i, v))
60
73
  pass.draw(gl.count, 1, 0, 0)
61
74
  pass.end()
62
75
  device.queue.submit([encoder.finish()])
@@ -65,14 +78,13 @@ export const webgpu = async (gl: Partial<GL>) => {
65
78
  const clean = () => {}
66
79
 
67
80
  const _attribute = (key = '', value: number[]) => {
68
- // @TODO FIX
69
- // vertexBuffers(key, value)
81
+ const { array, buffer } = attributes(key, value)
82
+ device.queue.writeBuffer(buffer, 0, array)
70
83
  }
71
84
 
72
85
  const _uniform = (key: string, value: number | number[]) => {
73
86
  if (is.num(value)) value = [value]
74
- if (!state.uniforms[key]) state.uniforms[key] = initUniform(value)
75
- const { array, buffer } = state.uniforms[key]
87
+ const { array, buffer } = uniforms(key, value)
76
88
  array.set(value)
77
89
  device.queue.writeBuffer(buffer, 0, array)
78
90
  }
@@ -81,8 +93,7 @@ export const webgpu = async (gl: Partial<GL>) => {
81
93
  state.loadingImg++
82
94
  const source = Object.assign(new Image(), { src, crossOrigin: 'anonymous' })
83
95
  source.decode().then(() => {
84
- if (!state.textures[key]) state.textures[key] = initTexutre(source)
85
- const { texture, width, height } = state.textures[key]
96
+ const { texture, width, height } = textures(key, source)
86
97
  device.queue.copyExternalImageToTexture({ source }, { texture }, { width, height })
87
98
  state.loadingImg--
88
99
  })