glre 0.23.0 → 0.24.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/README.md +11 -13
- package/dist/index.d.ts +5 -18
- package/dist/index.js +20 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -12
- package/dist/index.mjs.map +1 -1
- package/dist/native.d.ts +1 -1
- package/dist/native.js +20 -12
- package/dist/native.js.map +1 -1
- package/dist/native.mjs +19 -11
- package/dist/native.mjs.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +20 -12
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +19 -11
- package/dist/react.mjs.map +1 -1
- package/dist/solid.d.ts +1 -1
- package/dist/solid.js +20 -12
- package/dist/solid.js.map +1 -1
- package/dist/solid.mjs +19 -11
- package/dist/solid.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +9 -12
- package/src/node/index.ts +2 -2
- package/src/types.ts +1 -0
- package/src/utils/pipeline.ts +72 -76
- package/src/webgl.ts +0 -1
- package/src/webgpu.ts +42 -10
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -29,9 +29,7 @@ export const isWebGPUSupported = () => {
|
|
|
29
29
|
return 'gpu' in navigator
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
let iTime = performance.now()
|
|
33
|
-
iPrevTime = 0,
|
|
34
|
-
iDeltaTime = 0
|
|
32
|
+
let iTime = performance.now()
|
|
35
33
|
|
|
36
34
|
export const createGL = (props?: Partial<GL>) => {
|
|
37
35
|
const gl = event<Partial<GL>>({
|
|
@@ -50,8 +48,9 @@ export const createGL = (props?: Partial<GL>) => {
|
|
|
50
48
|
gl.frame = createFrame()
|
|
51
49
|
|
|
52
50
|
gl.attribute = durable((k, v, i) => gl.queue(() => gl._attribute?.(k, v, i)))
|
|
53
|
-
gl.uniform = durable((k, v, i) => gl.queue(() => gl._uniform?.(k, v, i)))
|
|
54
51
|
gl.texture = durable((k, v) => gl.queue(() => gl._texture?.(k, v)))
|
|
52
|
+
gl.uniform = durable((k, v, i) => gl.queue(() => gl._uniform?.(k, v, i)))
|
|
53
|
+
gl.uniform({ iResolution: gl.size, iMouse: [0, 0], iTime: 0 }) // default uniform
|
|
55
54
|
|
|
56
55
|
gl('mount', async () => {
|
|
57
56
|
if (!isWebGPUSupported()) gl.isWebGL = true
|
|
@@ -61,6 +60,7 @@ export const createGL = (props?: Partial<GL>) => {
|
|
|
61
60
|
gl.resize()
|
|
62
61
|
gl.frame(() => {
|
|
63
62
|
gl.loop()
|
|
63
|
+
gl.queue.flush()
|
|
64
64
|
gl.render()
|
|
65
65
|
return gl.isLoop
|
|
66
66
|
})
|
|
@@ -77,14 +77,6 @@ export const createGL = (props?: Partial<GL>) => {
|
|
|
77
77
|
gl.el.removeEventListener('mousemove', gl.mousemove)
|
|
78
78
|
})
|
|
79
79
|
|
|
80
|
-
gl('loop', () => {
|
|
81
|
-
iPrevTime = iTime
|
|
82
|
-
iTime = performance.now() / 1000
|
|
83
|
-
iDeltaTime = iTime - iPrevTime
|
|
84
|
-
gl.uniform({ iPrevTime, iTime, iDeltaTime })
|
|
85
|
-
// if (gl.fragmentNode) updateUniforms({ time: iTime }) // @TODO FIX
|
|
86
|
-
})
|
|
87
|
-
|
|
88
80
|
gl('resize', () => {
|
|
89
81
|
const w = gl.width || window.innerWidth
|
|
90
82
|
const h = gl.height || window.innerHeight
|
|
@@ -101,6 +93,11 @@ export const createGL = (props?: Partial<GL>) => {
|
|
|
101
93
|
gl.uniform('iMouse', gl.mouse)
|
|
102
94
|
})
|
|
103
95
|
|
|
96
|
+
gl('loop', () => {
|
|
97
|
+
iTime = performance.now() / 1000
|
|
98
|
+
gl.uniform('iTime', iTime)
|
|
99
|
+
})
|
|
100
|
+
|
|
104
101
|
return gl(props)
|
|
105
102
|
}
|
|
106
103
|
|
package/src/node/index.ts
CHANGED
|
@@ -43,8 +43,8 @@ export const If = (condition: X, callback: () => void): ConditionalNode => {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// 組み込み変数
|
|
46
|
-
export const
|
|
47
|
-
export const
|
|
46
|
+
export const fragCoord = node('vec4', undefined)
|
|
47
|
+
export const position = node('vec4', undefined)
|
|
48
48
|
export const iTime = uniform(0.0)
|
|
49
49
|
export const iResolution = uniform([1920, 1080])
|
|
50
50
|
export const iMouse = uniform([0, 0])
|
package/src/types.ts
CHANGED
|
@@ -6,6 +6,7 @@ export type GPUContext = any // GPUCanvasContext https://developer.mozilla.org/e
|
|
|
6
6
|
export type GPUDevice = any //
|
|
7
7
|
export type GPUBuffer = any //
|
|
8
8
|
export type GPUPipeline = any //
|
|
9
|
+
export type GPUBindGroup = any
|
|
9
10
|
export type Uniform = number | number[]
|
|
10
11
|
export type Attribute = number[]
|
|
11
12
|
export type Attributes = Record<string, Attribute>
|
package/src/utils/pipeline.ts
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
import { GPUContext, GPUDevice, GPUPipeline } from '../types'
|
|
2
2
|
|
|
3
|
-
export const initWebGPUDevice = async (el: HTMLCanvasElement) => {
|
|
4
|
-
const gpu = (navigator as any).gpu
|
|
5
|
-
if (!gpu) return null
|
|
6
|
-
const adapter = await gpu.requestAdapter()
|
|
7
|
-
if (!adapter) return null
|
|
8
|
-
const device = await adapter.requestDevice()
|
|
9
|
-
const context = el.getContext('webgpu') as GPUContext
|
|
10
|
-
if (!context) return null
|
|
11
|
-
const format = gpu.getPreferredCanvasFormat()
|
|
12
|
-
context.configure({ device, format })
|
|
13
|
-
return { device, context, format }
|
|
14
|
-
}
|
|
15
|
-
|
|
16
3
|
const defaultVertexWGSL = `
|
|
17
4
|
@vertex
|
|
18
5
|
fn main(@builtin(vertex_index) vertex_index: u32) -> @builtin(position) vec4f {
|
|
@@ -23,13 +10,21 @@ fn main(@builtin(vertex_index) vertex_index: u32) -> @builtin(position) vec4f {
|
|
|
23
10
|
`
|
|
24
11
|
|
|
25
12
|
const defaultFragmentWGSL = `
|
|
13
|
+
struct Uniforms {
|
|
14
|
+
iResolution: vec2f,
|
|
15
|
+
iMouse: vec2f,
|
|
16
|
+
iTime: f32,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@group(0) @binding(0) var<uniform> u: Uniforms;
|
|
20
|
+
|
|
26
21
|
@fragment
|
|
27
22
|
fn main(@builtin(position) position: vec4f) -> @location(0) vec4f {
|
|
28
|
-
return vec4f(position.xy /
|
|
23
|
+
return vec4f(position.xy / iResolution, 0.0, 1.0);
|
|
29
24
|
}
|
|
30
25
|
`
|
|
31
26
|
|
|
32
|
-
export const
|
|
27
|
+
export const createPipeline = (
|
|
33
28
|
device: GPUDevice,
|
|
34
29
|
format: string,
|
|
35
30
|
vs = defaultVertexWGSL,
|
|
@@ -64,65 +59,66 @@ export const createDescriptor = (c: GPUContext) => {
|
|
|
64
59
|
],
|
|
65
60
|
}
|
|
66
61
|
}
|
|
67
|
-
export const alignTo256 = (size: number) => Math.ceil(size / 256) * 256
|
|
68
|
-
|
|
69
|
-
export const createUniformBuffer = (device: GPUDevice, size: number) => {
|
|
70
|
-
return device.createBuffer({ size: alignTo256(size), usage: 0x40 | 0x4 }) as Buffer
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export const createVertexBuffer = (device: GPUDevice, value: number[]) => {
|
|
74
|
-
const array = new Float32Array(value)
|
|
75
|
-
const buffer = device.createBuffer({ size: array.byteLength, usage: 0x20 | 0x4 })
|
|
76
|
-
device.queue.writeBuffer(buffer, 0, array)
|
|
77
|
-
return buffer as Buffer
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export const createBindGroup = (device: GPUDevice, pipeline: GPUPipeline, entries: any[]) => {
|
|
81
|
-
const layout = pipeline.getBindGroupLayout(0)
|
|
82
|
-
return device.createBindGroup({ layout, entries })
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export const updateBindGroup = (
|
|
86
|
-
device: GPUDevice,
|
|
87
|
-
pipeline: GPUPipeline,
|
|
88
|
-
uniformBuffer: Buffer,
|
|
89
|
-
textures: any = {},
|
|
90
|
-
sampler: any = null
|
|
91
|
-
) => {
|
|
92
|
-
const entries = [{ binding: 0, resource: { buffer: uniformBuffer } }]
|
|
93
|
-
let binding = 1
|
|
94
|
-
Object.values(textures).forEach((texture: any) => {
|
|
95
|
-
entries.push({ binding: binding++, resource: texture.createView() })
|
|
96
|
-
})
|
|
97
|
-
if (sampler && Object.keys(textures).length > 0) entries.push({ binding: binding++, resource: sampler })
|
|
98
|
-
return createBindGroup(device, pipeline, entries)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export const createUniform = (device: GPUDevice, buffer: any, data: Float32Array, offset = 0) => {
|
|
102
|
-
device.queue.writeBuffer(buffer, offset, data)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export const createDeviceTexture = (device: GPUDevice, image: HTMLImageElement) => {
|
|
106
|
-
const texture = device.createTexture({
|
|
107
|
-
size: { width: image.width, height: image.height },
|
|
108
|
-
format: 'rgba8unorm',
|
|
109
|
-
usage: 0x4 | 0x2,
|
|
110
|
-
})
|
|
111
|
-
device.queue.copyExternalImageToTexture(
|
|
112
|
-
{ source: image },
|
|
113
|
-
{ texture },
|
|
114
|
-
{ width: image.width, height: image.height }
|
|
115
|
-
)
|
|
116
|
-
return texture
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export const createSampler = (device: GPUDevice) => {
|
|
120
|
-
return device.createSampler({
|
|
121
|
-
magFilter: 'linear',
|
|
122
|
-
minFilter: 'linear',
|
|
123
|
-
addressModeU: 'clamp-to-edge',
|
|
124
|
-
addressModeV: 'clamp-to-edge',
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
62
|
|
|
128
|
-
export const
|
|
63
|
+
// export const alignTo256 = (size: number) => Math.ceil(size / 256) * 256
|
|
64
|
+
//
|
|
65
|
+
// export const createUniformBuffer = (device: GPUDevice, size: number) => {
|
|
66
|
+
// return device.createBuffer({ size: alignTo256(size), usage: 0x40 | 0x4 }) as Buffer
|
|
67
|
+
// }
|
|
68
|
+
//
|
|
69
|
+
// export const createVertexBuffer = (device: GPUDevice, value: number[]) => {
|
|
70
|
+
// const array = new Float32Array(value)
|
|
71
|
+
// const buffer = device.createBuffer({ size: array.byteLength, usage: 0x20 | 0x4 })
|
|
72
|
+
// device.queue.writeBuffer(buffer, 0, array)
|
|
73
|
+
// return buffer as Buffer
|
|
74
|
+
// }
|
|
75
|
+
//
|
|
76
|
+
// export const createBindGroup = (device: GPUDevice, pipeline: GPUPipeline, entries: any[]) => {
|
|
77
|
+
// const layout = pipeline.getBindGroupLayout(0)
|
|
78
|
+
// return device.createBindGroup({ layout, entries })
|
|
79
|
+
// }
|
|
80
|
+
//
|
|
81
|
+
// export const updateBindGroup = (
|
|
82
|
+
// device: GPUDevice,
|
|
83
|
+
// pipeline: GPUPipeline,
|
|
84
|
+
// uniformBuffer: Buffer,
|
|
85
|
+
// textures: any = {},
|
|
86
|
+
// sampler: any = null
|
|
87
|
+
// ) => {
|
|
88
|
+
// const entries = [{ binding: 0, resource: { buffer: uniformBuffer } }]
|
|
89
|
+
// let binding = 1
|
|
90
|
+
// Object.values(textures).forEach((texture: any) => {
|
|
91
|
+
// entries.push({ binding: binding++, resource: texture.createView() })
|
|
92
|
+
// })
|
|
93
|
+
// if (sampler && Object.keys(textures).length > 0) entries.push({ binding: binding++, resource: sampler })
|
|
94
|
+
// return createBindGroup(device, pipeline, entries)
|
|
95
|
+
// }
|
|
96
|
+
//
|
|
97
|
+
// export const createUniform = (device: GPUDevice, buffer: any, data: Float32Array, offset = 0) => {
|
|
98
|
+
// device.queue.writeBuffer(buffer, offset, data)
|
|
99
|
+
// }
|
|
100
|
+
//
|
|
101
|
+
// export const createDeviceTexture = (device: GPUDevice, image: HTMLImageElement) => {
|
|
102
|
+
// const texture = device.createTexture({
|
|
103
|
+
// size: { width: image.width, height: image.height },
|
|
104
|
+
// format: 'rgba8unorm',
|
|
105
|
+
// usage: 0x4 | 0x2,
|
|
106
|
+
// })
|
|
107
|
+
// device.queue.copyExternalImageToTexture(
|
|
108
|
+
// { source: image },
|
|
109
|
+
// { texture },
|
|
110
|
+
// { width: image.width, height: image.height }
|
|
111
|
+
// )
|
|
112
|
+
// return texture
|
|
113
|
+
// }
|
|
114
|
+
//
|
|
115
|
+
// export const createSampler = (device: GPUDevice) => {
|
|
116
|
+
// return device.createSampler({
|
|
117
|
+
// magFilter: 'linear',
|
|
118
|
+
// minFilter: 'linear',
|
|
119
|
+
// addressModeU: 'clamp-to-edge',
|
|
120
|
+
// addressModeV: 'clamp-to-edge',
|
|
121
|
+
// })
|
|
122
|
+
// }
|
|
123
|
+
//
|
|
124
|
+
// export const getDefaultVertices = () => new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1])
|
package/src/webgl.ts
CHANGED
package/src/webgpu.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { wgsl } from './code/wgsl'
|
|
2
2
|
import { is } from './utils/helpers'
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
createPipeline,
|
|
5
5
|
createDescriptor,
|
|
6
6
|
// createUniformBuffer,
|
|
7
7
|
// updateBindGroup,
|
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
// createSampler,
|
|
12
12
|
} from './utils/pipeline'
|
|
13
13
|
import type { X } from './node'
|
|
14
|
-
import type { GL, GPUPipeline } from './types'
|
|
14
|
+
import type { GL, GPUBindGroup, GPUPipeline } from './types'
|
|
15
|
+
import { nested } from 'reev'
|
|
15
16
|
|
|
16
17
|
const quadVertexCount = 3
|
|
17
18
|
|
|
@@ -27,18 +28,44 @@ export const webgpu = async (gl: GL) => {
|
|
|
27
28
|
const format = gpu.getPreferredCanvasFormat()
|
|
28
29
|
c.configure({ device, format, alphaMode: 'opaque' })
|
|
29
30
|
|
|
31
|
+
// Uniform buffer setup
|
|
32
|
+
// WebGPU 16-byte alignment requirement: iTime(4) + padding(12) + iMouse(8) + iPrevTime(4) + iDeltaTime(4) + iResolution(8) = 40 bytes, rounded to 48
|
|
33
|
+
|
|
34
|
+
const buffer = device.createBuffer({
|
|
35
|
+
size: 64, // @ts-ignore
|
|
36
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
37
|
+
})
|
|
38
|
+
|
|
30
39
|
gl('clean', () => {})
|
|
31
40
|
|
|
41
|
+
const activeUnit = nested((_, size) => (_activeUnit += size))
|
|
42
|
+
let _activeUnit = 0
|
|
32
43
|
let pipeline: GPUPipeline
|
|
44
|
+
let bindGroup: GPUBindGroup
|
|
45
|
+
let uniformData = new Float32Array(0)
|
|
33
46
|
|
|
34
47
|
gl('render', () => {
|
|
35
|
-
if (!pipeline)
|
|
48
|
+
if (!pipeline) {
|
|
49
|
+
pipeline = createPipeline(device, format, vs, fs, [])
|
|
50
|
+
bindGroup = device.createBindGroup({
|
|
51
|
+
layout: pipeline.getBindGroupLayout(0),
|
|
52
|
+
entries: [
|
|
53
|
+
{
|
|
54
|
+
binding: 0,
|
|
55
|
+
resource: { buffer },
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
36
61
|
const encoder = device.createCommandEncoder()
|
|
37
62
|
const pass = encoder.beginRenderPass(createDescriptor(c))
|
|
38
63
|
pass.setPipeline(pipeline)
|
|
64
|
+
pass.setBindGroup(0, bindGroup)
|
|
39
65
|
pass.draw(quadVertexCount, 1, 0, 0)
|
|
40
66
|
pass.end()
|
|
41
67
|
device.queue.submit([encoder.finish()])
|
|
68
|
+
return true
|
|
42
69
|
})
|
|
43
70
|
|
|
44
71
|
gl('_attribute', (key = '', value: number[]) => {
|
|
@@ -46,17 +73,22 @@ export const webgpu = async (gl: GL) => {
|
|
|
46
73
|
// vertexBuffers(key, value)
|
|
47
74
|
})
|
|
48
75
|
|
|
49
|
-
gl('_uniform', (key: string, value
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
76
|
+
gl('_uniform', (key: string, value: number | number[]) => {
|
|
77
|
+
if (is.num(value)) value = [value]
|
|
78
|
+
const size = value.length
|
|
79
|
+
const unit = activeUnit(key, size)
|
|
80
|
+
if (unit === _activeUnit) {
|
|
81
|
+
const array = new Float32Array(_activeUnit)
|
|
82
|
+
if (uniformData) array.set(uniformData)
|
|
83
|
+
uniformData = array
|
|
84
|
+
}
|
|
85
|
+
for (let i = 0; i < size; i++) uniformData[unit - size + i] = value[i]
|
|
86
|
+
device.queue.writeBuffer(buffer, 0, uniformData)
|
|
55
87
|
})
|
|
56
88
|
|
|
57
89
|
// const _loadFun = (image: HTMLImageElement, gl: GL) => {
|
|
58
90
|
// const texture = createDeviceTexture(device, image)
|
|
59
|
-
// // bindGroup = updateBindGroup(device, pipeline,
|
|
91
|
+
// // bindGroup = updateBindGroup(device, pipeline, buffer, textures, sampler)
|
|
60
92
|
// }
|
|
61
93
|
|
|
62
94
|
gl('_texture', (alt: string, src: string) => {
|