@thi.ng/webgl 6.6.11 → 6.6.13

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/multipass.js CHANGED
@@ -17,157 +17,166 @@ import { defQuadModel } from "./geo/quad.js";
17
17
  import { defShader } from "./shader.js";
18
18
  import { PASSTHROUGH_VS } from "./shaders/pipeline.js";
19
19
  import { defTexture } from "./texture.js";
20
- export const defMultiPass = (opts) => {
21
- const gl = opts.gl;
22
- const numPasses = opts.passes.length;
23
- assert(numPasses > 0, "require at least one shader pass");
24
- const useMainBuffer = !opts.passes[numPasses - 1].outputs.length;
25
- const textures = initTextures(opts);
26
- const passes = initPasses(opts, textures);
27
- const fbos = initBuffers(opts, textures, useMainBuffer);
28
- const drawPass = (i, time, isFBO = true) => {
29
- isFBO && fbos[i].bind();
30
- const spec = opts.passes[i];
31
- const pass = passes[i];
32
- const shader = pass.shader;
33
- const size = spec.outputs.length
34
- ? textures[spec.outputs[0]].size
35
- : [gl.drawingBufferWidth, gl.drawingBufferHeight];
36
- shader.uniforms.resolution && (pass.uniforms.resolution = size);
37
- shader.uniforms.time && (pass.uniforms.time = time);
38
- gl.viewport(0, 0, size[0], size[1]);
39
- draw(pass);
40
- isFBO && fbos[i].unbind();
41
- };
42
- const update = (time) => {
43
- for (let i = 0; i < fbos.length; i++) {
44
- drawPass(i, time);
45
- }
46
- useMainBuffer && drawPass(numPasses - 1, time, false);
47
- };
48
- const updateRAF = () => {
49
- update((Date.now() - t0) * 1e-3);
50
- active && (rafID = requestAnimationFrame(updateRAF));
51
- };
52
- let active;
53
- let t0 = Date.now();
54
- let rafID;
55
- const instance = {
56
- start() {
57
- t0 = Date.now();
58
- active = true;
59
- rafID = requestAnimationFrame(updateRAF);
60
- },
61
- stop() {
62
- if (active) {
63
- active = false;
64
- cancelAnimationFrame(rafID);
65
- }
66
- },
67
- update(time) {
68
- update(time);
69
- },
70
- singlePass(i, time) {
71
- drawPass(i, time, i < fbos.length);
72
- },
73
- passes: opts.passes,
74
- fbos,
75
- models: passes,
76
- textures,
77
- };
78
- return instance;
20
+ const defMultiPass = (opts) => {
21
+ const gl = opts.gl;
22
+ const numPasses = opts.passes.length;
23
+ assert(numPasses > 0, "require at least one shader pass");
24
+ const useMainBuffer = !opts.passes[numPasses - 1].outputs.length;
25
+ const textures = initTextures(opts);
26
+ const passes = initPasses(opts, textures);
27
+ const fbos = initBuffers(opts, textures, useMainBuffer);
28
+ const drawPass = (i, time, isFBO = true) => {
29
+ isFBO && fbos[i].bind();
30
+ const spec = opts.passes[i];
31
+ const pass = passes[i];
32
+ const shader = pass.shader;
33
+ const size = spec.outputs.length ? textures[spec.outputs[0]].size : [gl.drawingBufferWidth, gl.drawingBufferHeight];
34
+ shader.uniforms.resolution && (pass.uniforms.resolution = size);
35
+ shader.uniforms.time && (pass.uniforms.time = time);
36
+ gl.viewport(0, 0, size[0], size[1]);
37
+ draw(pass);
38
+ isFBO && fbos[i].unbind();
39
+ };
40
+ const update = (time) => {
41
+ for (let i = 0; i < fbos.length; i++) {
42
+ drawPass(i, time);
43
+ }
44
+ useMainBuffer && drawPass(numPasses - 1, time, false);
45
+ };
46
+ const updateRAF = () => {
47
+ update((Date.now() - t0) * 1e-3);
48
+ active && (rafID = requestAnimationFrame(updateRAF));
49
+ };
50
+ let active;
51
+ let t0 = Date.now();
52
+ let rafID;
53
+ const instance = {
54
+ start() {
55
+ t0 = Date.now();
56
+ active = true;
57
+ rafID = requestAnimationFrame(updateRAF);
58
+ },
59
+ stop() {
60
+ if (active) {
61
+ active = false;
62
+ cancelAnimationFrame(rafID);
63
+ }
64
+ },
65
+ update(time) {
66
+ update(time);
67
+ },
68
+ singlePass(i, time) {
69
+ drawPass(i, time, i < fbos.length);
70
+ },
71
+ passes: opts.passes,
72
+ fbos,
73
+ models: passes,
74
+ textures
75
+ };
76
+ return instance;
79
77
  };
80
78
  const initPasses = (opts, textures) => {
81
- const gl = opts.gl;
82
- const model = compileModel(gl, defQuadModel({ uv: false }));
83
- return opts.passes.map((pass) => {
84
- const m = pass.model ? compileModel(gl, pass.model) : { ...model };
85
- m.shader = initShader(gl, pass, textures);
86
- m.uniforms = { ...pass.uniformVals };
87
- pass.inputs.length > 0 &&
88
- (m.textures = pass.inputs.map((id) => textures[id]));
89
- return m;
90
- });
79
+ const gl = opts.gl;
80
+ const model = compileModel(gl, defQuadModel({ uv: false }));
81
+ return opts.passes.map((pass) => {
82
+ const m = pass.model ? compileModel(gl, pass.model) : { ...model };
83
+ m.shader = initShader(gl, pass, textures);
84
+ m.uniforms = { ...pass.uniformVals };
85
+ pass.inputs.length > 0 && (m.textures = pass.inputs.map((id) => textures[id]));
86
+ return m;
87
+ });
91
88
  };
92
89
  const initShader = (gl, pass, textures) => {
93
- const isGL2 = isGL2Context(gl);
94
- const numIns = pass.inputs.length;
95
- const numOuts = pass.outputs.length;
96
- const ext = {};
97
- const spec = {
98
- vs: pass.vs || PASSTHROUGH_VS,
99
- fs: pass.fs,
100
- attribs: pass.attribs || {
101
- position: "vec2",
102
- },
103
- varying: pass.varying,
104
- uniforms: {
105
- ...pass.uniforms,
106
- ...transduce(map((i) => [`input${i}`, ["sampler2D", i]]), assocObj(), range(numIns)),
107
- },
108
- outputs: numOuts
109
- ? transduce(map((i) => [
110
- `output${i}`,
111
- ["vec4", i],
112
- ]), assocObj(), range(numOuts))
113
- : undefined,
114
- state: pass.state,
115
- pre: pass.pre,
116
- post: pass.post,
117
- replacePrelude: pass.replacePrelude,
118
- generateDecls: pass.generateDecls,
119
- ext,
120
- };
121
- const floatIn = some((id) => isFloatTexture(textures[id]), pass.inputs);
122
- const floatOut = some((id) => isFloatTexture(textures[id]), pass.outputs);
123
- if (!isGL2) {
124
- floatIn && (ext.OES_texture_float = "require");
125
- numOuts > 1 && (ext.WEBGL_draw_buffers = "require");
126
- }
127
- if (floatOut) {
128
- ext[isGL2 ? "EXT_color_buffer_float" : "WEBGL_color_buffer_float"] =
129
- "require";
130
- isGL2 && (ext["EXT_float_blend"] = "require");
131
- }
132
- return defShader(gl, spec);
90
+ const isGL2 = isGL2Context(gl);
91
+ const numIns = pass.inputs.length;
92
+ const numOuts = pass.outputs.length;
93
+ const ext = {};
94
+ const spec = {
95
+ vs: pass.vs || PASSTHROUGH_VS,
96
+ fs: pass.fs,
97
+ attribs: pass.attribs || {
98
+ position: "vec2"
99
+ },
100
+ varying: pass.varying,
101
+ uniforms: {
102
+ ...pass.uniforms,
103
+ ...transduce(
104
+ map(
105
+ (i) => [`input${i}`, ["sampler2D", i]]
106
+ ),
107
+ assocObj(),
108
+ range(numIns)
109
+ )
110
+ },
111
+ outputs: numOuts ? transduce(
112
+ map(
113
+ (i) => [
114
+ `output${i}`,
115
+ ["vec4", i]
116
+ ]
117
+ ),
118
+ assocObj(),
119
+ range(numOuts)
120
+ ) : void 0,
121
+ state: pass.state,
122
+ pre: pass.pre,
123
+ post: pass.post,
124
+ replacePrelude: pass.replacePrelude,
125
+ generateDecls: pass.generateDecls,
126
+ ext
127
+ };
128
+ const floatIn = some((id) => isFloatTexture(textures[id]), pass.inputs);
129
+ const floatOut = some((id) => isFloatTexture(textures[id]), pass.outputs);
130
+ if (!isGL2) {
131
+ floatIn && (ext.OES_texture_float = "require");
132
+ numOuts > 1 && (ext.WEBGL_draw_buffers = "require");
133
+ }
134
+ if (floatOut) {
135
+ ext[isGL2 ? "EXT_color_buffer_float" : "WEBGL_color_buffer_float"] = "require";
136
+ isGL2 && (ext["EXT_float_blend"] = "require");
137
+ }
138
+ return defShader(gl, spec);
133
139
  };
134
140
  const initTextures = (opts) => Object.keys(opts.textures).reduce((acc, id) => {
135
- acc[id] = defTexture(opts.gl, {
136
- width: opts.width,
137
- height: opts.height,
138
- filter: opts.gl.NEAREST,
139
- wrap: opts.gl.CLAMP_TO_EDGE,
140
- image: null,
141
- ...opts.textures[id],
142
- });
143
- return acc;
141
+ acc[id] = defTexture(opts.gl, {
142
+ width: opts.width,
143
+ height: opts.height,
144
+ filter: opts.gl.NEAREST,
145
+ wrap: opts.gl.CLAMP_TO_EDGE,
146
+ image: null,
147
+ ...opts.textures[id]
148
+ });
149
+ return acc;
144
150
  }, {});
145
- const initBuffers = (opts, textures, useMainBuffer) => (useMainBuffer
146
- ? opts.passes.slice(0, opts.passes.length - 1)
147
- : opts.passes).map((pass) => defFBO(opts.gl, { tex: pass.outputs.map((id) => textures[id]) }));
148
- /**
149
- * Returns a dynamically generated single pass spec ({@link PassOpts}) for use
150
- * within a larger multipass pipeline spec, and which copies given `src`
151
- * textures into their respective `dest` textures (e.g. for feedback purposes).
152
- *
153
- * @remarks
154
- * Both arrays must have same length. The first `src` texture is written to the
155
- * first `dest` tex, etc.
156
- *
157
- * WebGL2 only (uses `texelFetch()`)
158
- *
159
- * @param src -
160
- * @param dest -
161
- */
162
- export const passCopy = (src, dest) => {
163
- assert(src.length === dest.length, `require same number of in/out textures`);
164
- return {
165
- fs: (gl, unis, _, outs) => [
166
- defMain(() => [
167
- ...map((i) => assign(outs[`output${i}`], texelFetch(unis[`input${i}`], ivec2($xy(gl.gl_FragCoord)), INT0)), range(src.length)),
168
- ]),
169
- ],
170
- inputs: src,
171
- outputs: dest,
172
- };
151
+ const initBuffers = (opts, textures, useMainBuffer) => (useMainBuffer ? opts.passes.slice(0, opts.passes.length - 1) : opts.passes).map(
152
+ (pass) => defFBO(opts.gl, { tex: pass.outputs.map((id) => textures[id]) })
153
+ );
154
+ const passCopy = (src, dest) => {
155
+ assert(
156
+ src.length === dest.length,
157
+ `require same number of in/out textures`
158
+ );
159
+ return {
160
+ fs: (gl, unis, _, outs) => [
161
+ defMain(() => [
162
+ ...map(
163
+ (i) => assign(
164
+ outs[`output${i}`],
165
+ texelFetch(
166
+ unis[`input${i}`],
167
+ ivec2($xy(gl.gl_FragCoord)),
168
+ INT0
169
+ )
170
+ ),
171
+ range(src.length)
172
+ )
173
+ ])
174
+ ],
175
+ inputs: src,
176
+ outputs: dest
177
+ };
178
+ };
179
+ export {
180
+ defMultiPass,
181
+ passCopy
173
182
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/webgl",
3
- "version": "6.6.11",
3
+ "version": "6.6.13",
4
4
  "description": "WebGL & GLSL abstraction layer",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -28,7 +28,9 @@
28
28
  ],
29
29
  "license": "Apache-2.0",
30
30
  "scripts": {
31
- "build": "yarn clean && tsc --declaration",
31
+ "build": "yarn build:esbuild && yarn build:decl",
32
+ "build:decl": "tsc --declaration --emitDeclarationOnly",
33
+ "build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
32
34
  "clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc api geo shaders textures",
33
35
  "doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
34
36
  "doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
@@ -37,25 +39,26 @@
37
39
  "test": "bun test"
38
40
  },
39
41
  "dependencies": {
40
- "@thi.ng/adapt-dpi": "^2.2.27",
41
- "@thi.ng/api": "^8.9.11",
42
- "@thi.ng/associative": "^6.3.23",
43
- "@thi.ng/checks": "^3.4.11",
44
- "@thi.ng/equiv": "^2.1.36",
45
- "@thi.ng/errors": "^2.4.5",
46
- "@thi.ng/logger": "^2.0.1",
47
- "@thi.ng/matrices": "^2.2.12",
48
- "@thi.ng/memoize": "^3.1.45",
49
- "@thi.ng/pixel": "^5.0.3",
50
- "@thi.ng/shader-ast": "^0.12.84",
51
- "@thi.ng/shader-ast-glsl": "^0.4.84",
52
- "@thi.ng/shader-ast-stdlib": "^0.16.9",
53
- "@thi.ng/transducers": "^8.8.14",
54
- "@thi.ng/vector-pools": "^3.1.89",
55
- "@thi.ng/vectors": "^7.8.8"
42
+ "@thi.ng/adapt-dpi": "^2.2.28",
43
+ "@thi.ng/api": "^8.9.12",
44
+ "@thi.ng/associative": "^6.3.24",
45
+ "@thi.ng/checks": "^3.4.12",
46
+ "@thi.ng/equiv": "^2.1.37",
47
+ "@thi.ng/errors": "^2.4.6",
48
+ "@thi.ng/logger": "^2.0.2",
49
+ "@thi.ng/matrices": "^2.2.14",
50
+ "@thi.ng/memoize": "^3.1.46",
51
+ "@thi.ng/pixel": "^5.0.5",
52
+ "@thi.ng/shader-ast": "^0.12.85",
53
+ "@thi.ng/shader-ast-glsl": "^0.4.85",
54
+ "@thi.ng/shader-ast-stdlib": "^0.16.10",
55
+ "@thi.ng/transducers": "^8.8.15",
56
+ "@thi.ng/vector-pools": "^3.1.91",
57
+ "@thi.ng/vectors": "^7.8.10"
56
58
  },
57
59
  "devDependencies": {
58
60
  "@microsoft/api-extractor": "^7.38.3",
61
+ "esbuild": "^0.19.8",
59
62
  "rimraf": "^5.0.5",
60
63
  "tools": "^0.0.1",
61
64
  "typedoc": "^0.25.4",
@@ -217,5 +220,5 @@
217
220
  ],
218
221
  "year": 2014
219
222
  },
220
- "gitHead": "25f2ac8ff795a432a930119661b364d4d93b59a0\n"
223
+ "gitHead": "22e36fa838e5431d40165384918b395603bbd92f\n"
221
224
  }
package/rbo.js CHANGED
@@ -1,36 +1,45 @@
1
1
  import { error } from "./error.js";
2
- export class RBO {
3
- gl;
4
- buffer;
5
- format;
6
- width;
7
- height;
8
- constructor(gl, opts) {
9
- this.gl = gl;
10
- this.buffer = gl.createRenderbuffer() || error("error creating RBO");
11
- this.configure(opts);
12
- }
13
- bind() {
14
- this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.buffer);
15
- return true;
16
- }
17
- unbind() {
18
- this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null);
19
- return true;
20
- }
21
- release() {
22
- this.gl.deleteRenderbuffer(this.buffer);
23
- delete this.buffer;
24
- return true;
25
- }
26
- configure(opts, unbind = true) {
27
- const gl = this.gl;
28
- this.bind();
29
- this.format = opts.format || gl.DEPTH_COMPONENT16;
30
- this.width = opts.width;
31
- this.height = opts.height;
32
- gl.renderbufferStorage(gl.RENDERBUFFER, opts.format || gl.DEPTH_COMPONENT16, opts.width, opts.height);
33
- return unbind ? this.unbind() : true;
34
- }
2
+ class RBO {
3
+ gl;
4
+ buffer;
5
+ format;
6
+ width;
7
+ height;
8
+ constructor(gl, opts) {
9
+ this.gl = gl;
10
+ this.buffer = gl.createRenderbuffer() || error("error creating RBO");
11
+ this.configure(opts);
12
+ }
13
+ bind() {
14
+ this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.buffer);
15
+ return true;
16
+ }
17
+ unbind() {
18
+ this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null);
19
+ return true;
20
+ }
21
+ release() {
22
+ this.gl.deleteRenderbuffer(this.buffer);
23
+ delete this.buffer;
24
+ return true;
25
+ }
26
+ configure(opts, unbind = true) {
27
+ const gl = this.gl;
28
+ this.bind();
29
+ this.format = opts.format || gl.DEPTH_COMPONENT16;
30
+ this.width = opts.width;
31
+ this.height = opts.height;
32
+ gl.renderbufferStorage(
33
+ gl.RENDERBUFFER,
34
+ opts.format || gl.DEPTH_COMPONENT16,
35
+ opts.width,
36
+ opts.height
37
+ );
38
+ return unbind ? this.unbind() : true;
39
+ }
35
40
  }
36
- export const defRBO = (gl, opts) => new RBO(gl, opts);
41
+ const defRBO = (gl, opts) => new RBO(gl, opts);
42
+ export {
43
+ RBO,
44
+ defRBO
45
+ };
package/readpixels.js CHANGED
@@ -1,13 +1,17 @@
1
1
  import { FBO } from "./fbo.js";
2
- export const readPixels = (gl, x, y, w, h, format, type, out) => {
3
- gl.readPixels(x, y, w, h, format, type, out);
4
- return out;
2
+ const readPixels = (gl, x, y, w, h, format, type, out) => {
3
+ gl.readPixels(x, y, w, h, format, type, out);
4
+ return out;
5
5
  };
6
- export const readTexture = (gl, tex, format, type, out) => {
7
- const fbo = new FBO(gl, { tex: [tex] });
8
- fbo.bind();
9
- gl.readPixels(0, 0, tex.size[0], tex.size[1], format, type, out);
10
- fbo.unbind();
11
- fbo.release();
12
- return out;
6
+ const readTexture = (gl, tex, format, type, out) => {
7
+ const fbo = new FBO(gl, { tex: [tex] });
8
+ fbo.bind();
9
+ gl.readPixels(0, 0, tex.size[0], tex.size[1], format, type, out);
10
+ fbo.unbind();
11
+ fbo.release();
12
+ return out;
13
+ };
14
+ export {
15
+ readPixels,
16
+ readTexture
13
17
  };