glre 0.39.0 → 0.41.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 +1 -1
- package/dist/addons.cjs.map +1 -1
- package/dist/addons.d.ts +853 -22
- package/dist/addons.js +1 -1
- package/dist/addons.js.map +1 -1
- package/dist/index.cjs +8 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +47 -28
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/native.d.ts +60 -33
- package/dist/node.cjs +59 -30
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +39 -26
- package/dist/node.js +59 -30
- package/dist/node.js.map +1 -1
- package/dist/react.d.ts +47 -28
- package/dist/solid.d.ts +47 -28
- package/package.json +24 -24
- 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 -6
- 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 +5 -2
- package/src/node/build.ts +62 -52
- package/src/node/create.ts +3 -0
- package/src/node/index.ts +1 -2
- package/src/node/scope.ts +27 -25
- package/src/node/types.ts +16 -12
- package/src/node/utils/const.ts +12 -11
- package/src/node/utils/index.ts +15 -12
- package/src/node/utils/infer.ts +17 -6
- package/src/node/utils/parse.ts +37 -13
- package/src/node/utils/utils.ts +40 -22
- package/src/types.ts +13 -5
- package/src/utils/helpers.ts +80 -7
- package/src/utils/pipeline.ts +21 -5
- package/src/utils/program.ts +68 -42
- package/src/utils/webgl.ts +47 -37
- package/src/utils/webgpu.ts +30 -38
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)
|
|
@@ -73,15 +66,16 @@ export const createUniform = (c: WebGLRenderingContext, loc: WebGLUniformLocatio
|
|
|
73
66
|
}
|
|
74
67
|
|
|
75
68
|
export const createTexture = (
|
|
76
|
-
c:
|
|
77
|
-
|
|
69
|
+
c: WebGL2RenderingContext,
|
|
70
|
+
el: HTMLImageElement | HTMLVideoElement,
|
|
78
71
|
loc: WebGLUniformLocation,
|
|
79
|
-
unit: number
|
|
72
|
+
unit: number,
|
|
73
|
+
isVideo = false
|
|
80
74
|
) => {
|
|
81
75
|
const texture = c.createTexture()
|
|
82
76
|
c.bindTexture(c.TEXTURE_2D, texture)
|
|
83
|
-
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, c.RGBA, c.UNSIGNED_BYTE,
|
|
84
|
-
c.generateMipmap(c.TEXTURE_2D)
|
|
77
|
+
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, c.RGBA, c.UNSIGNED_BYTE, el)
|
|
78
|
+
if (!isVideo) c.generateMipmap(c.TEXTURE_2D)
|
|
85
79
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MIN_FILTER, c.LINEAR)
|
|
86
80
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MAG_FILTER, c.LINEAR)
|
|
87
81
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_S, c.CLAMP_TO_EDGE)
|
|
@@ -90,6 +84,12 @@ export const createTexture = (
|
|
|
90
84
|
c.uniform1i(loc, unit)
|
|
91
85
|
c.activeTexture(c.TEXTURE0 + unit)
|
|
92
86
|
c.bindTexture(c.TEXTURE_2D, texture)
|
|
87
|
+
if (isVideo)
|
|
88
|
+
return () => {
|
|
89
|
+
c.activeTexture(c.TEXTURE0 + unit)
|
|
90
|
+
c.bindTexture(c.TEXTURE_2D, texture)
|
|
91
|
+
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, c.RGBA, c.UNSIGNED_BYTE, el)
|
|
92
|
+
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/**
|
|
@@ -103,28 +103,29 @@ interface TextureBuffer {
|
|
|
103
103
|
export const createStorage = (
|
|
104
104
|
c: WebGL2RenderingContext,
|
|
105
105
|
value: number[],
|
|
106
|
-
|
|
106
|
+
width: number,
|
|
107
|
+
height: number,
|
|
107
108
|
ping: TextureBuffer,
|
|
108
109
|
pong: TextureBuffer,
|
|
109
110
|
unit: number,
|
|
110
111
|
array: Float32Array
|
|
111
112
|
) => {
|
|
112
|
-
const
|
|
113
|
-
const vectorSize = value.length /
|
|
114
|
-
for (let i = 0; i <
|
|
113
|
+
const particleCount = width * height
|
|
114
|
+
const vectorSize = value.length / particleCount
|
|
115
|
+
for (let i = 0; i < particleCount; i++) {
|
|
115
116
|
for (let j = 0; j < Math.min(vectorSize, 4); j++) {
|
|
116
117
|
array[4 * i + j] = value[i * vectorSize + j] || 0
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
120
|
c.activeTexture(c.TEXTURE0 + unit)
|
|
120
121
|
c.bindTexture(c.TEXTURE_2D, ping.texture)
|
|
121
|
-
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA32F,
|
|
122
|
+
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA32F, width, height, 0, c.RGBA, c.FLOAT, array)
|
|
122
123
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MIN_FILTER, c.NEAREST)
|
|
123
124
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MAG_FILTER, c.NEAREST)
|
|
124
125
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_S, c.CLAMP_TO_EDGE)
|
|
125
126
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_T, c.CLAMP_TO_EDGE)
|
|
126
127
|
c.bindTexture(c.TEXTURE_2D, pong.texture)
|
|
127
|
-
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA32F,
|
|
128
|
+
c.texImage2D(c.TEXTURE_2D, 0, c.RGBA32F, width, height, 0, c.RGBA, c.FLOAT, array)
|
|
128
129
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MIN_FILTER, c.NEAREST)
|
|
129
130
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MAG_FILTER, c.NEAREST)
|
|
130
131
|
c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_S, c.CLAMP_TO_EDGE)
|
|
@@ -159,3 +160,28 @@ export const createAttachment = (
|
|
|
159
160
|
c.framebufferTexture2D(c.FRAMEBUFFER, attachment, c.TEXTURE_2D, o.texture, 0)
|
|
160
161
|
return attachment
|
|
161
162
|
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* utils
|
|
166
|
+
*/
|
|
167
|
+
export const storageSize = (particleCount: number | number[] = 1024) => {
|
|
168
|
+
if (is.num(particleCount)) {
|
|
169
|
+
const sqrt = Math.sqrt(particleCount)
|
|
170
|
+
const size = Math.ceil(sqrt)
|
|
171
|
+
if (!Number.isInteger(sqrt)) {
|
|
172
|
+
console.warn(
|
|
173
|
+
`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.`
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
return { x: size, y: size }
|
|
177
|
+
}
|
|
178
|
+
const [x, y, z] = particleCount
|
|
179
|
+
if (z !== undefined) {
|
|
180
|
+
const yz = y * z
|
|
181
|
+
console.warn(
|
|
182
|
+
`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}.`
|
|
183
|
+
)
|
|
184
|
+
return { x, y: yz }
|
|
185
|
+
}
|
|
186
|
+
return { x, y }
|
|
187
|
+
}
|
package/src/utils/webgl.ts
CHANGED
|
@@ -1,34 +1,20 @@
|
|
|
1
1
|
import { nested as cached } from 'reev'
|
|
2
|
-
import { is,
|
|
2
|
+
import { is, getStride, GLSL_VS, GLSL_FS, loadingTexture } 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
|
-
|
|
10
|
+
setArrayBuffer,
|
|
11
|
+
storageSize,
|
|
12
|
+
updateAttrib,
|
|
13
|
+
updateInstance,
|
|
14
|
+
updateUniform,
|
|
11
15
|
} from './program'
|
|
12
16
|
import type { GL, WebGLState } from '../types'
|
|
13
17
|
|
|
14
|
-
const DEFAULT_FRAGMENT = /* cpp */ `
|
|
15
|
-
#version 300 es
|
|
16
|
-
precision mediump float;
|
|
17
|
-
out vec4 fragColor;
|
|
18
|
-
uniform vec2 iResolution;
|
|
19
|
-
void main() {
|
|
20
|
-
fragColor = vec4(fract((gl_FragCoord.xy / iResolution)), 0.0, 1.0);
|
|
21
|
-
}
|
|
22
|
-
`
|
|
23
|
-
|
|
24
|
-
const DEFAULT_VERTEX = /* cpp */ `
|
|
25
|
-
#version 300 es
|
|
26
|
-
void main() {
|
|
27
|
-
float x = float(gl_VertexID % 2) * 4.0 - 1.0;
|
|
28
|
-
float y = float(gl_VertexID / 2) * 4.0 - 1.0;
|
|
29
|
-
gl_Position = vec4(x, y, 0.0, 1.0);
|
|
30
|
-
}`
|
|
31
|
-
|
|
32
18
|
const computeProgram = (gl: GL, c: WebGL2RenderingContext) => {
|
|
33
19
|
if (!gl.cs) return null // ignore if no compute shader
|
|
34
20
|
c.getExtension('EXT_color_buffer_float')
|
|
@@ -38,12 +24,12 @@ const computeProgram = (gl: GL, c: WebGL2RenderingContext) => {
|
|
|
38
24
|
|
|
39
25
|
const units = cached(() => activeUnit++)
|
|
40
26
|
const cs = is.str(gl.cs) ? gl.cs : gl.cs!.compute({ isWebGL: true, gl, units })
|
|
41
|
-
const pg = createProgram(c, cs,
|
|
42
|
-
const size =
|
|
27
|
+
const pg = createProgram(c, cs, GLSL_VS, gl)!
|
|
28
|
+
const size = storageSize(gl.particleCount)
|
|
43
29
|
|
|
44
30
|
const uniforms = cached((key) => c.getUniformLocation(pg, key)!)
|
|
45
31
|
const storages = cached((key) => {
|
|
46
|
-
const array = new Float32Array(size * size * 4) // RGBA texture data
|
|
32
|
+
const array = new Float32Array(size.x * size.y * 4) // RGBA texture data
|
|
47
33
|
const ping = { texture: c.createTexture(), buffer: c.createFramebuffer() }
|
|
48
34
|
const pong = { texture: c.createTexture(), buffer: c.createFramebuffer() }
|
|
49
35
|
return { ping, pong, array, loc: uniforms(key), unit: units(key) }
|
|
@@ -51,12 +37,12 @@ const computeProgram = (gl: GL, c: WebGL2RenderingContext) => {
|
|
|
51
37
|
|
|
52
38
|
const _uniform = (key: string, value: number | number[]) => {
|
|
53
39
|
c.useProgram(pg)
|
|
54
|
-
|
|
40
|
+
updateUniform(c, uniforms(key), value)
|
|
55
41
|
}
|
|
56
42
|
|
|
57
43
|
const _storage = (key: string, value: number[]) => {
|
|
58
44
|
const { ping, pong, unit, array } = storages(key)
|
|
59
|
-
createStorage(c, value, size, ping, pong, unit, array)
|
|
45
|
+
createStorage(c, value, size.x, size.y, ping, pong, unit, array)
|
|
60
46
|
}
|
|
61
47
|
|
|
62
48
|
const clean = () => {
|
|
@@ -83,32 +69,49 @@ export const webgl = async (gl: GL) => {
|
|
|
83
69
|
const config = { isWebGL: true, gl }
|
|
84
70
|
const c = gl.el!.getContext('webgl2')!
|
|
85
71
|
const cp = computeProgram(gl, c)
|
|
86
|
-
const fs = gl.fs ? (is.str(gl.fs) ? gl.fs : gl.fs!.fragment(config)) :
|
|
87
|
-
const vs = gl.vs ? (is.str(gl.vs) ? gl.vs : gl.vs!.vertex(config)) :
|
|
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
|
|
88
74
|
const pg = createProgram(c, fs, vs, gl)!
|
|
89
75
|
c.useProgram(pg)
|
|
90
76
|
|
|
91
77
|
let activeUnit = 0 // for texture units
|
|
92
78
|
|
|
93
79
|
const units = cached(() => activeUnit++)
|
|
94
|
-
const attribs = cached((key) => c.getAttribLocation(pg, key))
|
|
95
80
|
const uniforms = cached((key) => c.getUniformLocation(pg, key))
|
|
96
81
|
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
|
|
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)
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
const _uniform = (key: string, value: number | number[]) => {
|
|
103
102
|
c.useProgram(pg)
|
|
104
|
-
|
|
103
|
+
updateUniform(c, uniforms(key)!, value)
|
|
105
104
|
cp?._uniform(key, value)
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
const _texture = (key: string, src: string) => {
|
|
108
|
+
gl.loading++
|
|
109
109
|
c.useProgram(pg)
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
loadingTexture(src, (source, isVideo) => {
|
|
111
|
+
const unit = units(key)
|
|
112
|
+
const loop = createTexture(c, source, uniforms(key)!, unit, isVideo)
|
|
113
|
+
if (loop) gl({ loop })
|
|
114
|
+
gl.loading--
|
|
112
115
|
})
|
|
113
116
|
}
|
|
114
117
|
|
|
@@ -122,11 +125,18 @@ export const webgl = async (gl: GL) => {
|
|
|
122
125
|
cp?.render()
|
|
123
126
|
c.useProgram(pg)
|
|
124
127
|
c.viewport(0, 0, ...gl.size)
|
|
125
|
-
|
|
128
|
+
if (gl.instanceCount > 1) {
|
|
129
|
+
c.drawArraysInstanced(c.TRIANGLES, 0, gl.count, gl.instanceCount)
|
|
130
|
+
} else c.drawArrays(c.TRIANGLES, 0, gl.count)
|
|
126
131
|
c.bindFramebuffer(c.FRAMEBUFFER, null)
|
|
127
132
|
}
|
|
128
133
|
|
|
134
|
+
if (gl.isDepth) {
|
|
135
|
+
c.depthFunc(c.LEQUAL)
|
|
136
|
+
c.enable(c.CULL_FACE)
|
|
137
|
+
}
|
|
138
|
+
|
|
129
139
|
const webgl: WebGLState = { context: c, program: pg, storages: cp?.storages }
|
|
130
140
|
|
|
131
|
-
return { webgl, render, clean, _attribute, _uniform, _texture, _storage: cp?._storage }
|
|
141
|
+
return { webgl, render, clean, _attribute, _instance, _uniform, _texture, _storage: cp?._storage }
|
|
132
142
|
}
|
package/src/utils/webgpu.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { nested as cached } from 'reev'
|
|
2
|
-
import { is,
|
|
2
|
+
import { is, getStride, WGSL_FS, WGSL_VS, loadingTexture } from './helpers'
|
|
3
3
|
import {
|
|
4
4
|
createArrayBuffer,
|
|
5
5
|
createBindGroup,
|
|
@@ -11,33 +11,10 @@ import {
|
|
|
11
11
|
createPipeline,
|
|
12
12
|
createTextureSampler,
|
|
13
13
|
createVertexBuffers,
|
|
14
|
+
workgroupCount,
|
|
14
15
|
} from './pipeline'
|
|
15
16
|
import type { GL, WebGPUState } from '../types'
|
|
16
17
|
|
|
17
|
-
const WORKING_GROUP_SIZE = 32
|
|
18
|
-
|
|
19
|
-
const DEFAULT_VERTEX = /* rust */ `
|
|
20
|
-
struct In { @builtin(vertex_index) vertex_index: u32 }
|
|
21
|
-
struct Out { @builtin(position) position: vec4f }
|
|
22
|
-
@vertex
|
|
23
|
-
fn main(in: In) -> Out {
|
|
24
|
-
var out: Out;
|
|
25
|
-
var x = f32(in.vertex_index % 2) * 4.0 - 1.0;
|
|
26
|
-
var y = f32(in.vertex_index / 2) * 4.0 - 1.0;
|
|
27
|
-
out.position = vec4f(x, y, 0.0, 1.0);
|
|
28
|
-
return out;
|
|
29
|
-
}
|
|
30
|
-
`.trim()
|
|
31
|
-
|
|
32
|
-
const DEFAULT_FRAGMENT = /* rust */ `
|
|
33
|
-
struct Out { @builtin(position) position: vec4f }
|
|
34
|
-
@group(0) @binding(0) var<uniform> iResolution: vec2f;
|
|
35
|
-
@fragment
|
|
36
|
-
fn main(out: Out) -> @location(0) vec4f {
|
|
37
|
-
return vec4f(fract((out.position.xy / iResolution)), 0.0, 1.0);
|
|
38
|
-
}
|
|
39
|
-
`
|
|
40
|
-
|
|
41
18
|
const computeProgram = (gl: GL, device: GPUDevice, bindings: any) => {
|
|
42
19
|
let flush = (_pass: GPUComputePassEncoder) => {}
|
|
43
20
|
|
|
@@ -57,8 +34,8 @@ const computeProgram = (gl: GL, device: GPUDevice, bindings: any) => {
|
|
|
57
34
|
flush = (pass) => {
|
|
58
35
|
pass.setPipeline(pipeline)
|
|
59
36
|
bindGroups.forEach((v, i) => pass.setBindGroup(i, v))
|
|
60
|
-
const
|
|
61
|
-
pass.dispatchWorkgroups(
|
|
37
|
+
const { x, y, z } = workgroupCount(gl.particleCount)
|
|
38
|
+
pass.dispatchWorkgroups(x, y, z)
|
|
62
39
|
pass.end()
|
|
63
40
|
}
|
|
64
41
|
}
|
|
@@ -86,12 +63,12 @@ export const webgpu = async (gl: GL) => {
|
|
|
86
63
|
let needsUpdate = true
|
|
87
64
|
let depthTexture: GPUTexture
|
|
88
65
|
|
|
89
|
-
const attribs = cached((_key, value: number[]) => {
|
|
66
|
+
const attribs = cached((_key, value: number[], isInstance = false) => {
|
|
90
67
|
needsUpdate = true
|
|
91
|
-
const stride = value.length
|
|
68
|
+
const stride = getStride(value.length, isInstance ? gl.instanceCount : gl.count)
|
|
92
69
|
const { location } = bindings.attrib()
|
|
93
70
|
const { array, buffer } = createArrayBuffer(device, value, 'attrib')
|
|
94
|
-
return { array, buffer, location, stride }
|
|
71
|
+
return { array, buffer, location, stride, isInstance }
|
|
95
72
|
})
|
|
96
73
|
|
|
97
74
|
const uniforms = cached((_key, value: number[]) => {
|
|
@@ -110,21 +87,36 @@ export const webgpu = async (gl: GL) => {
|
|
|
110
87
|
|
|
111
88
|
const _attribute = (key = '', value: number[]) => {
|
|
112
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)
|
|
113
97
|
device.queue.writeBuffer(buffer, 0, array as any)
|
|
114
98
|
}
|
|
115
99
|
|
|
116
100
|
const _uniform = (key: string, value: number | number[]) => {
|
|
117
101
|
if (is.num(value)) value = [value]
|
|
118
102
|
const { array, buffer } = uniforms(key, value)
|
|
119
|
-
array.set(value)
|
|
103
|
+
array.set(value)
|
|
120
104
|
device.queue.writeBuffer(buffer, 0, array as any)
|
|
121
105
|
}
|
|
122
106
|
|
|
123
107
|
const _texture = (key: string, src: string) => {
|
|
124
|
-
|
|
125
|
-
|
|
108
|
+
gl.loading++
|
|
109
|
+
loadingTexture(src, (source, isVideo) => {
|
|
110
|
+
const [width, height] = isVideo
|
|
111
|
+
? [source.videoWidth, source.videoHeight]
|
|
112
|
+
: [source.width, source.height]
|
|
126
113
|
const { texture } = textures(key, width, height)
|
|
127
|
-
|
|
114
|
+
const loop = () => {
|
|
115
|
+
device.queue.copyExternalImageToTexture({ source }, { texture }, { width, height })
|
|
116
|
+
}
|
|
117
|
+
loop()
|
|
118
|
+
if (isVideo) gl({ loop })
|
|
119
|
+
gl.loading--
|
|
128
120
|
})
|
|
129
121
|
}
|
|
130
122
|
|
|
@@ -141,7 +133,7 @@ export const webgpu = async (gl: GL) => {
|
|
|
141
133
|
pass.setPipeline(pipeline)
|
|
142
134
|
bindGroups.forEach((v, i) => pass.setBindGroup(i, v))
|
|
143
135
|
vertexBuffers.forEach((v, i) => pass.setVertexBuffer(i, v))
|
|
144
|
-
pass.draw(gl.count,
|
|
136
|
+
pass.draw(gl.count, gl.instanceCount, 0, 0)
|
|
145
137
|
pass.end()
|
|
146
138
|
}
|
|
147
139
|
if (gl.cs) cp.update(bindGroups, bindGroupLayouts, comp)
|
|
@@ -150,8 +142,8 @@ export const webgpu = async (gl: GL) => {
|
|
|
150
142
|
const render = () => {
|
|
151
143
|
if (!frag || !vert) {
|
|
152
144
|
const config = { isWebGL: false, gl }
|
|
153
|
-
frag = gl.fs ? (is.str(gl.fs) ? gl.fs : gl.fs.fragment(config)) :
|
|
154
|
-
vert = gl.vs ? (is.str(gl.vs) ? gl.vs : gl.vs.vertex(config)) :
|
|
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
|
|
155
147
|
comp = gl.cs ? (is.str(gl.cs) ? gl.cs : gl.cs.compute(config)) : ''
|
|
156
148
|
}
|
|
157
149
|
if (gl.loading) return // MEMO: loading after build node
|
|
@@ -182,5 +174,5 @@ export const webgpu = async (gl: GL) => {
|
|
|
182
174
|
|
|
183
175
|
const webgpu = { device, uniforms, textures, attribs, storages: cp.storages } as WebGPUState
|
|
184
176
|
|
|
185
|
-
return { webgpu, render, resize, clean, _attribute, _uniform, _texture, _storage: cp._storage }
|
|
177
|
+
return { webgpu, render, resize, clean, _attribute, _instance, _uniform, _texture, _storage: cp._storage }
|
|
186
178
|
}
|