glre 0.38.0 → 0.40.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 +8 -4
- package/dist/addons.cjs +2 -0
- package/dist/addons.cjs.map +1 -0
- package/dist/addons.d.ts +1287 -0
- package/dist/addons.js +2 -0
- package/dist/addons.js.map +1 -0
- package/dist/index.cjs +31 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +187 -323
- package/dist/index.js +31 -43
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +1 -48
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.ts +536 -10
- package/dist/native.js +1 -48
- package/dist/native.js.map +1 -1
- package/dist/node.cjs +69 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.ts +626 -0
- package/dist/node.js +69 -0
- package/dist/node.js.map +1 -0
- package/dist/react.cjs +1 -48
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +524 -4
- package/dist/react.js +1 -48
- package/dist/react.js.map +1 -1
- package/dist/solid.cjs +1 -48
- package/dist/solid.cjs.map +1 -1
- package/dist/solid.d.ts +524 -4
- package/dist/solid.js +1 -48
- package/dist/solid.js.map +1 -1
- package/package.json +64 -11
- package/src/addons/animation/easing/backIn.ts +10 -0
- package/src/addons/animation/easing/backInOut.ts +12 -0
- package/src/addons/animation/easing/backOut.ts +10 -0
- package/src/addons/animation/easing/bounceIn.ts +10 -0
- package/src/addons/animation/easing/bounceInOut.ts +13 -0
- package/src/addons/animation/easing/bounceOut.ts +30 -0
- package/src/addons/animation/easing/circularIn.ts +9 -0
- package/src/addons/animation/easing/circularInOut.ts +11 -0
- package/src/addons/animation/easing/circularOut.ts +9 -0
- package/src/addons/animation/easing/cubicIn.ts +9 -0
- package/src/addons/animation/easing/cubicInOut.ts +11 -0
- package/src/addons/animation/easing/cubicOut.ts +10 -0
- package/src/addons/animation/easing/elasticIn.ts +10 -0
- package/src/addons/animation/easing/elasticInOut.ts +21 -0
- package/src/addons/animation/easing/elasticOut.ts +12 -0
- package/src/addons/animation/easing/exponentialIn.ts +9 -0
- package/src/addons/animation/easing/exponentialInOut.ts +13 -0
- package/src/addons/animation/easing/exponentialOut.ts +9 -0
- package/src/addons/animation/easing/index.ts +33 -0
- package/src/addons/animation/easing/linearIn.ts +9 -0
- package/src/addons/animation/easing/linearInOut.ts +9 -0
- package/src/addons/animation/easing/linearOut.ts +9 -0
- package/src/addons/animation/easing/quadraticIn.ts +9 -0
- package/src/addons/animation/easing/quadraticInOut.ts +10 -0
- package/src/addons/animation/easing/quadraticOut.ts +9 -0
- package/src/addons/animation/easing/quarticIn.ts +9 -0
- package/src/addons/animation/easing/quarticInOut.ts +11 -0
- package/src/addons/animation/easing/quarticOut.ts +10 -0
- package/src/addons/animation/easing/quinticIn.ts +9 -0
- package/src/addons/animation/easing/quinticInOut.ts +11 -0
- package/src/addons/animation/easing/quinticOut.ts +9 -0
- package/src/addons/animation/easing/sineIn.ts +10 -0
- package/src/addons/animation/easing/sineInOut.ts +10 -0
- package/src/addons/animation/easing/sineOut.ts +10 -0
- package/src/addons/color/palette/macbeth.ts +42 -0
- package/src/addons/color/space/cmyk2rgb.ts +12 -0
- package/src/addons/color/space/gamma2linear.ts +19 -0
- package/src/addons/color/space/hsl2rgb.ts +20 -0
- package/src/addons/color/space/hsv2rgb.ts +18 -0
- package/src/addons/color/space/hue2rgb.ts +12 -0
- package/src/addons/color/space/index.ts +29 -0
- package/src/addons/color/space/lab2lch.ts +22 -0
- package/src/addons/color/space/lab2rgb.ts +19 -0
- package/src/addons/color/space/lab2xyz.ts +32 -0
- package/src/addons/color/space/lch2lab.ts +21 -0
- package/src/addons/color/space/lch2rgb.ts +22 -0
- package/src/addons/color/space/linear2gamma.ts +19 -0
- package/src/addons/color/space/oklab2rgb.ts +35 -0
- package/src/addons/color/space/rgb2cmyk.ts +13 -0
- package/src/addons/color/space/rgb2hcv.ts +29 -0
- package/src/addons/color/space/rgb2hsl.ts +23 -0
- package/src/addons/color/space/rgb2hsv.ts +36 -0
- package/src/addons/color/space/rgb2hue.ts +29 -0
- package/src/addons/color/space/rgb2lab.ts +19 -0
- package/src/addons/color/space/rgb2lch.ts +22 -0
- package/src/addons/color/space/rgb2oklab.ts +45 -0
- package/src/addons/color/space/rgb2srgb.ts +34 -0
- package/src/addons/color/space/rgb2xyz.ts +20 -0
- package/src/addons/color/space/rgb2yiq.ts +22 -0
- package/src/addons/color/space/rgb2yuv.ts +32 -0
- package/src/addons/color/space/srgb2rgb.ts +34 -0
- package/src/addons/color/space/xyz2lab.ts +27 -0
- package/src/addons/color/space/xyz2rgb.ts +30 -0
- package/src/addons/color/space/yiq2rgb.ts +22 -0
- package/src/addons/color/space/yuv2rgb.ts +32 -0
- package/src/addons/draw/arrows.ts +75 -0
- package/src/addons/draw/axis.ts +57 -0
- package/src/addons/draw/bridge.ts +81 -0
- package/src/addons/draw/char.ts +30 -0
- package/src/addons/draw/circle.ts +29 -0
- package/src/addons/draw/fill.ts +25 -0
- package/src/addons/draw/flip.ts +45 -0
- package/src/addons/draw/hex.ts +29 -0
- package/src/addons/draw/index.ts +13 -0
- package/src/addons/draw/line.ts +16 -0
- package/src/addons/draw/point.ts +30 -0
- package/src/addons/draw/rect.ts +52 -0
- package/src/addons/draw/stroke.ts +31 -0
- package/src/addons/draw/tri.ts +29 -0
- package/src/addons/generative/cnoise.ts +239 -0
- package/src/addons/generative/curl.ts +64 -0
- package/src/addons/generative/fbm.ts +69 -0
- package/src/addons/generative/gerstnerWave.ts +21 -0
- package/src/addons/generative/gnoise.ts +113 -0
- package/src/addons/generative/index.ts +15 -0
- package/src/addons/generative/noised.ts +139 -0
- package/src/addons/generative/pnoise.ts +249 -0
- package/src/addons/generative/psrdnoise.ts +277 -0
- package/src/addons/generative/random.ts +136 -0
- package/src/addons/generative/snoise.ts +199 -0
- package/src/addons/generative/srandom.ts +90 -0
- package/src/addons/generative/voronoi.ts +134 -0
- package/src/addons/generative/voronoise.ts +69 -0
- package/src/addons/generative/wavelet.ts +77 -0
- package/src/addons/generative/worley.ts +99 -0
- package/src/addons/geometry/aabb/aabb.ts +8 -0
- package/src/addons/geometry/aabb/centroid.ts +10 -0
- package/src/addons/geometry/aabb/contain.ts +19 -0
- package/src/addons/geometry/aabb/diagonal.ts +10 -0
- package/src/addons/geometry/aabb/expand.ts +16 -0
- package/src/addons/geometry/aabb/index.ts +7 -0
- package/src/addons/geometry/aabb/intersect.ts +20 -0
- package/src/addons/geometry/aabb/square.ts +17 -0
- package/src/addons/geometry/index.ts +2 -0
- package/src/addons/geometry/triangle/area.ts +10 -0
- package/src/addons/geometry/triangle/barycentric.ts +50 -0
- package/src/addons/geometry/triangle/centroid.ts +10 -0
- package/src/addons/geometry/triangle/closestPoint.ts +85 -0
- package/src/addons/geometry/triangle/contain.ts +19 -0
- package/src/addons/geometry/triangle/distanceSq.ts +38 -0
- package/src/addons/geometry/triangle/index.ts +10 -0
- package/src/addons/geometry/triangle/intersect.ts +49 -0
- package/src/addons/geometry/triangle/normal.ts +12 -0
- package/src/addons/geometry/triangle/signedDistance.ts +31 -0
- package/src/addons/geometry/triangle/triangle.ts +9 -0
- package/src/addons/index.ts +8 -0
- package/src/addons/lighting/ray.ts +8 -0
- package/src/addons/math/aafloor.ts +13 -0
- package/src/addons/math/aafract.ts +38 -0
- package/src/addons/math/aamirror.ts +12 -0
- package/src/addons/math/aastep.ts +14 -0
- package/src/addons/math/absi.ts +9 -0
- package/src/addons/math/adaptiveThreshold.ts +24 -0
- package/src/addons/math/bump.ts +20 -0
- package/src/addons/math/const.ts +19 -0
- package/src/addons/math/cubic.ts +101 -0
- package/src/addons/math/cubicMix.ts +49 -0
- package/src/addons/math/decimate.ts +12 -0
- package/src/addons/math/dist.ts +143 -0
- package/src/addons/math/fcos.ts +11 -0
- package/src/addons/math/frac.ts +9 -0
- package/src/addons/math/gain.ts +14 -0
- package/src/addons/math/gaussian.ts +14 -0
- package/src/addons/math/grad4.ts +19 -0
- package/src/addons/math/hammersley.ts +54 -0
- package/src/addons/math/highPass.ts +12 -0
- package/src/addons/math/index.ts +63 -0
- package/src/addons/math/inside.ts +68 -0
- package/src/addons/math/invCubic.ts +9 -0
- package/src/addons/math/invQuartic.ts +9 -0
- package/src/addons/math/inverse.ts +9 -0
- package/src/addons/math/lengthSq.ts +10 -0
- package/src/addons/math/map.ts +27 -0
- package/src/addons/math/mirror.ts +12 -0
- package/src/addons/math/mmax.ts +27 -0
- package/src/addons/math/mmin.ts +28 -0
- package/src/addons/math/mmix.ts +47 -0
- package/src/addons/math/mod2.ts +44 -0
- package/src/addons/math/mod289.ts +46 -0
- package/src/addons/math/modi.ts +15 -0
- package/src/addons/math/nyquist.ts +15 -0
- package/src/addons/math/pack.ts +15 -0
- package/src/addons/math/parabola.ts +12 -0
- package/src/addons/math/permute.ts +42 -0
- package/src/addons/math/pow2.ts +10 -0
- package/src/addons/math/pow3.ts +9 -0
- package/src/addons/math/pow5.ts +10 -0
- package/src/addons/math/pow7.ts +12 -0
- package/src/addons/math/powFast.ts +18 -0
- package/src/addons/math/quartic.ts +15 -0
- package/src/addons/math/quat/index.ts +14 -0
- package/src/addons/math/quat/quat2mat3.ts +28 -0
- package/src/addons/math/quat/quat2mat4.ts +16 -0
- package/src/addons/math/quat/quatAdd.ts +18 -0
- package/src/addons/math/quat/quatConj.ts +14 -0
- package/src/addons/math/quat/quatDiv.ts +18 -0
- package/src/addons/math/quat/quatIdentity.ts +9 -0
- package/src/addons/math/quat/quatInverse.ts +17 -0
- package/src/addons/math/quat/quatLength.ts +15 -0
- package/src/addons/math/quat/quatLengthSq.ts +14 -0
- package/src/addons/math/quat/quatLerp.ts +40 -0
- package/src/addons/math/quat/quatMul.ts +38 -0
- package/src/addons/math/quat/quatNeg.ts +14 -0
- package/src/addons/math/quat/quatNorm.ts +16 -0
- package/src/addons/math/quat/quatSub.ts +18 -0
- package/src/addons/math/quintic.ts +16 -0
- package/src/addons/math/rotate2d.ts +16 -0
- package/src/addons/math/rotate3d.ts +37 -0
- package/src/addons/math/rotate3dX.ts +20 -0
- package/src/addons/math/rotate3dY.ts +20 -0
- package/src/addons/math/rotate3dZ.ts +20 -0
- package/src/addons/math/rotate4d.ts +41 -0
- package/src/addons/math/rotate4dX.ts +21 -0
- package/src/addons/math/rotate4dY.ts +16 -0
- package/src/addons/math/rotate4dZ.ts +21 -0
- package/src/addons/math/saturateMediump.ts +11 -0
- package/src/addons/math/scale2d.ts +44 -0
- package/src/addons/math/scale3d.ts +17 -0
- package/src/addons/math/scale4d.ts +50 -0
- package/src/addons/math/smootherstep.ts +16 -0
- package/src/addons/math/taylorInvSqrt.ts +9 -0
- package/src/addons/math/toMat3.ts +14 -0
- package/src/addons/math/toMat4.ts +14 -0
- package/src/addons/math/translate4d.ts +31 -0
- package/src/addons/math/unpack.ts +88 -0
- package/src/addons/sdf/boxSDF.ts +24 -0
- package/src/addons/sdf/circleSDF.ts +20 -0
- package/src/addons/sdf/crossSDF.ts +17 -0
- package/src/addons/sdf/hexSDF.ts +18 -0
- package/src/addons/sdf/index.ts +7 -0
- package/src/addons/sdf/lineSDF.ts +33 -0
- package/src/addons/sdf/rectSDF.ts +46 -0
- package/src/addons/sdf/sphereSDF.ts +20 -0
- package/src/addons/sdf/triSDF.ts +14 -0
- package/src/addons/space/aspect.ts +14 -0
- package/src/addons/space/bracketing.ts +44 -0
- package/src/addons/space/brickTile.ts +44 -0
- package/src/addons/space/cart2polar.ts +20 -0
- package/src/addons/space/center.ts +32 -0
- package/src/addons/space/checkerTile.ts +41 -0
- package/src/addons/space/depth2viewZ.ts +43 -0
- package/src/addons/space/displace.ts +55 -0
- package/src/addons/space/equirect2xyz.ts +17 -0
- package/src/addons/space/eulerView.ts +19 -0
- package/src/addons/space/fisheye2xyz.ts +18 -0
- package/src/addons/space/flipY.ts +25 -0
- package/src/addons/space/hexTile.ts +18 -0
- package/src/addons/space/index.ts +38 -0
- package/src/addons/space/kaleidoscope.ts +48 -0
- package/src/addons/space/linearizeDepth.ts +17 -0
- package/src/addons/space/lookAt.ts +49 -0
- package/src/addons/space/lookAtView.ts +40 -0
- package/src/addons/space/mirrorTile.ts +73 -0
- package/src/addons/space/nearest.ts +13 -0
- package/src/addons/space/orthographic.ts +25 -0
- package/src/addons/space/parallaxMapping.ts +149 -0
- package/src/addons/space/perspective.ts +24 -0
- package/src/addons/space/polar2cart.ts +24 -0
- package/src/addons/space/ratio.ts +14 -0
- package/src/addons/space/rotate.ts +37 -0
- package/src/addons/space/rotateX.ts +54 -0
- package/src/addons/space/rotateY.ts +54 -0
- package/src/addons/space/rotateZ.ts +54 -0
- package/src/addons/space/scale.ts +13 -0
- package/src/addons/space/sprite.ts +16 -0
- package/src/addons/space/sqTile.ts +20 -0
- package/src/addons/space/tbn.ts +26 -0
- package/src/addons/space/translate.ts +12 -0
- package/src/addons/space/triTile.ts +32 -0
- package/src/addons/space/uncenter.ts +32 -0
- package/src/addons/space/unratio.ts +12 -0
- package/src/addons/space/viewZ2depth.ts +25 -0
- package/src/addons/space/windmillTile.ts +58 -0
- package/src/addons/space/xyz2equirect.ts +10 -0
- package/src/index.ts +10 -23
- package/src/node/build.ts +127 -0
- package/src/node/create.ts +76 -0
- package/src/node/index.ts +64 -49
- package/src/node/scope.ts +66 -62
- package/src/node/types.ts +221 -187
- package/src/node/utils/const.ts +74 -13
- package/src/node/utils/index.ts +19 -14
- package/src/node/utils/infer.ts +32 -34
- package/src/node/utils/parse.ts +48 -24
- package/src/node/utils/utils.ts +52 -29
- package/src/types.ts +11 -6
- package/src/utils/helpers.ts +56 -0
- package/src/utils/pipeline.ts +24 -8
- package/src/utils/program.ts +62 -38
- package/src/{webgl.ts → utils/webgl.ts} +46 -30
- package/src/{webgpu.ts → utils/webgpu.ts} +22 -17
- package/src/node/core.ts +0 -121
- package/src/node/node.ts +0 -65
package/src/types.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { EventState, Nested } from 'reev'
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
export type { Fun, Queue, Frame }
|
|
2
|
+
import type { Queue, Frame } from 'refr'
|
|
3
|
+
import type { Vec4, Void } from './node'
|
|
5
4
|
|
|
6
5
|
export type GL = EventState<{
|
|
7
6
|
/**
|
|
@@ -11,14 +10,17 @@ export type GL = EventState<{
|
|
|
11
10
|
isWebGL: boolean
|
|
12
11
|
isError: boolean
|
|
13
12
|
isLoop: boolean
|
|
13
|
+
isDebug: boolean
|
|
14
|
+
isDepth: boolean
|
|
14
15
|
isGL: true
|
|
15
16
|
width?: number
|
|
16
17
|
height?: number
|
|
17
18
|
size: [number, number]
|
|
18
19
|
mouse: [number, number]
|
|
19
20
|
count: number
|
|
21
|
+
instanceCount: number
|
|
22
|
+
particleCount: number | [number, number] | [number, number, number]
|
|
20
23
|
loading: number
|
|
21
|
-
particles: 64 | 256 | 576 | 1024 | 1600 | 2304 | 3136 | 4096 | 4096 | 5184 | 6400 // (8k)^2
|
|
22
24
|
el: HTMLCanvasElement
|
|
23
25
|
vs?: string | Vec4
|
|
24
26
|
cs?: string | Void
|
|
@@ -47,7 +49,7 @@ export type GL = EventState<{
|
|
|
47
49
|
error(e?: string): void
|
|
48
50
|
render(): void
|
|
49
51
|
resize(e?: Event): void
|
|
50
|
-
mousemove(e:
|
|
52
|
+
mousemove(e: MouseEvent): void
|
|
51
53
|
loop(): void
|
|
52
54
|
|
|
53
55
|
/**
|
|
@@ -55,7 +57,6 @@ export type GL = EventState<{
|
|
|
55
57
|
*/
|
|
56
58
|
_uniform?(key: string, value: Uniform, isMatrix?: boolean): GL
|
|
57
59
|
uniform(key: string, value: Uniform, isMatrix?: boolean): GL
|
|
58
|
-
uniform(node: NodeProxy): GL
|
|
59
60
|
uniform(target: { [key: string]: Uniform }): GL
|
|
60
61
|
_texture?(key: string, value: string): GL
|
|
61
62
|
texture(key: string, value: string): GL
|
|
@@ -63,6 +64,9 @@ export type GL = EventState<{
|
|
|
63
64
|
_attribute?(key: string, value: Attribute, iboValue?: Attribute): GL
|
|
64
65
|
attribute(key: string, value: Attribute, iboValue?: Attribute): GL
|
|
65
66
|
attribute(target: { [key: string]: Attribute }): GL
|
|
67
|
+
_instance?(key: string, value: Attribute, at?: number): GL
|
|
68
|
+
instance(key: string, value: Attribute, at?: number): GL
|
|
69
|
+
instance(target: { [key: string]: Attribute }): GL
|
|
66
70
|
_storage?(key: string, value: Storage): GL
|
|
67
71
|
storage(key: string, value: Storage): GL
|
|
68
72
|
storage(target: { [key: string]: Storage }): GL
|
|
@@ -95,6 +99,7 @@ export interface AttribData {
|
|
|
95
99
|
buffer: GPUBuffer
|
|
96
100
|
location: number
|
|
97
101
|
stride: number
|
|
102
|
+
isInstance?: boolean
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
export interface StorageData {
|
package/src/utils/helpers.ts
CHANGED
|
@@ -58,3 +58,59 @@ export const loadingImage = (gl: GL, src: string, fun: (source: HTMLImageElement
|
|
|
58
58
|
gl.loading--
|
|
59
59
|
})
|
|
60
60
|
}
|
|
61
|
+
|
|
62
|
+
const isValidStride = (stride: number) => [1, 2, 3, 4, 9, 16].includes(stride)
|
|
63
|
+
|
|
64
|
+
const calcStride = (arrayLength: number, count = 3) => {
|
|
65
|
+
if (arrayLength % count === 0) return Math.floor(arrayLength / count)
|
|
66
|
+
return -1
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const getStride = (arrayLength: number, count = 1, error = console.warn) => {
|
|
70
|
+
const ret = calcStride(arrayLength, count)
|
|
71
|
+
if (!isValidStride(ret))
|
|
72
|
+
error(
|
|
73
|
+
`glre attribute error: Invalid attribute length ${arrayLength}. Must divide by vertex count (${count}) with valid stride (1,2,3,4,9,16)`
|
|
74
|
+
)
|
|
75
|
+
return ret
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const GLSL_FS = /* cpp */ `
|
|
79
|
+
#version 300 es
|
|
80
|
+
precision mediump float;
|
|
81
|
+
out vec4 fragColor;
|
|
82
|
+
uniform vec2 iResolution;
|
|
83
|
+
void main() {
|
|
84
|
+
fragColor = vec4(fract((gl_FragCoord.xy / iResolution)), 0.0, 1.0);
|
|
85
|
+
}
|
|
86
|
+
`
|
|
87
|
+
|
|
88
|
+
export const GLSL_VS = /* cpp */ `
|
|
89
|
+
#version 300 es
|
|
90
|
+
void main() {
|
|
91
|
+
float x = float(gl_VertexID % 2) * 4.0 - 1.0;
|
|
92
|
+
float y = float(gl_VertexID / 2) * 4.0 - 1.0;
|
|
93
|
+
gl_Position = vec4(x, y, 0.0, 1.0);
|
|
94
|
+
}`
|
|
95
|
+
|
|
96
|
+
export const WGSL_VS = /* rust */ `
|
|
97
|
+
struct In { @builtin(vertex_index) vertex_index: u32 }
|
|
98
|
+
struct Out { @builtin(position) position: vec4f }
|
|
99
|
+
@vertex
|
|
100
|
+
fn main(in: In) -> Out {
|
|
101
|
+
var out: Out;
|
|
102
|
+
var x = f32(in.vertex_index % 2) * 4.0 - 1.0;
|
|
103
|
+
var y = f32(in.vertex_index / 2) * 4.0 - 1.0;
|
|
104
|
+
out.position = vec4f(x, y, 0.0, 1.0);
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
107
|
+
`.trim()
|
|
108
|
+
|
|
109
|
+
export const WGSL_FS = /* rust */ `
|
|
110
|
+
struct Out { @builtin(position) position: vec4f }
|
|
111
|
+
@group(0) @binding(0) var<uniform> iResolution: vec2f;
|
|
112
|
+
@fragment
|
|
113
|
+
fn main(out: Out) -> @location(0) vec4f {
|
|
114
|
+
return vec4f(fract((out.position.xy / iResolution)), 0.0, 1.0);
|
|
115
|
+
}
|
|
116
|
+
`
|
package/src/utils/pipeline.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isFloat32 } from './helpers'
|
|
1
|
+
import { is, isFloat32 } from './helpers'
|
|
2
2
|
import type { AttribData, TextureData, UniformData, StorageData } from '../types'
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -58,18 +58,21 @@ const getVertexFormat = (stride: number): GPUVertexFormat => {
|
|
|
58
58
|
return 'float32'
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
export const createVertexBuffers = (attribs: Iterable<AttribData>) => {
|
|
61
|
+
export const createVertexBuffers = (attribs: Iterable<AttribData & { isInstance?: boolean }>) => {
|
|
62
62
|
const vertexBuffers: GPUBuffer[] = []
|
|
63
63
|
const bufferLayouts: GPUVertexBufferLayout[] = []
|
|
64
|
-
for (const { buffer, location, stride } of attribs) {
|
|
64
|
+
for (const { buffer, location, stride, isInstance } of attribs) {
|
|
65
65
|
vertexBuffers[location] = buffer
|
|
66
|
+
const componentSize = Math.min(Math.max(Math.floor(stride), 1), 4)
|
|
67
|
+
const arrayStride = Math.max(4, Math.ceil((componentSize * 4) / 4) * 4)
|
|
66
68
|
bufferLayouts[location] = {
|
|
67
|
-
arrayStride
|
|
69
|
+
arrayStride,
|
|
70
|
+
stepMode: isInstance ? 'instance' : 'vertex',
|
|
68
71
|
attributes: [
|
|
69
72
|
{
|
|
70
73
|
shaderLocation: location,
|
|
71
74
|
offset: 0,
|
|
72
|
-
format: getVertexFormat(
|
|
75
|
+
format: getVertexFormat(componentSize),
|
|
73
76
|
},
|
|
74
77
|
],
|
|
75
78
|
}
|
|
@@ -118,12 +121,12 @@ export const createPipeline = (
|
|
|
118
121
|
) => {
|
|
119
122
|
return device.createRenderPipeline({
|
|
120
123
|
vertex: {
|
|
121
|
-
module: device.createShaderModule({ label: 'vert', code: vs }),
|
|
124
|
+
module: device.createShaderModule({ label: 'vert', code: vs.trim() }),
|
|
122
125
|
entryPoint: 'main',
|
|
123
126
|
buffers: bufferLayouts,
|
|
124
127
|
},
|
|
125
128
|
fragment: {
|
|
126
|
-
module: device.createShaderModule({ label: 'frag', code: fs }),
|
|
129
|
+
module: device.createShaderModule({ label: 'frag', code: fs.trim() }),
|
|
127
130
|
entryPoint: 'main',
|
|
128
131
|
targets: [{ format }],
|
|
129
132
|
},
|
|
@@ -140,7 +143,7 @@ export const createPipeline = (
|
|
|
140
143
|
export const createComputePipeline = (device: GPUDevice, bindGroupLayouts: GPUBindGroupLayout[], cs: string) => {
|
|
141
144
|
return device.createComputePipeline({
|
|
142
145
|
compute: {
|
|
143
|
-
module: device.createShaderModule({ label: 'compute', code: cs }),
|
|
146
|
+
module: device.createShaderModule({ label: 'compute', code: cs.trim() }),
|
|
144
147
|
entryPoint: 'main',
|
|
145
148
|
},
|
|
146
149
|
layout: device.createPipelineLayout({ bindGroupLayouts }),
|
|
@@ -203,3 +206,16 @@ export const createDepthTexture = (device: GPUDevice, width: number, height: num
|
|
|
203
206
|
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
204
207
|
})
|
|
205
208
|
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* utils
|
|
212
|
+
*/
|
|
213
|
+
export const workgroupCount = (particleCount: number | number[], workgroupSize = 32) => {
|
|
214
|
+
if (is.num(particleCount)) particleCount = [particleCount]
|
|
215
|
+
const [x, y = 1, z = 1] = particleCount
|
|
216
|
+
return {
|
|
217
|
+
x: Math.min((x * y * z) / workgroupSize, 65535),
|
|
218
|
+
y: 1,
|
|
219
|
+
z: 1,
|
|
220
|
+
}
|
|
221
|
+
}
|
package/src/utils/program.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { is } from './helpers'
|
|
2
2
|
import type { GL } from '../types'
|
|
3
3
|
|
|
4
|
-
const createShader = (c:
|
|
4
|
+
const createShader = (c: WebGL2RenderingContext, source: string, type: number, onError = console.warn) => {
|
|
5
5
|
const shader = c.createShader(type)
|
|
6
6
|
if (!shader) return onError('Failed to create shader')
|
|
7
7
|
c.shaderSource(shader, source.trim())
|
|
@@ -12,7 +12,7 @@ const createShader = (c: WebGLRenderingContext, source: string, type: number, on
|
|
|
12
12
|
onError(`Could not compile shader: ${error}\n\n↓↓↓generated↓↓↓\n${source}`)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export const createProgram = (c:
|
|
15
|
+
export const createProgram = (c: WebGL2RenderingContext, frag: string, vert: string, gl: GL) => {
|
|
16
16
|
const pg = c.createProgram()
|
|
17
17
|
const fs = createShader(c, frag, c.FRAGMENT_SHADER, gl.error)
|
|
18
18
|
const vs = createShader(c, vert, c.VERTEX_SHADER, gl.error)
|
|
@@ -26,45 +26,38 @@ export const createProgram = (c: WebGLRenderingContext, frag: string, vert: stri
|
|
|
26
26
|
gl.error(`Could not link program: ${error}`)
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
export const createArrayBuffer = (c: WebGL2RenderingContext, data: number[]) => {
|
|
30
|
+
const array = new Float32Array(data)
|
|
30
31
|
const buffer = c.createBuffer()
|
|
31
|
-
|
|
32
|
-
c.bufferData(c.ARRAY_BUFFER, new Float32Array(data), c.STATIC_DRAW)
|
|
33
|
-
c.bindBuffer(c.ARRAY_BUFFER, null)
|
|
34
|
-
return buffer
|
|
32
|
+
return { array, buffer }
|
|
35
33
|
}
|
|
36
34
|
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
export const setArrayBuffer = (
|
|
36
|
+
c: WebGL2RenderingContext,
|
|
37
|
+
array: Float32Array,
|
|
38
|
+
buffer: WebGLBuffer,
|
|
39
|
+
value: number[]
|
|
40
|
+
) => {
|
|
41
|
+
array.set(value)
|
|
42
|
+
c.bindBuffer(c.ARRAY_BUFFER, buffer)
|
|
43
|
+
c.bufferData(c.ARRAY_BUFFER, array, c.STATIC_DRAW)
|
|
44
|
+
c.bindBuffer(c.ARRAY_BUFFER, null)
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
export const updateAttrib = (c: WebGL2RenderingContext, loc: number, stride: number, buffer: WebGLBuffer) => {
|
|
48
|
+
c.bindBuffer(c.ARRAY_BUFFER, buffer)
|
|
49
|
+
c.enableVertexAttribArray(loc)
|
|
50
|
+
c.vertexAttribPointer(loc, stride, c.FLOAT, false, 0, 0)
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
export const
|
|
52
|
-
c
|
|
53
|
-
loc: number,
|
|
54
|
-
count: number,
|
|
55
|
-
value: number[],
|
|
56
|
-
iboValue: number[]
|
|
57
|
-
) => {
|
|
58
|
-
const vbo = createVbo(c, value)
|
|
59
|
-
const ibo = createIbo(c, iboValue)
|
|
60
|
-
const str = getStride(count, value, iboValue)
|
|
61
|
-
c.bindBuffer(c.ARRAY_BUFFER, vbo)
|
|
53
|
+
export const updateInstance = (c: WebGL2RenderingContext, loc: number, stride: number, buffer: WebGLBuffer) => {
|
|
54
|
+
c.bindBuffer(c.ARRAY_BUFFER, buffer)
|
|
62
55
|
c.enableVertexAttribArray(loc)
|
|
63
|
-
c.vertexAttribPointer(loc,
|
|
64
|
-
|
|
56
|
+
c.vertexAttribPointer(loc, stride, c.FLOAT, false, 0, 0)
|
|
57
|
+
c.vertexAttribDivisor(loc, 1) // divisor is 1
|
|
65
58
|
}
|
|
66
59
|
|
|
67
|
-
export const
|
|
60
|
+
export const updateUniform = (c: WebGL2RenderingContext, loc: WebGLUniformLocation, value: number | number[]) => {
|
|
68
61
|
if (is.num(value)) return c.uniform1f(loc, value)
|
|
69
62
|
let l = value.length
|
|
70
63
|
if (l <= 4) return c[`uniform${l as 2}fv`](loc, value)
|
|
@@ -72,7 +65,12 @@ export const createUniform = (c: WebGLRenderingContext, loc: WebGLUniformLocatio
|
|
|
72
65
|
c[`uniformMatrix${l as 2}fv`](loc, false, value)
|
|
73
66
|
}
|
|
74
67
|
|
|
75
|
-
export const createTexture = (
|
|
68
|
+
export const createTexture = (
|
|
69
|
+
c: WebGL2RenderingContext,
|
|
70
|
+
img: HTMLImageElement,
|
|
71
|
+
loc: WebGLUniformLocation,
|
|
72
|
+
unit: number
|
|
73
|
+
) => {
|
|
76
74
|
const texture = c.createTexture()
|
|
77
75
|
c.bindTexture(c.TEXTURE_2D, texture)
|
|
78
76
|
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, c.RGBA, c.UNSIGNED_BYTE, img)
|
|
@@ -98,28 +96,29 @@ interface TextureBuffer {
|
|
|
98
96
|
export const createStorage = (
|
|
99
97
|
c: WebGL2RenderingContext,
|
|
100
98
|
value: number[],
|
|
101
|
-
|
|
99
|
+
width: number,
|
|
100
|
+
height: number,
|
|
102
101
|
ping: TextureBuffer,
|
|
103
102
|
pong: TextureBuffer,
|
|
104
103
|
unit: number,
|
|
105
104
|
array: Float32Array
|
|
106
105
|
) => {
|
|
107
|
-
const
|
|
108
|
-
const vectorSize = value.length /
|
|
109
|
-
for (let i = 0; i <
|
|
106
|
+
const particleCount = width * height
|
|
107
|
+
const vectorSize = value.length / particleCount
|
|
108
|
+
for (let i = 0; i < particleCount; i++) {
|
|
110
109
|
for (let j = 0; j < Math.min(vectorSize, 4); j++) {
|
|
111
110
|
array[4 * i + j] = value[i * vectorSize + j] || 0
|
|
112
111
|
}
|
|
113
112
|
}
|
|
114
113
|
c.activeTexture(c.TEXTURE0 + unit)
|
|
115
114
|
c.bindTexture(c.TEXTURE_2D, ping.texture)
|
|
116
|
-
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA32F,
|
|
115
|
+
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA32F, width, height, 0, c.RGBA, c.FLOAT, array)
|
|
117
116
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MIN_FILTER, c.NEAREST)
|
|
118
117
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MAG_FILTER, c.NEAREST)
|
|
119
118
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_S, c.CLAMP_TO_EDGE)
|
|
120
119
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_T, c.CLAMP_TO_EDGE)
|
|
121
120
|
c.bindTexture(c.TEXTURE_2D, pong.texture)
|
|
122
|
-
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA32F,
|
|
121
|
+
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA32F, width, height, 0, c.RGBA, c.FLOAT, array)
|
|
123
122
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MIN_FILTER, c.NEAREST)
|
|
124
123
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MAG_FILTER, c.NEAREST)
|
|
125
124
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_S, c.CLAMP_TO_EDGE)
|
|
@@ -154,3 +153,28 @@ export const createAttachment = (
|
|
|
154
153
|
c.framebufferTexture2D(c.FRAMEBUFFER, attachment, c.TEXTURE_2D, o.texture, 0)
|
|
155
154
|
return attachment
|
|
156
155
|
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* utils
|
|
159
|
+
*/
|
|
160
|
+
export const storageSize = (particleCount: number | number[] = 1024) => {
|
|
161
|
+
if (is.num(particleCount)) {
|
|
162
|
+
const sqrt = Math.sqrt(particleCount)
|
|
163
|
+
const size = Math.ceil(sqrt)
|
|
164
|
+
if (!Number.isInteger(sqrt)) {
|
|
165
|
+
console.warn(
|
|
166
|
+
`GLRE Storage Warning: particleCount (${particleCount}) is not a square. Using ${size}x${size} texture may waste GPU memory. Consider using [width, height] format for optimal storage.`
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
return { x: size, y: size }
|
|
170
|
+
}
|
|
171
|
+
const [x, y, z] = particleCount
|
|
172
|
+
if (z !== undefined) {
|
|
173
|
+
const yz = y * z
|
|
174
|
+
console.warn(
|
|
175
|
+
`GLRE Storage Warning: 3D particleCount [${x}, ${y}, ${z}] specified but WebGL storage textures only support 2D. Flattening to 2D by multiplying height=${y} * depth=${z} = ${yz}.`
|
|
176
|
+
)
|
|
177
|
+
return { x, y: yz }
|
|
178
|
+
}
|
|
179
|
+
return { x, y }
|
|
180
|
+
}
|
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
import { nested as cached } from 'reev'
|
|
2
|
-
import { loadingImage } from './
|
|
2
|
+
import { is, loadingImage, getStride, GLSL_VS, GLSL_FS } from './helpers'
|
|
3
3
|
import {
|
|
4
|
+
createArrayBuffer,
|
|
4
5
|
cleanStorage,
|
|
5
6
|
createAttachment,
|
|
6
|
-
createAttrib,
|
|
7
7
|
createProgram,
|
|
8
8
|
createStorage,
|
|
9
9
|
createTexture,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
void main() {
|
|
18
|
-
float x = float(gl_VertexID % 2) * 4.0 - 1.0;
|
|
19
|
-
float y = float(gl_VertexID / 2) * 4.0 - 1.0;
|
|
20
|
-
gl_Position = vec4(x, y, 0.0, 1.0);
|
|
21
|
-
}`.trim()
|
|
10
|
+
setArrayBuffer,
|
|
11
|
+
storageSize,
|
|
12
|
+
updateAttrib,
|
|
13
|
+
updateInstance,
|
|
14
|
+
updateUniform,
|
|
15
|
+
} from './program'
|
|
16
|
+
import type { GL, WebGLState } from '../types'
|
|
22
17
|
|
|
23
18
|
const computeProgram = (gl: GL, c: WebGL2RenderingContext) => {
|
|
24
19
|
if (!gl.cs) return null // ignore if no compute shader
|
|
@@ -28,14 +23,13 @@ const computeProgram = (gl: GL, c: WebGL2RenderingContext) => {
|
|
|
28
23
|
let currentNum = 0 // for storage buffers
|
|
29
24
|
|
|
30
25
|
const units = cached(() => activeUnit++)
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
const size = Math.ceil(Math.sqrt(gl.particles))
|
|
26
|
+
const cs = is.str(gl.cs) ? gl.cs : gl.cs!.compute({ isWebGL: true, gl, units })
|
|
27
|
+
const pg = createProgram(c, cs, GLSL_VS, gl)!
|
|
28
|
+
const size = storageSize(gl.particleCount)
|
|
35
29
|
|
|
36
30
|
const uniforms = cached((key) => c.getUniformLocation(pg, key)!)
|
|
37
31
|
const storages = cached((key) => {
|
|
38
|
-
const array = new Float32Array(size * size * 4) // RGBA texture data
|
|
32
|
+
const array = new Float32Array(size.x * size.y * 4) // RGBA texture data
|
|
39
33
|
const ping = { texture: c.createTexture(), buffer: c.createFramebuffer() }
|
|
40
34
|
const pong = { texture: c.createTexture(), buffer: c.createFramebuffer() }
|
|
41
35
|
return { ping, pong, array, loc: uniforms(key), unit: units(key) }
|
|
@@ -43,12 +37,12 @@ const computeProgram = (gl: GL, c: WebGL2RenderingContext) => {
|
|
|
43
37
|
|
|
44
38
|
const _uniform = (key: string, value: number | number[]) => {
|
|
45
39
|
c.useProgram(pg)
|
|
46
|
-
|
|
40
|
+
updateUniform(c, uniforms(key), value)
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
const _storage = (key: string, value: number[]) => {
|
|
50
44
|
const { ping, pong, unit, array } = storages(key)
|
|
51
|
-
createStorage(c, value, size, ping, pong, unit, array)
|
|
45
|
+
createStorage(c, value, size.x, size.y, ping, pong, unit, array)
|
|
52
46
|
}
|
|
53
47
|
|
|
54
48
|
const clean = () => {
|
|
@@ -75,30 +69,45 @@ export const webgl = async (gl: GL) => {
|
|
|
75
69
|
const config = { isWebGL: true, gl }
|
|
76
70
|
const c = gl.el!.getContext('webgl2')!
|
|
77
71
|
const cp = computeProgram(gl, c)
|
|
78
|
-
const
|
|
72
|
+
const fs = gl.fs ? (is.str(gl.fs) ? gl.fs : gl.fs!.fragment(config)) : GLSL_FS
|
|
73
|
+
const vs = gl.vs ? (is.str(gl.vs) ? gl.vs : gl.vs!.vertex(config)) : GLSL_VS
|
|
74
|
+
const pg = createProgram(c, fs, vs, gl)!
|
|
79
75
|
c.useProgram(pg)
|
|
80
76
|
|
|
81
77
|
let activeUnit = 0 // for texture units
|
|
82
78
|
|
|
83
79
|
const units = cached(() => activeUnit++)
|
|
84
|
-
const attribs = cached((key) => c.getAttribLocation(pg, key))
|
|
85
80
|
const uniforms = cached((key) => c.getUniformLocation(pg, key))
|
|
86
81
|
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
|
|
82
|
+
const attribs = cached((key, value: number[], isInstance = false) => {
|
|
83
|
+
const stride = getStride(value.length, isInstance ? gl.instanceCount : gl.count, gl.error)
|
|
84
|
+
const location = c.getAttribLocation(pg, key)
|
|
85
|
+
const { array, buffer } = createArrayBuffer(c, value)
|
|
86
|
+
return { array, buffer, location, stride }
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const _attribute = (key = '', value: number[]) => {
|
|
90
|
+
const { array, buffer, location, stride } = attribs(key, value)
|
|
91
|
+
setArrayBuffer(c, array, buffer, value)
|
|
92
|
+
updateAttrib(c, location, stride, buffer)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const _instance = (key: string, value: number[]) => {
|
|
96
|
+
const { array, buffer, location, stride } = attribs(key, value, true)
|
|
97
|
+
setArrayBuffer(c, array, buffer, value)
|
|
98
|
+
updateInstance(c, location, stride, buffer)
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
const _uniform = (key: string, value: number | number[]) => {
|
|
93
102
|
c.useProgram(pg)
|
|
94
|
-
|
|
103
|
+
updateUniform(c, uniforms(key)!, value)
|
|
95
104
|
cp?._uniform(key, value)
|
|
96
105
|
}
|
|
97
106
|
|
|
98
107
|
const _texture = (key: string, src: string) => {
|
|
99
108
|
c.useProgram(pg)
|
|
100
109
|
loadingImage(gl, src, (source) => {
|
|
101
|
-
createTexture(c, source, uniforms(key)
|
|
110
|
+
createTexture(c, source, uniforms(key)!, units(key))
|
|
102
111
|
})
|
|
103
112
|
}
|
|
104
113
|
|
|
@@ -112,11 +121,18 @@ export const webgl = async (gl: GL) => {
|
|
|
112
121
|
cp?.render()
|
|
113
122
|
c.useProgram(pg)
|
|
114
123
|
c.viewport(0, 0, ...gl.size)
|
|
115
|
-
|
|
124
|
+
if (gl.instanceCount > 1) {
|
|
125
|
+
c.drawArraysInstanced(c.TRIANGLES, 0, gl.count, gl.instanceCount)
|
|
126
|
+
} else c.drawArrays(c.TRIANGLES, 0, gl.count)
|
|
116
127
|
c.bindFramebuffer(c.FRAMEBUFFER, null)
|
|
117
128
|
}
|
|
118
129
|
|
|
130
|
+
if (gl.isDepth) {
|
|
131
|
+
c.depthFunc(c.LEQUAL)
|
|
132
|
+
c.enable(c.CULL_FACE)
|
|
133
|
+
}
|
|
134
|
+
|
|
119
135
|
const webgl: WebGLState = { context: c, program: pg, storages: cp?.storages }
|
|
120
136
|
|
|
121
|
-
return { webgl, render, clean, _attribute, _uniform, _texture, _storage: cp?._storage }
|
|
137
|
+
return { webgl, render, clean, _attribute, _instance, _uniform, _texture, _storage: cp?._storage }
|
|
122
138
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { nested as cached } from 'reev'
|
|
2
|
-
import { is, loadingImage } from './
|
|
2
|
+
import { is, loadingImage, getStride, WGSL_FS, WGSL_VS } from './helpers'
|
|
3
3
|
import {
|
|
4
4
|
createArrayBuffer,
|
|
5
5
|
createBindGroup,
|
|
@@ -11,11 +11,9 @@ import {
|
|
|
11
11
|
createPipeline,
|
|
12
12
|
createTextureSampler,
|
|
13
13
|
createVertexBuffers,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
const WORKING_GROUP_SIZE = 32
|
|
14
|
+
workgroupCount,
|
|
15
|
+
} from './pipeline'
|
|
16
|
+
import type { GL, WebGPUState } from '../types'
|
|
19
17
|
|
|
20
18
|
const computeProgram = (gl: GL, device: GPUDevice, bindings: any) => {
|
|
21
19
|
let flush = (_pass: GPUComputePassEncoder) => {}
|
|
@@ -36,8 +34,8 @@ const computeProgram = (gl: GL, device: GPUDevice, bindings: any) => {
|
|
|
36
34
|
flush = (pass) => {
|
|
37
35
|
pass.setPipeline(pipeline)
|
|
38
36
|
bindGroups.forEach((v, i) => pass.setBindGroup(i, v))
|
|
39
|
-
const
|
|
40
|
-
pass.dispatchWorkgroups(
|
|
37
|
+
const { x, y, z } = workgroupCount(gl.particleCount)
|
|
38
|
+
pass.dispatchWorkgroups(x, y, z)
|
|
41
39
|
pass.end()
|
|
42
40
|
}
|
|
43
41
|
}
|
|
@@ -65,12 +63,12 @@ export const webgpu = async (gl: GL) => {
|
|
|
65
63
|
let needsUpdate = true
|
|
66
64
|
let depthTexture: GPUTexture
|
|
67
65
|
|
|
68
|
-
const attribs = cached((_key, value: number[]) => {
|
|
66
|
+
const attribs = cached((_key, value: number[], isInstance = false) => {
|
|
69
67
|
needsUpdate = true
|
|
70
|
-
const stride = value.length
|
|
68
|
+
const stride = getStride(value.length, isInstance ? gl.instanceCount : gl.count)
|
|
71
69
|
const { location } = bindings.attrib()
|
|
72
70
|
const { array, buffer } = createArrayBuffer(device, value, 'attrib')
|
|
73
|
-
return { array, buffer, location, stride }
|
|
71
|
+
return { array, buffer, location, stride, isInstance }
|
|
74
72
|
})
|
|
75
73
|
|
|
76
74
|
const uniforms = cached((_key, value: number[]) => {
|
|
@@ -89,13 +87,20 @@ export const webgpu = async (gl: GL) => {
|
|
|
89
87
|
|
|
90
88
|
const _attribute = (key = '', value: number[]) => {
|
|
91
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)
|
|
92
97
|
device.queue.writeBuffer(buffer, 0, array as any)
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
const _uniform = (key: string, value: number | number[]) => {
|
|
96
101
|
if (is.num(value)) value = [value]
|
|
97
102
|
const { array, buffer } = uniforms(key, value)
|
|
98
|
-
array.set(value)
|
|
103
|
+
array.set(value)
|
|
99
104
|
device.queue.writeBuffer(buffer, 0, array as any)
|
|
100
105
|
}
|
|
101
106
|
|
|
@@ -120,7 +125,7 @@ export const webgpu = async (gl: GL) => {
|
|
|
120
125
|
pass.setPipeline(pipeline)
|
|
121
126
|
bindGroups.forEach((v, i) => pass.setBindGroup(i, v))
|
|
122
127
|
vertexBuffers.forEach((v, i) => pass.setVertexBuffer(i, v))
|
|
123
|
-
pass.draw(gl.count,
|
|
128
|
+
pass.draw(gl.count, gl.instanceCount, 0, 0)
|
|
124
129
|
pass.end()
|
|
125
130
|
}
|
|
126
131
|
if (gl.cs) cp.update(bindGroups, bindGroupLayouts, comp)
|
|
@@ -129,9 +134,9 @@ export const webgpu = async (gl: GL) => {
|
|
|
129
134
|
const render = () => {
|
|
130
135
|
if (!frag || !vert) {
|
|
131
136
|
const config = { isWebGL: false, gl }
|
|
132
|
-
frag =
|
|
133
|
-
vert =
|
|
134
|
-
comp =
|
|
137
|
+
frag = gl.fs ? (is.str(gl.fs) ? gl.fs : gl.fs.fragment(config)) : WGSL_FS
|
|
138
|
+
vert = gl.vs ? (is.str(gl.vs) ? gl.vs : gl.vs.vertex(config)) : WGSL_VS
|
|
139
|
+
comp = gl.cs ? (is.str(gl.cs) ? gl.cs : gl.cs.compute(config)) : ''
|
|
135
140
|
}
|
|
136
141
|
if (gl.loading) return // MEMO: loading after build node
|
|
137
142
|
if (needsUpdate) update()
|
|
@@ -161,5 +166,5 @@ export const webgpu = async (gl: GL) => {
|
|
|
161
166
|
|
|
162
167
|
const webgpu = { device, uniforms, textures, attribs, storages: cp.storages } as WebGPUState
|
|
163
168
|
|
|
164
|
-
return { webgpu, render, resize, clean, _attribute, _uniform, _texture, _storage: cp._storage }
|
|
169
|
+
return { webgpu, render, resize, clean, _attribute, _instance, _uniform, _texture, _storage: cp._storage }
|
|
165
170
|
}
|