glre 0.20.0 → 0.22.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 +150 -80
- package/dist/index.d.ts +442 -236
- package/dist/index.js +46 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46 -13
- package/dist/index.mjs.map +1 -1
- package/dist/native.d.ts +7 -530
- package/dist/native.js +46 -13
- package/dist/native.js.map +1 -1
- package/dist/native.mjs +46 -13
- package/dist/native.mjs.map +1 -1
- package/dist/react.d.ts +7 -478
- package/dist/react.js +46 -13
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +46 -13
- package/dist/react.mjs.map +1 -1
- package/dist/solid.d.ts +7 -424
- package/dist/solid.js +46 -13
- package/dist/solid.js.map +1 -1
- package/dist/solid.mjs +46 -13
- package/dist/solid.mjs.map +1 -1
- package/package.json +26 -61
- package/src/code/glsl.ts +186 -0
- package/src/code/wgsl.ts +170 -0
- package/src/index.ts +105 -0
- package/src/native.ts +24 -0
- package/src/node/cache.ts +67 -0
- package/src/node/const.ts +147 -0
- package/src/node/conv.ts +122 -0
- package/src/node/index.ts +96 -0
- package/src/node/node.ts +114 -0
- package/src/node/types.ts +101 -0
- package/src/node/uniform.ts +99 -0
- package/src/react.ts +18 -0
- package/src/solid.ts +15 -0
- package/src/types.ts +90 -0
- package/src/utils.ts +53 -0
- package/src/webgl/buffer.ts +78 -0
- package/src/webgl/index.ts +79 -0
- package/src/webgl/program.ts +61 -0
- package/src/webgl/shader.ts +60 -0
- package/src/webgl/texture.ts +93 -0
- package/src/webgpu/buffer.ts +96 -0
- package/src/webgpu/device.ts +91 -0
- package/src/webgpu/index.ts +40 -0
- package/src/webgpu/pipeline.ts +94 -0
- package/src/webgpu/texture.ts +139 -0
- package/dist/types-2792569d.d.ts +0 -7
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// WebGPUデバイス管理
|
|
2
|
+
export const requestWebGPUDevice = async (): Promise<{
|
|
3
|
+
adapter: any // GPUAdapter @TODO FIX
|
|
4
|
+
device: any // GPUDevice @TODO FIX
|
|
5
|
+
}> => {
|
|
6
|
+
// @ts-ignore @TODO FIX
|
|
7
|
+
if (!navigator.gpu)
|
|
8
|
+
throw new Error('WebGPU is not supported in this browser')
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
const adapter = await navigator.gpu.requestAdapter()
|
|
11
|
+
if (!adapter) throw new Error('Failed to get WebGPU adapter')
|
|
12
|
+
const device = await adapter.requestDevice()
|
|
13
|
+
if (!device) throw new Error('Failed to get WebGPU device')
|
|
14
|
+
return { adapter, device }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// WebGPUデバイスの機能チェック
|
|
18
|
+
export const checkWebGPUSupport = (): boolean => {
|
|
19
|
+
return 'gpu' in navigator
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// デバイスの制限情報を取得
|
|
23
|
+
export const getDeviceLimits = (device: any) => {
|
|
24
|
+
return {
|
|
25
|
+
maxTextureDimension1D: device.limits.maxTextureDimension1D,
|
|
26
|
+
maxTextureDimension2D: device.limits.maxTextureDimension2D,
|
|
27
|
+
maxTextureDimension3D: device.limits.maxTextureDimension3D,
|
|
28
|
+
maxTextureArrayLayers: device.limits.maxTextureArrayLayers,
|
|
29
|
+
maxBindGroups: device.limits.maxBindGroups,
|
|
30
|
+
maxDynamicUniformBuffersPerPipelineLayout:
|
|
31
|
+
device.limits.maxDynamicUniformBuffersPerPipelineLayout,
|
|
32
|
+
maxDynamicStorageBuffersPerPipelineLayout:
|
|
33
|
+
device.limits.maxDynamicStorageBuffersPerPipelineLayout,
|
|
34
|
+
maxSampledTexturesPerShaderStage:
|
|
35
|
+
device.limits.maxSampledTexturesPerShaderStage,
|
|
36
|
+
maxSamplersPerShaderStage:
|
|
37
|
+
device.limits.maxSamplersPerShaderStage,
|
|
38
|
+
maxStorageBuffersPerShaderStage:
|
|
39
|
+
device.limits.maxStorageBuffersPerShaderStage,
|
|
40
|
+
maxStorageTexturesPerShaderStage:
|
|
41
|
+
device.limits.maxStorageTexturesPerShaderStage,
|
|
42
|
+
maxUniformBuffersPerShaderStage:
|
|
43
|
+
device.limits.maxUniformBuffersPerShaderStage,
|
|
44
|
+
maxUniformBufferBindingSize:
|
|
45
|
+
device.limits.maxUniformBufferBindingSize,
|
|
46
|
+
maxStorageBufferBindingSize:
|
|
47
|
+
device.limits.maxStorageBufferBindingSize,
|
|
48
|
+
maxVertexBuffers: device.limits.maxVertexBuffers,
|
|
49
|
+
maxVertexAttributes: device.limits.maxVertexAttributes,
|
|
50
|
+
maxVertexBufferArrayStride:
|
|
51
|
+
device.limits.maxVertexBufferArrayStride,
|
|
52
|
+
maxComputeWorkgroupStorageSize:
|
|
53
|
+
device.limits.maxComputeWorkgroupStorageSize,
|
|
54
|
+
maxComputeInvocationsPerWorkgroup:
|
|
55
|
+
device.limits.maxComputeInvocationsPerWorkgroup,
|
|
56
|
+
maxComputeWorkgroupSizeX:
|
|
57
|
+
device.limits.maxComputeWorkgroupSizeX,
|
|
58
|
+
maxComputeWorkgroupSizeY:
|
|
59
|
+
device.limits.maxComputeWorkgroupSizeY,
|
|
60
|
+
maxComputeWorkgroupSizeZ:
|
|
61
|
+
device.limits.maxComputeWorkgroupSizeZ,
|
|
62
|
+
maxComputeWorkgroupsPerDimension:
|
|
63
|
+
device.limits.maxComputeWorkgroupsPerDimension,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// デバイスエラーハンドリング
|
|
68
|
+
export const setupDeviceErrorHandling = (device: any) => {
|
|
69
|
+
device.addEventListener('uncapturederror', (event: any) => {
|
|
70
|
+
console.error('WebGPU uncaptured error:', event.error)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// キャンバスコンテキストの設定
|
|
75
|
+
export const configureCanvasContext = (
|
|
76
|
+
canvas: HTMLCanvasElement,
|
|
77
|
+
device: any,
|
|
78
|
+
format: any = 'bgra8unorm'
|
|
79
|
+
) => {
|
|
80
|
+
const context = canvas.getContext('webgpu')
|
|
81
|
+
if (!context) throw new Error('Failed to get WebGPU canvas context')
|
|
82
|
+
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
context.configure({
|
|
85
|
+
device,
|
|
86
|
+
format,
|
|
87
|
+
alphaMode: 'premultiplied',
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
return context
|
|
91
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { requestWebGPUDevice } from './device'
|
|
2
|
+
import { createCommandEncoder, createRenderPass, createRenderPipeline } from './pipeline'
|
|
3
|
+
import { wgsl } from '../code/wgsl'
|
|
4
|
+
import { is } from '../utils'
|
|
5
|
+
import type { X } from '../node'
|
|
6
|
+
import type { GL } from '../types'
|
|
7
|
+
export * from './buffer'
|
|
8
|
+
export * from './device'
|
|
9
|
+
export * from './pipeline'
|
|
10
|
+
export * from './texture'
|
|
11
|
+
|
|
12
|
+
export const webgpu = (gl: GL) => {
|
|
13
|
+
const init = async () => {
|
|
14
|
+
const { device } = await requestWebGPUDevice()
|
|
15
|
+
gl.gl = { device }
|
|
16
|
+
let vs = gl.vs || gl.vert || gl.vertex
|
|
17
|
+
let fs = gl.fs || gl.frag || gl.fragment
|
|
18
|
+
if (is.obj(vs)) vs = wgsl(fs as X)
|
|
19
|
+
if (is.obj(fs)) fs = wgsl(fs as X)
|
|
20
|
+
gl.gl.pipeline = createRenderPipeline(device, vs, fs)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const loop = () => {
|
|
24
|
+
const { device, context, pipeline } = gl.gl
|
|
25
|
+
const encoder = createCommandEncoder(device)
|
|
26
|
+
const pass = createRenderPass(encoder, {
|
|
27
|
+
view: context.getCurrentTexture().createView(),
|
|
28
|
+
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
29
|
+
loadOp: 'clear',
|
|
30
|
+
storeOp: 'store',
|
|
31
|
+
})
|
|
32
|
+
pass.setPipeline(pipeline)
|
|
33
|
+
pass.draw(gl.count)
|
|
34
|
+
pass.end()
|
|
35
|
+
device.queue.submit([encoder.finish()])
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// @TODO add uniform and attribute
|
|
39
|
+
return gl({ init, loop })
|
|
40
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// デフォルトの頂点シェーダー
|
|
2
|
+
const defaultVertexShader = `
|
|
3
|
+
@vertex
|
|
4
|
+
fn main(@builtin(vertex_index) vertexIndex: u32) -> @builtin(position) vec4<f32> {
|
|
5
|
+
var pos = array<vec2<f32>, 6>(
|
|
6
|
+
vec2<f32>(-1.0, -1.0),
|
|
7
|
+
vec2<f32>( 1.0, -1.0),
|
|
8
|
+
vec2<f32>(-1.0, 1.0),
|
|
9
|
+
vec2<f32>(-1.0, 1.0),
|
|
10
|
+
vec2<f32>( 1.0, -1.0),
|
|
11
|
+
vec2<f32>( 1.0, 1.0)
|
|
12
|
+
);
|
|
13
|
+
return vec4<f32>(pos[vertexIndex], 0.0, 1.0);
|
|
14
|
+
}
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
// デフォルトのフラグメントシェーダー
|
|
18
|
+
const defaultFragmentShader = `
|
|
19
|
+
@fragment
|
|
20
|
+
fn main() -> @location(0) vec4<f32> {
|
|
21
|
+
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
|
22
|
+
}
|
|
23
|
+
`
|
|
24
|
+
|
|
25
|
+
// WebGPUパイプライン管理
|
|
26
|
+
export const createRenderPipeline = (
|
|
27
|
+
device: any,
|
|
28
|
+
vertexShader = defaultVertexShader,
|
|
29
|
+
fragmentShader = defaultFragmentShader,
|
|
30
|
+
format = 'bgra8unorm'
|
|
31
|
+
) => {
|
|
32
|
+
const v = device.createShaderModule({ code: vertexShader })
|
|
33
|
+
const f = device.createShaderModule({ code: fragmentShader })
|
|
34
|
+
return device.createRenderPipeline({
|
|
35
|
+
layout: 'auto',
|
|
36
|
+
vertex: {
|
|
37
|
+
module: v,
|
|
38
|
+
entryPoint: 'main',
|
|
39
|
+
},
|
|
40
|
+
fragment: {
|
|
41
|
+
module: f,
|
|
42
|
+
entryPoint: 'main',
|
|
43
|
+
targets: [
|
|
44
|
+
{
|
|
45
|
+
format,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
primitive: {
|
|
50
|
+
topology: 'triangle-list',
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// コンピュートパイプライン作成
|
|
56
|
+
export const createComputePipeline = (device: any, computeShader: string) => {
|
|
57
|
+
const computeModule = device.createShaderModule({ code: computeShader })
|
|
58
|
+
return device.createComputePipeline({
|
|
59
|
+
layout: 'auto',
|
|
60
|
+
compute: { module: computeModule, entryPoint: 'main' },
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// シェーダーモジュール作成
|
|
65
|
+
export const createShaderModule = (device: any, code: string) => {
|
|
66
|
+
return device.createShaderModule({ code })
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// バインドグループレイアウト作成
|
|
70
|
+
export const createBindGroupLayout = (device: any, entries: any[]) => {
|
|
71
|
+
return device.createBindGroupLayout({ entries })
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// バインドグループ作成
|
|
75
|
+
export const createBindGroup = (device: any, layout: any, entries: any[]) => {
|
|
76
|
+
return device.createBindGroup({ layout, entries })
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// レンダーパス作成
|
|
80
|
+
export const createRenderPass = (
|
|
81
|
+
encoder: any,
|
|
82
|
+
colorAttachment: any,
|
|
83
|
+
depthStencilAttachment?: any
|
|
84
|
+
) => {
|
|
85
|
+
const descriptor: any = { colorAttachments: [colorAttachment] }
|
|
86
|
+
if (depthStencilAttachment)
|
|
87
|
+
descriptor.depthStencilAttachment = depthStencilAttachment
|
|
88
|
+
return encoder.beginRenderPass(descriptor)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// コマンドエンコーダー作成
|
|
92
|
+
export const createCommandEncoder = (device: any) => {
|
|
93
|
+
return device.createCommandEncoder()
|
|
94
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// WebGPUテクスチャ管理
|
|
2
|
+
const createTexture = (
|
|
3
|
+
device: any,
|
|
4
|
+
w = 1280,
|
|
5
|
+
h = 800,
|
|
6
|
+
format = 'rgba8unorm',
|
|
7
|
+
usage = 0x14 // GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
|
|
8
|
+
) => {
|
|
9
|
+
return device.createTexture({
|
|
10
|
+
size: { width: w, height: h, depthOrArrayLayers: 1 },
|
|
11
|
+
format,
|
|
12
|
+
usage,
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 画像からテクスチャ作成
|
|
17
|
+
export const createTextureFromImage = (
|
|
18
|
+
device: any,
|
|
19
|
+
image: HTMLImageElement | ImageBitmap,
|
|
20
|
+
format = 'rgba8unorm'
|
|
21
|
+
) => {
|
|
22
|
+
const texture = createTexture(
|
|
23
|
+
device,
|
|
24
|
+
image.width,
|
|
25
|
+
image.height,
|
|
26
|
+
format,
|
|
27
|
+
0x14 | 0x4 // TEXTURE_BINDING | COPY_DST
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
device.queue.copyExternalImageToTexture(
|
|
31
|
+
{ source: image },
|
|
32
|
+
{ texture },
|
|
33
|
+
{ width: image.width, height: image.height }
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
return texture
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// キューブマップテクスチャ作成
|
|
40
|
+
const createCubeTexture = (
|
|
41
|
+
device: any,
|
|
42
|
+
size: number,
|
|
43
|
+
format = 'rgba8unorm'
|
|
44
|
+
) => {
|
|
45
|
+
return device.createTexture({
|
|
46
|
+
size: { width: size, height: size, depthOrArrayLayers: 6 },
|
|
47
|
+
format,
|
|
48
|
+
usage: 0x14, // GPUTextureUsage.TEXTURE_BINDING
|
|
49
|
+
dimension: '2d',
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 深度テクスチャ作成
|
|
54
|
+
export const createDepthTexture = (
|
|
55
|
+
device: any,
|
|
56
|
+
w = 1280,
|
|
57
|
+
h = 800,
|
|
58
|
+
format = 'depth24plus'
|
|
59
|
+
) => {
|
|
60
|
+
return device.createTexture({
|
|
61
|
+
size: { width: w, height: h, depthOrArrayLayers: 1 },
|
|
62
|
+
format,
|
|
63
|
+
usage: 0x10, // GPUTextureUsage.RENDER_ATTACHMENT
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// サンプラー作成
|
|
68
|
+
export const createSampler = (
|
|
69
|
+
device: any,
|
|
70
|
+
options: {
|
|
71
|
+
magFilter?: string
|
|
72
|
+
minFilter?: string
|
|
73
|
+
addressModeU?: string
|
|
74
|
+
addressModeV?: string
|
|
75
|
+
addressModeW?: string
|
|
76
|
+
} = {}
|
|
77
|
+
) => {
|
|
78
|
+
return device.createSampler({
|
|
79
|
+
magFilter: options.magFilter || 'linear',
|
|
80
|
+
minFilter: options.minFilter || 'linear',
|
|
81
|
+
addressModeU: options.addressModeU || 'repeat',
|
|
82
|
+
addressModeV: options.addressModeV || 'repeat',
|
|
83
|
+
addressModeW: options.addressModeW || 'repeat',
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// テクスチャビュー作成
|
|
88
|
+
export const createTextureView = (
|
|
89
|
+
texture: any,
|
|
90
|
+
options: {
|
|
91
|
+
format?: string
|
|
92
|
+
dimension?: string
|
|
93
|
+
aspect?: string
|
|
94
|
+
baseMipLevel?: number
|
|
95
|
+
mipLevelCount?: number
|
|
96
|
+
baseArrayLayer?: number
|
|
97
|
+
arrayLayerCount?: number
|
|
98
|
+
} = {}
|
|
99
|
+
) => {
|
|
100
|
+
return texture.createView(options)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// テクスチャデータ更新
|
|
104
|
+
export const updateTexture = (
|
|
105
|
+
device: any,
|
|
106
|
+
texture: any,
|
|
107
|
+
data: Uint8Array | Uint8ClampedArray,
|
|
108
|
+
w = 1280,
|
|
109
|
+
h = 800
|
|
110
|
+
) => {
|
|
111
|
+
device.queue.writeTexture(
|
|
112
|
+
{ texture },
|
|
113
|
+
data,
|
|
114
|
+
{ bytesPerRow: w * 4 },
|
|
115
|
+
{ width: w, height: h }
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// テクスチャの削除
|
|
120
|
+
export const destroyTexture = (texture: any) => texture.destroy()
|
|
121
|
+
|
|
122
|
+
// テクスチャ使用量の定数
|
|
123
|
+
export const TextureUsage = {
|
|
124
|
+
COPY_SRC: 0x1,
|
|
125
|
+
COPY_DST: 0x2,
|
|
126
|
+
TEXTURE_BINDING: 0x4,
|
|
127
|
+
STORAGE_BINDING: 0x8,
|
|
128
|
+
RENDER_ATTACHMENT: 0x10,
|
|
129
|
+
} as const
|
|
130
|
+
|
|
131
|
+
// テクスチャフォーマットの定数
|
|
132
|
+
export const TextureFormat = {
|
|
133
|
+
RGBA8_UNORM: 'rgba8unorm',
|
|
134
|
+
RGBA8_SRGB: 'rgba8unorm-srgb',
|
|
135
|
+
BGRA8_UNORM: 'bgra8unorm',
|
|
136
|
+
BGRA8_SRGB: 'bgra8unorm-srgb',
|
|
137
|
+
DEPTH24_PLUS: 'depth24plus',
|
|
138
|
+
DEPTH32_FLOAT: 'depth32float',
|
|
139
|
+
} as const
|
package/dist/types-2792569d.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
declare type Uniform = number | number[];
|
|
2
|
-
declare type Attribute = number[];
|
|
3
|
-
declare type PrecisionMode = 'highp' | 'mediump' | 'lowp';
|
|
4
|
-
declare type GLClearMode = 'COLOR_BUFFER_BIT' | 'DEPTH_BUFFER_BIT' | 'STENCIL_BUFFER_BIT';
|
|
5
|
-
declare type GLDrawMode = 'POINTS' | 'LINE_STRIP' | 'LINE_LOOP' | 'LINES' | 'TRIANGLE_STRIP' | 'TRIANGLE_FAN' | 'TRIANGLES';
|
|
6
|
-
|
|
7
|
-
export { Attribute as A, GLClearMode as G, PrecisionMode as P, Uniform as U, GLDrawMode as a };
|