├── .prettierignore
├── .gitmodules
├── examples
├── blursketch.js
├── blurtraceexample.html
├── hueexample.html
├── blurexample.html
├── inkyexample.html
├── colordistexample.html
├── instanceexample.html
├── mandalaexample.html
├── blurtracesketch.js
├── inkysketch.js
├── huesketch.js
├── colordistsketch.js
├── instancesketch.js
└── mandalasketch.js
├── LICENSE
├── README.md
├── p5extensions.js
└── post5.js
/.prettierignore:
--------------------------------------------------------------------------------
1 | everythingpass.js
2 | p5.js
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "postpre"]
2 | path = postpre
3 | url = https://github.com/bandaloo/postpre
4 | ignore = dirty
5 |
--------------------------------------------------------------------------------
/examples/blursketch.js:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | let black = false;
3 |
4 | function setup() {
5 | createCanvas(400, 400);
6 | addEffects(blur2d(2, 2, 13), motionBlur());
7 | addChannels(null);
8 | }
9 |
10 | function draw() {
11 | background(255);
12 | fill(255, 0, 0);
13 | noStroke();
14 | ellipse(mouseX, mouseY, 70, 70);
15 | }
16 |
--------------------------------------------------------------------------------
/examples/blurtraceexample.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | blur and trace
10 | use mouse to paint and click to change color
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/hueexample.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | hue shift
10 | use mouse to paint and click to change color
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/blurexample.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | types of blur
10 | move the mouse to move the circle around
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/inkyexample.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | inky sunbeams
10 | use mouse to paint and click to change color
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/colordistexample.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | types of blur
10 | move the mouse to move the circle around
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/instanceexample.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | instance mode
10 | use mouse to paint and click to change color
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/mandalaexample.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | mandala
10 | use mouse to paint and click to change color
11 | x position controls tracing color
12 | y position controls noisiness
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/blurtracesketch.js:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | let white = false;
3 |
4 | function setup() {
5 | createCanvas(400, 400);
6 | background(0);
7 | addEffects(blurAndTrace());
8 | addChannels(null);
9 | }
10 |
11 | function draw() {
12 | if (white) {
13 | fill(0);
14 | } else {
15 | fill(Math.random() * 255, Math.random() * 255, Math.random() * 255);
16 | }
17 | noStroke();
18 | ellipse(mouseX, mouseY, 20 + (r = 60 * Math.random()), 20 + r);
19 | }
20 |
21 | function mouseClicked() {
22 | white = !white;
23 | }
24 |
--------------------------------------------------------------------------------
/examples/inkysketch.js:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | let black = false;
3 |
4 | function setup() {
5 | createCanvas(400, 400);
6 | background(255);
7 | addEffects(
8 | noiseDisplacement(),
9 | godrays({ samplerNum: -1, lightPos: nMouse() }),
10 | oldFilm(),
11 | vignette()
12 | );
13 | }
14 |
15 | function draw() {
16 | const col = black ? 255 : 0;
17 | fill(col, col, col);
18 | noStroke();
19 | ellipse(mouseX, mouseY, 20 + (r = 60 * Math.random()), 20 + r);
20 | }
21 |
22 | function mouseClicked() {
23 | black = !black;
24 | }
25 |
--------------------------------------------------------------------------------
/examples/huesketch.js:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | let white = false;
3 |
4 | function setup() {
5 | createCanvas(400, 400);
6 | background(255);
7 | addEffects(
8 | noiseDisplacement(0.01, 0),
9 | hsvToRgb(changeComp(rgbToHsv(fColor()), getComp(nMouse(), "x"), "x", "+"))
10 | );
11 | }
12 |
13 | function draw() {
14 | if (white) {
15 | colorMode(RGB);
16 | fill(255, 255, 255);
17 | } else {
18 | colorMode(HSB, 100);
19 | fill(Math.random() * 100, 100, 100);
20 | }
21 | noStroke();
22 | ellipse(mouseX, mouseY, 20 + (r = 60 * Math.random()), 20 + r);
23 | }
24 |
25 | function mouseClicked() {
26 | white = !white;
27 | }
28 |
--------------------------------------------------------------------------------
/examples/colordistsketch.js:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | let white = false;
3 |
4 | function setup() {
5 | createCanvas(400, 400);
6 | background(255);
7 | addEffects(
8 | godrays({ samplerNum: -1, lightPos: nMouse(), density: 0.5 }),
9 | channel(
10 | -1,
11 | op(pos(), "+", op(get2Comp(fColor(), "rg"), "*", op(nMouse(), "-", 0.5)))
12 | )
13 | );
14 | }
15 |
16 | function draw() {
17 | if (white) {
18 | colorMode(RGB);
19 | fill(255, 255, 255);
20 | } else {
21 | colorMode(HSB, 100);
22 | fill(Math.random() * 100, 100, 100);
23 | }
24 | noStroke();
25 | ellipse(mouseX, mouseY, 20 + (r = 60 * Math.random()), 20 + r);
26 | }
27 |
28 | function mouseClicked() {
29 | white = !white;
30 | }
31 |
--------------------------------------------------------------------------------
/examples/instancesketch.js:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | new p5(function (sketch) {
3 | sketch.black = false;
4 |
5 | sketch.setup = () => {
6 | const c = sketch.createCanvas(400, 400);
7 | sketch.background(255);
8 | sketch.addEffects(
9 | sketch.noiseDisplacement(),
10 | sketch.godrays({ samplerNum: -1, lightPos: sketch.nMouse() }),
11 | sketch.oldFilm(),
12 | sketch.vignette()
13 | );
14 | };
15 |
16 | sketch.draw = () => {
17 | const col = sketch.black ? 255 : 0;
18 | sketch.fill(col, col, col);
19 | sketch.noStroke();
20 | sketch.ellipse(
21 | sketch.mouseX,
22 | sketch.mouseY,
23 | 20 + (r = 60 * Math.random()),
24 | 20 + r
25 | );
26 | };
27 |
28 | sketch.mouseClicked = () => {
29 | sketch.black = !sketch.black;
30 | };
31 | });
32 |
--------------------------------------------------------------------------------
/examples/mandalasketch.js:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | let black = false;
3 |
4 | function setup() {
5 | createCanvas(400, 400);
6 | background(0);
7 | const intensity = op(getComp(nMouse(), "y"), "*", 0.03);
8 | const tracing = op(op(getComp(nMouse(), "x"), "-", 0.5), "*", 2);
9 | addEffects(
10 | noiseDisplacement(0.05, 1, intensity),
11 | blurAndTrace(tracing, 2),
12 | kaleidoscope(),
13 | godrays({ samplerNum: -1, lightPos: nMouse(), density: 0.5 })
14 | );
15 | addChannels(null);
16 | }
17 |
18 | function draw() {
19 | if (black) {
20 | fill(0);
21 | } else {
22 | fill(Math.random() * 255, Math.random() * 255, Math.random() * 255);
23 | }
24 | noStroke();
25 | ellipse(mouseX, mouseY, 20 + (r = 60 * Math.random()), 20 + r);
26 | }
27 |
28 | function mouseClicked() {
29 | black = !black;
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2020 Cole Granof
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # post5
2 |
3 | post5 is a library for p5 that enables you to do interesting post-processing
4 | effects with the power of WebGL2. You can build it or download it from the
5 | "releases" section on the sidebar in GitHub. It wraps
6 | [merge-pass](https://github.com/bandaloo/merge-pass) and
7 | [postpre](https://github.com/bandaloo/postpre).
8 |
9 | Check out the
10 | [merge-pass live example](https://www.bandaloo.fun/merge-pass/example.html)
11 | and the [postpre live example](https://www.bandaloo.fun/postpre/example.html)
12 | to get an idea of how to nest and sequence these effects in interesting ways.
13 | Also check out the included examples in this repo or the examples
14 | [in the web editor](https://editor.p5js.org/bandaloo/collections/KKmpKHP-V).
15 |
16 | To get started, all you need to do is include the `post5.js` script after
17 | the `p5` script and before your sketch script:
18 |
19 | ```html
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | ```
30 |
31 | ## Mappings from merge-pass and postpre to post5
32 |
33 | This library is really just a thin wrapper for merge-pass and postpre.
34 | (Although the default arguments for the provided functions will get you
35 | pretty far, a number of things could be done to make this easier to use
36 | without TypeScript and the surrounding tooling.) As mentioned previously,
37 | check out the
38 | [merge-pass live example](https://www.bandaloo.fun/merge-pass/example.html)
39 | and the [postpre live example](https://www.bandaloo.fun/postpre/example.html)
40 | for examples on how to use this library. Below is a table to keep track of
41 | the mappings in post5; you want to use the names in the left column. Most are
42 | just changed to camelCase, but some names had to change totally due to naming
43 | conflicts with p5.
44 |
45 | | post5 | merge-pass/postpre |
46 | | ----------------- | ------------------ |
47 | | foggyRays | foggyrays |
48 | | vignette | vignette |
49 | | blurAndTrace | blurandtrace |
50 | | lightBands | lightbands |
51 | | noiseDisplacement | noisedisplacement |
52 | | oldFilm | oldfilm |
53 | | kaleidoscope | kaleidoscope |
54 | | effectLoop | loop |
55 | | gauss | gauss |
56 | | fColor | fcolor |
57 | | vec2 | vec2 |
58 | | vec3 | vec3 |
59 | | vec4 | vec4 |
60 | | pVec2 | pvec2 |
61 | | pVec3 | pvec3 |
62 | | pVec4 | pvec4 |
63 | | op | op |
64 | | blur2d | blur2d |
65 | | len | len |
66 | | normalize | norm |
67 | | pixel | pixel |
68 | | pos | pos |
69 | | center | center |
70 | | input | input |
71 | | bright | brightness |
72 | | contrast | contrast |
73 | | grain | grain |
74 | | getComp | getcomp |
75 | | get2Comp | get2comp |
76 | | get3Comp | get3comp |
77 | | get4Comp | get4comp |
78 | | changeComp | changecomp |
79 | | rgbToHsv | rgb2hsv |
80 | | hsvToRgb | hsv2rgb |
81 | | time | time |
82 | | a1 | a1 |
83 | | a2 | a2 |
84 | | fxaa | fxaa |
85 | | channel | channel |
86 | | depthOfField | dof |
87 | | trueDepth | truedepth |
88 | | godrays | godrays |
89 | | depthToOcclusion | depth2occlusion |
90 | | resolution | resolution |
91 | | mouse | mouse |
92 | | rotate2d | rotate |
93 | | translate2d | translate |
94 | | nMouse | nmouse |
95 | | perlin | perlin |
96 | | simplex | simplex |
97 | | motionBlur | motionblur |
98 | | randomFloat | random |
99 | | sobel | sobel |
100 | | bloom | bloom |
101 | | monochrome | monochrome |
102 | | invert | invert |
103 | | edge | edge |
104 | | edgeColor | edgecolor |
105 | | ternary | ternary |
106 | | region | region |
107 | | cFloat | cfloat |
108 | | cVec2 | cvec2 |
109 | | cVec3 | cvec3 |
110 | | cVec4 | cvec4 |
111 | | mut | mut |
112 | | basicFloat | float |
113 | | pFloat | pfloat |
114 | | tag | tag |
115 | | celShade | celshade |
116 |
117 | ## Building
118 |
119 | Run `sh build.sh`. This will automatically run `npm install` if
120 | `node_modules` does not exist in the postpre submodule and generate
121 | `post5.js`, which is the file you include as a script. Run `sh build.sh` to
122 | run postpre's `npm install` regardless.
123 |
--------------------------------------------------------------------------------
/p5extensions.js:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | {
3 | const addToProto = (pr, name, add) => {
4 | if (p5.prototype.hasOwnProperty(name)) {
5 | throw new Error("p5 already has this: " + name);
6 | }
7 | pr[name] = add;
8 | };
9 |
10 | const pr = p5.prototype;
11 | // this avoids collisions with names in p5 and changes to camelCase
12 | addToProto(pr, "foggyRays", MP.foggyrays);
13 | addToProto(pr, "vignette", MP.vignette);
14 | addToProto(pr, "blurAndTrace", MP.blurandtrace);
15 | addToProto(pr, "lightBands", MP.lightbands);
16 | addToProto(pr, "noiseDisplacement", MP.noisedisplacement);
17 | addToProto(pr, "oldFilm", MP.oldfilm);
18 | addToProto(pr, "kaleidoscope", MP.kaleidoscope);
19 | addToProto(pr, "effectLoop", MP.loop);
20 | addToProto(pr, "gauss", MP.gauss);
21 | addToProto(pr, "fColor", MP.fcolor);
22 | addToProto(pr, "vec2", MP.vec2);
23 | addToProto(pr, "vec3", MP.vec3);
24 | addToProto(pr, "vec4", MP.vec4);
25 | addToProto(pr, "pVec2", MP.pvec2);
26 | addToProto(pr, "pVec3", MP.pvec3);
27 | addToProto(pr, "pVec4", MP.pvec4);
28 | addToProto(pr, "op", MP.op);
29 | addToProto(pr, "blur2d", MP.blur2d);
30 | addToProto(pr, "len", MP.len);
31 | addToProto(pr, "normalize", MP.norm);
32 | addToProto(pr, "pixel", MP.pixel);
33 | addToProto(pr, "pos", MP.pos);
34 | addToProto(pr, "center", MP.center);
35 | addToProto(pr, "input", MP.input);
36 | addToProto(pr, "bright", MP.brightness);
37 | addToProto(pr, "contrast", MP.contrast);
38 | addToProto(pr, "grain", MP.grain);
39 | addToProto(pr, "getComp", MP.getcomp);
40 | addToProto(pr, "get2Comp", MP.get2comp);
41 | addToProto(pr, "get3Comp", MP.get3comp);
42 | addToProto(pr, "get4Comp", MP.get4comp);
43 | addToProto(pr, "changeComp", MP.changecomp);
44 | addToProto(pr, "rgbToHsv", MP.rgb2hsv);
45 | addToProto(pr, "hsvToRgb", MP.hsv2rgb);
46 | addToProto(pr, "time", MP.time);
47 | addToProto(pr, "a1", MP.a1);
48 | addToProto(pr, "a2", MP.a2);
49 | addToProto(pr, "fxaa", MP.fxaa);
50 | addToProto(pr, "channel", MP.channel);
51 | addToProto(pr, "depthOfField", MP.dof);
52 | addToProto(pr, "trueDepth", MP.truedepth);
53 | addToProto(pr, "godrays", MP.godrays);
54 | addToProto(pr, "depthToOcclusion", MP.depth2occlusion);
55 | addToProto(pr, "resolution", MP.resolution);
56 | addToProto(pr, "mouse", MP.mouse);
57 | addToProto(pr, "rotate2d", MP.rotate);
58 | addToProto(pr, "translate2d", MP.translate);
59 | addToProto(pr, "nMouse", MP.nmouse);
60 | addToProto(pr, "perlin", MP.perlin);
61 | addToProto(pr, "simplex", MP.simplex);
62 | addToProto(pr, "motionBlur", MP.motionblur);
63 | addToProto(pr, "randomFloat", MP.random);
64 | addToProto(pr, "sobel", MP.sobel);
65 | addToProto(pr, "bloom", MP.bloom);
66 | addToProto(pr, "monochrome", MP.monochrome);
67 | addToProto(pr, "invert", MP.invert);
68 | addToProto(pr, "edge", MP.edge);
69 | addToProto(pr, "edgeColor", MP.edgecolor);
70 | addToProto(pr, "ternary", MP.ternary);
71 | addToProto(pr, "region", MP.region);
72 | addToProto(pr, "cFloat", MP.cfloat);
73 | addToProto(pr, "cVec2", MP.cvec2);
74 | addToProto(pr, "cVec3", MP.cvec3);
75 | addToProto(pr, "cVec4", MP.cvec4);
76 | addToProto(pr, "mut", MP.mut);
77 | addToProto(pr, "basicFloat", MP.float);
78 | addToProto(pr, "pFloat", MP.pfloat);
79 | addToProto(pr, "tag", MP.tag);
80 | addToProto(pr, "celShade", MP.celshade);
81 |
82 | addToProto(pr, "__info", {
83 | replaced: false,
84 | orig: null,
85 | canvas: null,
86 | gl: null,
87 | verbosity: 0,
88 | startTime: 0,
89 | mousePos: { x: 0, y: 0 },
90 | effects: [],
91 | channels: [],
92 | });
93 |
94 | console.log(pr.__info);
95 |
96 | addToProto(pr, "addEffects", function () {
97 | pr.__info.effects.push(...arguments);
98 | });
99 |
100 | addToProto(pr, "addChannels", function () {
101 | pr.__info.channels.push(...arguments);
102 | });
103 |
104 | const info = p5.prototype.__info;
105 |
106 | function mpInit() {
107 | if (info.verbosity > 0) console.log("mp init");
108 | }
109 |
110 | function mpPre() {
111 | if (info.replaced || !info.effects) return;
112 | if (info.verbosity > 0) console.log("mp pre x1");
113 |
114 | info.startTime = new Date().getTime();
115 |
116 | info.orig = document.getElementById("defaultCanvas0");
117 |
118 | if (!info.orig) throw new Error("mergepass couldn't get the p5 canvas");
119 | const parent = info.orig.parentElement;
120 | parent.style.position = "relative";
121 |
122 | info.canvas = document.createElement("canvas");
123 |
124 | info.canvas.width = info.orig.width;
125 | info.canvas.height = info.orig.height;
126 | info.canvas.style.width = info.orig.style.width;
127 | info.canvas.style.height = info.orig.style.height;
128 |
129 | info.gl = info.canvas.getContext("webgl2");
130 | if (!info.gl) throw new Error("mergepass couldn't get the webgl2 context");
131 |
132 | parent.appendChild(info.canvas);
133 |
134 | info.merger = new MP.Merger(pr.__info.effects, info.orig, info.gl, {
135 | channels: pr.__info.channels,
136 | });
137 |
138 | const align = (c, z) => {
139 | c.style.position = "absolute";
140 | c.style.left = 0;
141 | c.style.top = 0;
142 | c.style.zIndex = z;
143 | };
144 |
145 | align(info.canvas, 0);
146 | align(info.orig, 1);
147 |
148 | info.orig.style.visibility = "hidden";
149 |
150 | info.canvas.addEventListener("mousemove", (e) => {
151 | const rect = info.orig.getBoundingClientRect();
152 | info.mousePos.x =
153 | (info.canvas.width * (e.clientX - rect.left)) / rect.width;
154 | info.mousePos.y =
155 | (info.canvas.height * (rect.height - (e.clientY - rect.top))) /
156 | rect.height;
157 | });
158 |
159 | info.replaced = true;
160 | }
161 |
162 | function mpPost() {
163 | if (info.verbosity > 1) console.log("mp post");
164 | if (!info.effects) return;
165 | const time = info.startTime - new Date().getTime();
166 | info.merger.draw(time / 1000, info.mousePos.x, info.mousePos.y);
167 | }
168 |
169 | p5.prototype.registerMethod("pre", mpPre);
170 | p5.prototype.registerMethod("init", mpInit);
171 | p5.prototype.registerMethod("post", mpPost);
172 | }
173 |
--------------------------------------------------------------------------------
/post5.js:
--------------------------------------------------------------------------------
1 | /* post5 0.1.0 | (c) 2020, Cole Granof | MIT License */
2 | // @ts-nocheck
3 | (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i merge_pass_1.simplex(merge_pass_1.op(merge_pass_1.op(merge_pass_1.changecomp(merge_pass_1.op(merge_pass_1.pos(), "/", periodFloat), merge_pass_1.op(merge_pass_1.time(), "*", speedFloat), comp, "+"), "*", merge_pass_1.op(merge_pass_1.resolution(), "/", merge_pass_1.getcomp(merge_pass_1.resolution(), "y"))), "+", comp === "x" ? X_OFF : Y_OFF));
249 | super(merge_pass_1.channel(-1, merge_pass_1.op(merge_pass_1.op(merge_pass_1.op(merge_pass_1.vec2(noise("x"), noise("y")), "*", intensityFloat), "*", merge_pass_1.op(merge_pass_1.get2comp(merge_pass_1.resolution(), "yx"), "/", merge_pass_1.getcomp(merge_pass_1.resolution(), "y"))), "+", merge_pass_1.pos())));
250 | this.periodFloat = periodFloat;
251 | this.speedFloat = speedFloat;
252 | this.intensityFloat = intensityFloat;
253 | this.period = period;
254 | this.speed = speed;
255 | this.intensity = intensity;
256 | }
257 | setPeriod(period) {
258 | this.periodFloat.setVal(merge_pass_1.wrapInValue(period));
259 | this.period = merge_pass_1.wrapInValue(period);
260 | }
261 | setSpeed(speed) {
262 | this.speedFloat.setVal(merge_pass_1.wrapInValue(speed));
263 | this.speed = merge_pass_1.wrapInValue(speed);
264 | }
265 | setIntensity(intensity) {
266 | this.intensityFloat.setVal(merge_pass_1.wrapInValue(intensity));
267 | this.speed = merge_pass_1.wrapInValue(intensity);
268 | }
269 | }
270 | exports.NoiseDisplacement = NoiseDisplacement;
271 | function noisedisplacement(period = merge_pass_1.mut(0.1), speed = merge_pass_1.mut(1), intensity = merge_pass_1.mut(0.005)) {
272 | return new NoiseDisplacement(merge_pass_1.wrapInValue(period), merge_pass_1.wrapInValue(speed), merge_pass_1.wrapInValue(intensity));
273 | }
274 | exports.noisedisplacement = noisedisplacement;
275 |
276 | },{"@bandaloo/merge-pass":62}],8:[function(require,module,exports){
277 | "use strict";
278 | Object.defineProperty(exports, "__esModule", { value: true });
279 | exports.oldfilm = exports.OldFilm = void 0;
280 | const merge_pass_1 = require("@bandaloo/merge-pass");
281 | class OldFilm extends merge_pass_1.WrappedExpr {
282 | constructor(speckIntensity, lineIntensity, grainIntensity) {
283 | const speckIntensityFloat = merge_pass_1.float(speckIntensity);
284 | const lineIntensityFloat = merge_pass_1.float(lineIntensity);
285 | const grainIntensityFloat = merge_pass_1.float(grainIntensity);
286 | const ftime = merge_pass_1.a1("floor", merge_pass_1.op(merge_pass_1.time(), "*", 24));
287 | const grainy = merge_pass_1.op(merge_pass_1.random(merge_pass_1.op(merge_pass_1.pixel(), "+", merge_pass_1.a2("mod", merge_pass_1.op(ftime, "*", 99), 3000))), "*", grainIntensityFloat);
288 | const rate = 10;
289 | const triangles = merge_pass_1.op(merge_pass_1.op(merge_pass_1.op(merge_pass_1.a1("abs", merge_pass_1.op(merge_pass_1.op(2, "*", merge_pass_1.a1("fract", merge_pass_1.op(rate, "*", merge_pass_1.getcomp(merge_pass_1.pos(), "x")))), "-", 1)), "-", 0.5), "*", 2), "*", lineIntensityFloat);
290 | const stepping = merge_pass_1.a2("step", merge_pass_1.op(1, "-", merge_pass_1.op(1, "/", rate * 12)), merge_pass_1.a2("mod", merge_pass_1.op(merge_pass_1.getcomp(merge_pass_1.pos(), "x"), "+", merge_pass_1.random(merge_pass_1.op(merge_pass_1.vec2(50, 50), "*", merge_pass_1.time()))), 1));
291 | const lines = merge_pass_1.op(triangles, "*", stepping);
292 | const spos = merge_pass_1.a2("mod", merge_pass_1.op(merge_pass_1.op(merge_pass_1.pos(), "*", merge_pass_1.op(merge_pass_1.resolution(), "/", merge_pass_1.getcomp(merge_pass_1.resolution(), "y"))), "+", ftime), merge_pass_1.vec2(100, 100));
293 | const fsimplex = merge_pass_1.op(merge_pass_1.op(merge_pass_1.simplex(merge_pass_1.op(spos, "*", 7)), "*", 0.44), "+", 0.5);
294 | const spots = merge_pass_1.op(merge_pass_1.a2("step", fsimplex, 0.08), "*", speckIntensityFloat);
295 | super(merge_pass_1.monochrome(merge_pass_1.brightness(spots, merge_pass_1.brightness(lines, merge_pass_1.brightness(grainy)))));
296 | this.speckIntensityFloat = speckIntensityFloat;
297 | this.lineIntensityFloat = lineIntensityFloat;
298 | this.grainIntensityFloat = grainIntensityFloat;
299 | this.speckIntensity = speckIntensity;
300 | this.lineIntensity = lineIntensity;
301 | this.grainIntensity = grainIntensity;
302 | }
303 | setSpeckIntensity(speckIntensity) {
304 | this.speckIntensityFloat.setVal(merge_pass_1.wrapInValue(speckIntensity));
305 | this.speckIntensity = merge_pass_1.wrapInValue(speckIntensity);
306 | }
307 | setLineIntensity(lineIntensity) {
308 | this.lineIntensityFloat.setVal(merge_pass_1.wrapInValue(lineIntensity));
309 | this.lineIntensity = merge_pass_1.wrapInValue(lineIntensity);
310 | }
311 | setGrainIntensity(grainIntensity) {
312 | this.grainIntensityFloat.setVal(merge_pass_1.wrapInValue(grainIntensity));
313 | this.grainIntensity = merge_pass_1.wrapInValue(grainIntensity);
314 | }
315 | }
316 | exports.OldFilm = OldFilm;
317 | function oldfilm(speckIntensity = merge_pass_1.mut(0.4), lineIntensity = merge_pass_1.mut(0.12), grainIntensity = merge_pass_1.mut(0.11)) {
318 | return new OldFilm(merge_pass_1.wrapInValue(speckIntensity), merge_pass_1.wrapInValue(lineIntensity), merge_pass_1.wrapInValue(grainIntensity));
319 | }
320 | exports.oldfilm = oldfilm;
321 |
322 | },{"@bandaloo/merge-pass":62}],9:[function(require,module,exports){
323 | "use strict";
324 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
325 | if (k2 === undefined) k2 = k;
326 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
327 | }) : (function(o, m, k, k2) {
328 | if (k2 === undefined) k2 = k;
329 | o[k2] = m[k];
330 | }));
331 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
332 | Object.defineProperty(o, "default", { enumerable: true, value: v });
333 | }) : function(o, v) {
334 | o["default"] = v;
335 | });
336 | var __importStar = (this && this.__importStar) || function (mod) {
337 | if (mod && mod.__esModule) return mod;
338 | var result = {};
339 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
340 | __setModuleDefault(result, mod);
341 | return result;
342 | };
343 | Object.defineProperty(exports, "__esModule", { value: true });
344 | // @ts-nocheck
345 | const postpre = __importStar(require("./index"));
346 | const mergepass = __importStar(require("@bandaloo/merge-pass"));
347 | window.MP = Object.assign({}, postpre, mergepass);
348 |
349 | },{"./index":4,"@bandaloo/merge-pass":62}],10:[function(require,module,exports){
350 | "use strict";
351 | Object.defineProperty(exports, "__esModule", { value: true });
352 | exports.vignette = exports.Vignette = void 0;
353 | const merge_pass_1 = require("@bandaloo/merge-pass");
354 | class Vignette extends merge_pass_1.EffectLoop {
355 | constructor(blurScalar, brightnessScalar, brightnessExponent) {
356 | const blurScalarFloat = merge_pass_1.float(blurScalar);
357 | const brightnessScalarFloat = merge_pass_1.float(brightnessScalar);
358 | const brightnessExponentFloat = merge_pass_1.float(brightnessExponent);
359 | const blurLen = merge_pass_1.op(merge_pass_1.len(merge_pass_1.center()), "*", blurScalarFloat);
360 | const blurExpr = merge_pass_1.blur2d(blurLen, blurLen);
361 | const brightLen = merge_pass_1.a2("pow", merge_pass_1.len(merge_pass_1.center()), brightnessExponentFloat);
362 | const brightExpr = merge_pass_1.brightness(merge_pass_1.op(brightLen, "*", merge_pass_1.op(brightnessScalarFloat, "*", -1)));
363 | super([blurExpr, brightExpr], { num: 1 });
364 | this.blurScalarFloat = blurScalarFloat;
365 | this.brightnessScalarFloat = brightnessScalarFloat;
366 | this.brightnessExponentFloat = brightnessExponentFloat;
367 | this.blurScalar = blurScalar;
368 | this.brightnessScalar = brightnessScalar;
369 | this.brightnessExponent = brightnessExponent;
370 | }
371 | setBlurScalar(blurScalar) {
372 | this.blurScalarFloat.setVal(merge_pass_1.wrapInValue(blurScalar));
373 | this.blurScalar = merge_pass_1.wrapInValue(blurScalar);
374 | }
375 | setBrightnessScalar(brightnessScalar) {
376 | this.brightnessScalarFloat.setVal(merge_pass_1.wrapInValue(brightnessScalar));
377 | this.brightnessScalar = merge_pass_1.wrapInValue(brightnessScalar);
378 | }
379 | setBrightnessExponent(brightnessExponent) {
380 | this.brightnessExponentFloat.setVal(merge_pass_1.wrapInValue(brightnessExponent));
381 | this.brightnessExponent = merge_pass_1.wrapInValue(brightnessExponent);
382 | }
383 | }
384 | exports.Vignette = Vignette;
385 | function vignette(blurScalar = merge_pass_1.mut(3), brightnessScalar = merge_pass_1.mut(1.8), brightnessExponent = merge_pass_1.mut(1.8)) {
386 | return new Vignette(merge_pass_1.wrapInValue(blurScalar), merge_pass_1.wrapInValue(brightnessScalar), merge_pass_1.wrapInValue(brightnessExponent));
387 | }
388 | exports.vignette = vignette;
389 |
390 | },{"@bandaloo/merge-pass":62}],11:[function(require,module,exports){
391 | "use strict";
392 | Object.defineProperty(exports, "__esModule", { value: true });
393 | exports.CodeBuilder = exports.channelSamplerName = void 0;
394 | const expr_1 = require("./exprs/expr");
395 | const webglprogramloop_1 = require("./webglprogramloop");
396 | const settings_1 = require("./settings");
397 | /** @ignore */
398 | const FRAG_SET = ` gl_FragColor = texture2D(uSampler, gl_FragCoord.xy / uResolution);\n`;
399 | /** @ignore */
400 | const SCENE_SET = `uniform sampler2D uSceneSampler;\n`;
401 | /** @ignore */
402 | const TIME_SET = `uniform mediump float uTime;\n`;
403 | /** @ignore */
404 | const MOUSE_SET = `uniform mediump vec2 uMouse;\n`;
405 | /** @ignore */
406 | const COUNT_SET = `uniform int uCount;\n`;
407 | /** @ignore */
408 | const BOILERPLATE = `#ifdef GL_ES
409 | precision mediump float;
410 | #endif
411 |
412 | uniform sampler2D uSampler;
413 | uniform mediump vec2 uResolution;\n`;
414 | /**
415 | * returns the string name of the sampler uniform for code generation purposes
416 | * @param num channel number to sample from
417 | */
418 | function channelSamplerName(num) {
419 | // texture 2 sampler has number 0 (0 and 1 are used for back buffer and scene)
420 | return num === -1 ? "uSampler" : `uBufferSampler${num}`;
421 | }
422 | exports.channelSamplerName = channelSamplerName;
423 | /**
424 | * returns the string of the declaration of the sampler for code generation
425 | * purposes
426 | * @param num channel number to sample from
427 | */
428 | function channelSamplerDeclaration(num) {
429 | return `uniform sampler2D ${channelSamplerName(num)};`;
430 | }
431 | /** class that manages generation and compilation of GLSL code */
432 | class CodeBuilder {
433 | constructor(effectLoop) {
434 | this.calls = [];
435 | this.externalFuncs = new Set();
436 | this.uniformDeclarations = new Set();
437 | this.counter = 0;
438 | this.baseLoop = effectLoop;
439 | const buildInfo = {
440 | uniformTypes: {},
441 | externalFuncs: new Set(),
442 | exprs: [],
443 | // update me on change to needs
444 | needs: {
445 | centerSample: false,
446 | neighborSample: false,
447 | sceneBuffer: false,
448 | timeUniform: false,
449 | mouseUniform: false,
450 | passCount: false,
451 | extraBuffers: new Set(),
452 | },
453 | };
454 | this.addEffectLoop(effectLoop, 1, buildInfo);
455 | // add all the types to uniform declarations from the `BuildInfo` instance
456 | for (const name in buildInfo.uniformTypes) {
457 | const typeName = buildInfo.uniformTypes[name];
458 | this.uniformDeclarations.add(`uniform mediump ${typeName} ${name};`);
459 | }
460 | // add all external functions from the `BuildInfo` instance
461 | buildInfo.externalFuncs.forEach((func) => this.externalFuncs.add(func));
462 | this.totalNeeds = buildInfo.needs;
463 | this.exprs = buildInfo.exprs;
464 | }
465 | addEffectLoop(effectLoop, indentLevel, buildInfo, topLevel = true) {
466 | const needsLoop = !topLevel && effectLoop.loopInfo.num > 1;
467 | if (needsLoop) {
468 | const iName = "i" + this.counter;
469 | indentLevel++;
470 | const forStart = " ".repeat(indentLevel - 1) +
471 | `for (int ${iName} = 0; ${iName} < ${effectLoop.loopInfo.num}; ${iName}++) {`;
472 | this.calls.push(forStart);
473 | }
474 | for (const e of effectLoop.effects) {
475 | if (e instanceof expr_1.Expr) {
476 | e.parse(buildInfo);
477 | this.calls.push(" ".repeat(indentLevel) + "gl_FragColor = " + e.sourceCode + ";");
478 | this.counter++;
479 | }
480 | else {
481 | this.addEffectLoop(e, indentLevel, buildInfo, false);
482 | }
483 | }
484 | if (needsLoop) {
485 | this.calls.push(" ".repeat(indentLevel - 1) + "}");
486 | }
487 | }
488 | /** generate the code and compile the program into a loop */
489 | compileProgram(gl, vShader, uniformLocs, shaders = []) {
490 | // set up the fragment shader
491 | const fShader = gl.createShader(gl.FRAGMENT_SHADER);
492 | if (fShader === null) {
493 | throw new Error("problem creating fragment shader");
494 | }
495 | const fullCode = BOILERPLATE +
496 | (this.totalNeeds.sceneBuffer ? SCENE_SET : "") +
497 | (this.totalNeeds.timeUniform ? TIME_SET : "") +
498 | (this.totalNeeds.mouseUniform ? MOUSE_SET : "") +
499 | (this.totalNeeds.passCount ? COUNT_SET : "") +
500 | Array.from(this.totalNeeds.extraBuffers)
501 | .map((n) => channelSamplerDeclaration(n))
502 | .join("\n") +
503 | "\n" +
504 | [...this.uniformDeclarations].join("\n") +
505 | "\n" +
506 | [...this.externalFuncs].join("\n") +
507 | "\n" +
508 | "void main() {\n" +
509 | (this.totalNeeds.centerSample ? FRAG_SET : "") +
510 | this.calls.join("\n") +
511 | "\n}";
512 | if (settings_1.settings.verbosity > 0)
513 | console.log(fullCode);
514 | gl.shaderSource(fShader, fullCode);
515 | gl.compileShader(fShader);
516 | // set up the program
517 | const program = gl.createProgram();
518 | if (program === null) {
519 | throw new Error("problem creating program");
520 | }
521 | gl.attachShader(program, vShader);
522 | gl.attachShader(program, fShader);
523 | shaders.push(fShader);
524 | const shaderLog = (name, shader) => {
525 | const output = gl.getShaderInfoLog(shader);
526 | if (output)
527 | console.log(`${name} shader info log\n${output}`);
528 | };
529 | shaderLog("vertex", vShader);
530 | shaderLog("fragment", fShader);
531 | gl.linkProgram(program);
532 | // we need to use the program here so we can get uniform locations
533 | gl.useProgram(program);
534 | // find all uniform locations and add them to the dictionary
535 | for (const expr of this.exprs) {
536 | for (const name in expr.uniformValChangeMap) {
537 | const location = gl.getUniformLocation(program, name);
538 | if (location === null) {
539 | throw new Error("couldn't find uniform " + name);
540 | }
541 | // TODO enforce unique names in the same program
542 | if (uniformLocs[name] === undefined) {
543 | uniformLocs[name] = { locs: [], counter: 0 };
544 | }
545 | // assign the name to the location
546 | uniformLocs[name].locs.push(location);
547 | }
548 | }
549 | // set the uniform resolution (every program has this uniform)
550 | const uResolution = gl.getUniformLocation(program, "uResolution");
551 | gl.uniform2f(uResolution, gl.drawingBufferWidth, gl.drawingBufferHeight);
552 | if (this.totalNeeds.sceneBuffer) {
553 | // TODO allow for texture options for scene texture
554 | const location = gl.getUniformLocation(program, "uSceneSampler");
555 | // put the scene buffer in texture 1 (0 is used for the backbuffer)
556 | gl.uniform1i(location, 1 + settings_1.settings.offset);
557 | }
558 | // set all sampler uniforms
559 | for (const b of this.totalNeeds.extraBuffers) {
560 | const location = gl.getUniformLocation(program, channelSamplerName(b));
561 | // offset the texture location by 2 (0 and 1 are used for scene and original)
562 | gl.uniform1i(location, b + 2 + settings_1.settings.offset);
563 | }
564 | // set the default sampler if there is an offset
565 | if (settings_1.settings.offset !== 0) {
566 | const location = gl.getUniformLocation(program, "uSampler");
567 | gl.uniform1i(location, settings_1.settings.offset);
568 | }
569 | // TODO do we need to do this every time?
570 | // get attribute
571 | const position = gl.getAttribLocation(program, "aPosition");
572 | // enable the attribute
573 | gl.enableVertexAttribArray(position);
574 | // points to the vertices in the last bound array buffer
575 | gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
576 | return new webglprogramloop_1.WebGLProgramLoop(new webglprogramloop_1.WebGLProgramLeaf(program, this.totalNeeds, this.exprs), this.baseLoop.loopInfo, gl);
577 | }
578 | }
579 | exports.CodeBuilder = CodeBuilder;
580 |
581 | },{"./exprs/expr":25,"./settings":64,"./webglprogramloop":66}],12:[function(require,module,exports){
582 | "use strict";
583 | Object.defineProperty(exports, "__esModule", { value: true });
584 | exports.a1 = exports.Arity1HomogenousExpr = void 0;
585 | const expr_1 = require("./expr");
586 | /** @ignore */
587 | function genArity1SourceList(name, val) {
588 | return {
589 | sections: [name + "(", ")"],
590 | values: [val],
591 | };
592 | }
593 | /** arity 1 homogenous function expression */
594 | class Arity1HomogenousExpr extends expr_1.Operator {
595 | constructor(val, operation) {
596 | super(val, genArity1SourceList(operation, val), ["uVal"]);
597 | this.val = val;
598 | }
599 | /** set the value being passed into the arity 1 homogenous function */
600 | setVal(val) {
601 | this.setUniform("uVal" + this.id, val);
602 | this.val = expr_1.wrapInValue(val);
603 | }
604 | }
605 | exports.Arity1HomogenousExpr = Arity1HomogenousExpr;
606 | /**
607 | * built-in functions that take in one `genType x` and return a `genType x`
608 | * @param name function name (see [[Arity1HomogenousName]] for valid function names)
609 | * @param val the `genType x` argument
610 | */
611 | function a1(name, val) {
612 | return new Arity1HomogenousExpr(expr_1.wrapInValue(val), name);
613 | }
614 | exports.a1 = a1;
615 |
616 | },{"./expr":25}],13:[function(require,module,exports){
617 | "use strict";
618 | Object.defineProperty(exports, "__esModule", { value: true });
619 | exports.a2 = exports.Arity2HomogenousExpr = void 0;
620 | const expr_1 = require("./expr");
621 | // note: glsl has atan(y/x) as well as atan(y, x)
622 | /** @ignore */
623 | function genArity1SourceList(name, val1, val2) {
624 | return {
625 | sections: [name + "(", ",", ")"],
626 | values: [val1, val2],
627 | };
628 | }
629 | /** arity 2 homogenous function expression */
630 | class Arity2HomogenousExpr extends expr_1.Operator {
631 | constructor(name, val1, val2) {
632 | super(val1, genArity1SourceList(name, val1, val2), ["uVal1", "uVal2"]);
633 | this.val1 = val1;
634 | this.val2 = val2;
635 | }
636 | /** set the first value being passed into the arity 2 homogenous function */
637 | setFirstVal(val1) {
638 | this.setUniform("uVal1" + this.id, val1);
639 | this.val1 = expr_1.wrapInValue(val1);
640 | }
641 | /** set the second value being passed into the arity 2 homogenous function */
642 | setSecondVal(val2) {
643 | this.setUniform("uVal2" + this.id, val2);
644 | this.val2 = expr_1.wrapInValue(val2);
645 | }
646 | }
647 | exports.Arity2HomogenousExpr = Arity2HomogenousExpr;
648 | // implementation
649 | /**
650 | * built-in functions that take in two `genType x` arguments and return a `genType x`
651 | * @param name function name (see [[Arity2HomogenousName]] for valid function names)
652 | * @param val1 the first `genType x` argument
653 | * @param val2 the second `genType x` argument
654 | */
655 | function a2(name, val1, val2) {
656 | return new Arity2HomogenousExpr(name, expr_1.wrapInValue(val1), expr_1.wrapInValue(val2));
657 | }
658 | exports.a2 = a2;
659 |
660 | },{"./expr":25}],14:[function(require,module,exports){
661 | "use strict";
662 | Object.defineProperty(exports, "__esModule", { value: true });
663 | exports.bloom = exports.BloomLoop = void 0;
664 | const mergepass_1 = require("../mergepass");
665 | const arity2_1 = require("./arity2");
666 | const blurexpr_1 = require("./blurexpr");
667 | const brightnessexpr_1 = require("./brightnessexpr");
668 | const channelsampleexpr_1 = require("./channelsampleexpr");
669 | const contrastexpr_1 = require("./contrastexpr");
670 | const expr_1 = require("./expr");
671 | const fragcolorexpr_1 = require("./fragcolorexpr");
672 | const opexpr_1 = require("./opexpr");
673 | const vecexprs_1 = require("./vecexprs");
674 | // TODO bloom uses `input` so it has to be the first
675 | // TODO maybe a way to update the scene buffer?
676 | /** bloom loop */
677 | class BloomLoop extends mergepass_1.EffectLoop {
678 | constructor(threshold = expr_1.float(expr_1.mut(0.4)), horizontal = expr_1.float(expr_1.mut(1)), vertical = expr_1.float(expr_1.mut(1)), boost = expr_1.float(expr_1.mut(1.3)), samplerNum = 1, taps = 9, reps = 3) {
679 | const bright = expr_1.cfloat(expr_1.tag `((${channelsampleexpr_1.channel(samplerNum)}.r + ${channelsampleexpr_1.channel(samplerNum)}.g + ${channelsampleexpr_1.channel(samplerNum)}.b) / 3.)`);
680 | const step = arity2_1.a2("step", bright, threshold);
681 | const col = expr_1.cvec4(expr_1.tag `vec4(${channelsampleexpr_1.channel(samplerNum)}.rgb * (1. - ${step}), 1.)`);
682 | const list = [
683 | mergepass_1.loop([col]).target(samplerNum),
684 | mergepass_1.loop([
685 | blurexpr_1.gauss(vecexprs_1.vec2(horizontal, 0), taps),
686 | blurexpr_1.gauss(vecexprs_1.vec2(0, vertical), taps),
687 | brightnessexpr_1.brightness(0.1),
688 | contrastexpr_1.contrast(boost),
689 | ], reps).target(samplerNum),
690 | opexpr_1.op(fragcolorexpr_1.fcolor(), "+", channelsampleexpr_1.channel(samplerNum)),
691 | ];
692 | super(list, { num: 1 });
693 | this.threshold = threshold;
694 | this.horizontal = horizontal;
695 | this.vertical = vertical;
696 | this.boost = boost;
697 | }
698 | /**
699 | * set the horizontal stretch of the blur effect (no greater than 1 for best
700 | * effect)
701 | */
702 | setHorizontal(num) {
703 | if (!(this.horizontal instanceof expr_1.BasicFloat))
704 | throw new Error("horizontal expression not basic float");
705 | this.horizontal.setVal(num);
706 | }
707 | /**
708 | * set the vertical stretch of the blur effect (no greater than 1 for best
709 | * effect)
710 | */
711 | setVertical(num) {
712 | if (!(this.vertical instanceof expr_1.BasicFloat))
713 | throw new Error("vertical expression not basic float");
714 | this.vertical.setVal(num);
715 | }
716 | /** set the treshold */
717 | setThreshold(num) {
718 | if (!(this.threshold instanceof expr_1.BasicFloat))
719 | throw new Error("threshold expression not basic float");
720 | this.threshold.setVal(num);
721 | }
722 | /** set the contrast boost */
723 | setBoost(num) {
724 | if (!(this.boost instanceof expr_1.BasicFloat))
725 | throw new Error("boost expression not basic float");
726 | this.boost.setVal(num);
727 | }
728 | }
729 | exports.BloomLoop = BloomLoop;
730 | /**
731 | * creates a bloom loop
732 | * @param threshold values below this brightness don't get blurred (0.4 is
733 | * about reasonable, which is also the default)
734 | * @param horizontal how much to blur vertically (defaults to 1 pixel)
735 | * @param vertical how much to blur horizontally (defaults to 1 pixel)
736 | * @param taps how many taps for the blur (defaults to 9)
737 | * @param reps how many times to loop the blur (defaults to 3)
738 | */
739 | function bloom(threshold, horizontal, vertical, boost, samplerNum, taps, reps) {
740 | return new BloomLoop(expr_1.wrapInValue(threshold), expr_1.wrapInValue(horizontal), expr_1.wrapInValue(vertical), expr_1.wrapInValue(boost), samplerNum, taps, reps);
741 | }
742 | exports.bloom = bloom;
743 |
744 | },{"../mergepass":63,"./arity2":13,"./blurexpr":16,"./brightnessexpr":17,"./channelsampleexpr":19,"./contrastexpr":20,"./expr":25,"./fragcolorexpr":26,"./opexpr":43,"./vecexprs":59}],15:[function(require,module,exports){
745 | "use strict";
746 | Object.defineProperty(exports, "__esModule", { value: true });
747 | exports.blur2d = exports.Blur2dLoop = void 0;
748 | const mergepass_1 = require("../mergepass");
749 | const blurexpr_1 = require("./blurexpr");
750 | const expr_1 = require("./expr");
751 | const vecexprs_1 = require("./vecexprs");
752 | /** 2D blur loop */
753 | class Blur2dLoop extends mergepass_1.EffectLoop {
754 | constructor(horizontal = expr_1.float(expr_1.mut(1)), vertical = expr_1.float(expr_1.mut(1)), reps = 2, taps, samplerNum) {
755 | const side = blurexpr_1.gauss(vecexprs_1.vec2(horizontal, 0), taps, samplerNum);
756 | const up = blurexpr_1.gauss(vecexprs_1.vec2(0, vertical), taps, samplerNum);
757 | super([side, up], { num: reps });
758 | this.horizontal = horizontal;
759 | this.vertical = vertical;
760 | }
761 | /**
762 | * set the horizontal stretch of the blur effect (no greater than 1 for best
763 | * effect)
764 | */
765 | setHorizontal(num) {
766 | if (!(this.horizontal instanceof expr_1.BasicFloat))
767 | throw new Error("horizontal expression not basic float");
768 | this.horizontal.setVal(num);
769 | }
770 | /**
771 | * set the vertical stretch of the blur effect (no greater than 1 for best
772 | * effect)
773 | */
774 | setVertical(num) {
775 | if (!(this.vertical instanceof expr_1.BasicFloat))
776 | throw new Error("vertical expression not basic float");
777 | this.vertical.setVal(num);
778 | }
779 | }
780 | exports.Blur2dLoop = Blur2dLoop;
781 | /**
782 | * creates a loop that runs a horizontal, then vertical gaussian blur (anything
783 | * more than 1 pixel in the horizontal or vertical direction will create a
784 | * ghosting effect, which is usually not desirable)
785 | * @param horizontalExpr float for the horizontal blur (1 pixel default)
786 | * @param verticalExpr float for the vertical blur (1 pixel default)
787 | * @param reps how many passes (defaults to 2)
788 | * @param taps how many taps (defaults to 5)
789 | * @param samplerNum change if you want to sample from a different channel and
790 | * the outer loop has a different target
791 | */
792 | function blur2d(horizontalExpr, verticalExpr, reps, taps, samplerNum) {
793 | return new Blur2dLoop(expr_1.wrapInValue(horizontalExpr), expr_1.wrapInValue(verticalExpr), reps, taps, samplerNum);
794 | }
795 | exports.blur2d = blur2d;
796 |
797 | },{"../mergepass":63,"./blurexpr":16,"./expr":25,"./vecexprs":59}],16:[function(require,module,exports){
798 | "use strict";
799 | Object.defineProperty(exports, "__esModule", { value: true });
800 | exports.gauss = exports.BlurExpr = void 0;
801 | const glslfunctions_1 = require("../glslfunctions");
802 | const expr_1 = require("./expr");
803 | /** @ignore */
804 | function genBlurSource(direction, taps) {
805 | return {
806 | sections: [`gauss${taps}(`, ")"],
807 | values: [direction],
808 | };
809 | }
810 | /** @ignore */
811 | function tapsToFuncSource(taps) {
812 | switch (taps) {
813 | case 5:
814 | return glslfunctions_1.glslFuncs.gauss5;
815 | case 9:
816 | return glslfunctions_1.glslFuncs.gauss9;
817 | case 13:
818 | return glslfunctions_1.glslFuncs.gauss13;
819 | }
820 | }
821 | /** gaussian blur expression */
822 | class BlurExpr extends expr_1.ExprVec4 {
823 | constructor(direction, taps = 5, samplerNum) {
824 | // this is already guaranteed by typescript, but creates helpful error for
825 | // use in gibber or anyone just using javascript
826 | if (![5, 9, 13].includes(taps)) {
827 | throw new Error("taps for gauss blur can only be 5, 9 or 13");
828 | }
829 | super(genBlurSource(direction, taps), ["uDirection"]);
830 | this.direction = direction;
831 | this.externalFuncs = [tapsToFuncSource(taps)];
832 | this.brandExprWithChannel(0, samplerNum);
833 | }
834 | /** set the blur direction (keep magnitude no greater than 1 for best effect) */
835 | setDirection(direction) {
836 | this.setUniform("uDirection" + this.id, direction);
837 | this.direction = direction;
838 | }
839 | }
840 | exports.BlurExpr = BlurExpr;
841 | /**
842 | * creates expression that performs one pass of a gaussian blur
843 | * @param direction direction to blur (keep magnitude less than or equal to 1
844 | * for best effect)
845 | * @param taps number of taps (defaults to 5)
846 | * @param samplerNum which channel to sample from (default 0)
847 | */
848 | function gauss(direction, taps = 5, samplerNum) {
849 | return new BlurExpr(direction, taps, samplerNum);
850 | }
851 | exports.gauss = gauss;
852 |
853 | },{"../glslfunctions":61,"./expr":25}],17:[function(require,module,exports){
854 | "use strict";
855 | Object.defineProperty(exports, "__esModule", { value: true });
856 | exports.brightness = exports.Brightness = void 0;
857 | const glslfunctions_1 = require("../glslfunctions");
858 | const expr_1 = require("./expr");
859 | const fragcolorexpr_1 = require("./fragcolorexpr");
860 | /** brightness expression */
861 | class Brightness extends expr_1.ExprVec4 {
862 | constructor(brightness, col = fragcolorexpr_1.fcolor()) {
863 | super(expr_1.tag `brightness(${brightness}, ${col})`, ["uBrightness", "uColor"]);
864 | this.brightness = brightness;
865 | this.externalFuncs = [glslfunctions_1.glslFuncs.brightness];
866 | }
867 | /** set the brightness (should probably be between -1 and 1) */
868 | setBrightness(brightness) {
869 | this.setUniform("uBrightness" + this.id, brightness);
870 | this.brightness = expr_1.wrapInValue(brightness);
871 | }
872 | }
873 | exports.Brightness = Brightness;
874 | /**
875 | * changes the brightness of a color
876 | * @param val float for how much to change the brightness by (should probably be
877 | * between -1 and 1)
878 | * @param col the color to increase the brightness of (defaults to current
879 | * fragment color)
880 | */
881 | function brightness(val, col) {
882 | return new Brightness(expr_1.wrapInValue(val), col);
883 | }
884 | exports.brightness = brightness;
885 |
886 | },{"../glslfunctions":61,"./expr":25,"./fragcolorexpr":26}],18:[function(require,module,exports){
887 | "use strict";
888 | Object.defineProperty(exports, "__esModule", { value: true });
889 | exports.changecomp = exports.ChangeCompExpr = void 0;
890 | const expr_1 = require("./expr");
891 | const getcompexpr_1 = require("./getcompexpr");
892 | /** @ignore */
893 | function getChangeFunc(typ, id, setter, comps, op = "") {
894 | return `${typ} changecomp_${id}(${typ} col, ${setter.typeString()} setter) {
895 | col.${comps} ${op}= setter;
896 | return col;
897 | }`;
898 | }
899 | /**
900 | * throws a runtime error if component access is not valid, and disallows
901 | * duplicate components because duplicate components can not be in a left
902 | * expression. (for example `v.xyx = vec3(1., 2., 3.)` is illegal, but `v1.xyz
903 | * = v2.xyx` is legal.) also checks for type errors such as `v1.xy = vec3(1.,
904 | * 2., 3.)`; the right hand side can only be a `vec2` if only two components
905 | * are supplied
906 | * @param comps component string
907 | * @param setter how the components are being changed
908 | * @param vec the vector where components are being accessed
909 | */
910 | function checkChangeComponents(comps, setter, vec) {
911 | // setter has different length than components
912 | if (comps.length !== getcompexpr_1.typeStringToLength(setter.typeString())) {
913 | throw new Error("components length must be equal to the target float/vec");
914 | }
915 | // duplicate components
916 | if (duplicateComponents(comps)) {
917 | throw new Error("duplicate components not allowed on left side");
918 | }
919 | // legal components
920 | getcompexpr_1.checkLegalComponents(comps, vec);
921 | }
922 | /** @ignore */
923 | function duplicateComponents(comps) {
924 | return new Set(comps.split("")).size !== comps.length;
925 | }
926 | /** change component expression */
927 | class ChangeCompExpr extends expr_1.Operator {
928 | constructor(vec, setter, comps, op) {
929 | checkChangeComponents(comps, setter, vec);
930 | // part of name of custom function
931 | const operation = op === "+"
932 | ? "plus"
933 | : op === "-"
934 | ? "minus"
935 | : op === "*"
936 | ? "mult"
937 | : op === "/"
938 | ? "div"
939 | : "assign";
940 | const suffix = `${vec.typeString()}_${setter.typeString()}_${comps}_${operation}`;
941 | super(vec, { sections: [`changecomp_${suffix}(`, ", ", ")"], values: [vec, setter] }, ["uOriginal", "uNew"]);
942 | this.originalVec = vec;
943 | this.newVal = setter;
944 | this.externalFuncs = [
945 | getChangeFunc(vec.typeString(), suffix, setter, comps, op),
946 | ];
947 | }
948 | /** set the original vector */
949 | setOriginal(originalVec) {
950 | this.setUniform("uOriginal" + this.id, originalVec);
951 | this.originalVec = originalVec;
952 | }
953 | /** set the neww vector */
954 | setNew(newVal) {
955 | this.setUniform("uNew" + this.id, newVal);
956 | this.newVal = expr_1.wrapInValue(newVal);
957 | }
958 | }
959 | exports.ChangeCompExpr = ChangeCompExpr;
960 | /**
961 | * change the components of a vector
962 | * @param vec the vector to augment components of
963 | * @param setter the vector (or float, if only one component is changed) for
964 | * how to change the components
965 | * @param comps string representing the components to change (e.g. `"xy"` or
966 | * `"r"` or `"stpq"`.)
967 | * @param op optionally perform an operation on the original component
968 | * (defaults to no operation, just assigning that component to a new value)
969 | */
970 | function changecomp(vec, setter, comps, op) {
971 | return new ChangeCompExpr(vec, expr_1.wrapInValue(setter), comps, op);
972 | }
973 | exports.changecomp = changecomp;
974 |
975 | },{"./expr":25,"./getcompexpr":30}],19:[function(require,module,exports){
976 | "use strict";
977 | Object.defineProperty(exports, "__esModule", { value: true });
978 | exports.channel = exports.ChannelSampleExpr = void 0;
979 | const codebuilder_1 = require("../codebuilder");
980 | const expr_1 = require("./expr");
981 | const normfragcoordexpr_1 = require("./normfragcoordexpr");
982 | const glslfunctions_1 = require("../glslfunctions");
983 | /** @ignore */
984 | function genChannelSampleSource(buf, coord) {
985 | return {
986 | sections: ["channel(", `, ${codebuilder_1.channelSamplerName(buf)})`],
987 | values: [coord],
988 | };
989 | }
990 | // TODO create a way to sample but not clamp by region
991 | /** channel sample expression */
992 | class ChannelSampleExpr extends expr_1.ExprVec4 {
993 | constructor(buf, coord = normfragcoordexpr_1.pos()) {
994 | super(genChannelSampleSource(buf, coord), ["uVec"]);
995 | this.coord = coord;
996 | this.externalFuncs = [glslfunctions_1.glslFuncs.channel];
997 | if (buf !== -1)
998 | this.needs.extraBuffers = new Set([buf]);
999 | else
1000 | this.needs.neighborSample = true;
1001 | }
1002 | setCoord(coord) {
1003 | this.setUniform("uVec", coord);
1004 | this.coord = coord;
1005 | }
1006 | }
1007 | exports.ChannelSampleExpr = ChannelSampleExpr;
1008 | /**
1009 | * creates an expression that samples from one of the user-defined channels.
1010 | * don't sample from the same channel that you are using [[target]] on in a
1011 | * loop, just use [[fcolor]]
1012 | * @param channel which channel to sample from
1013 | * @param vec where to sample the channel texture (defaults to the normalized
1014 | * frag coord)
1015 | */
1016 | function channel(channel, vec) {
1017 | return new ChannelSampleExpr(channel, vec);
1018 | }
1019 | exports.channel = channel;
1020 |
1021 | },{"../codebuilder":11,"../glslfunctions":61,"./expr":25,"./normfragcoordexpr":41}],20:[function(require,module,exports){
1022 | "use strict";
1023 | Object.defineProperty(exports, "__esModule", { value: true });
1024 | exports.contrast = exports.ContrastExpr = void 0;
1025 | const glslfunctions_1 = require("../glslfunctions");
1026 | const expr_1 = require("./expr");
1027 | const fragcolorexpr_1 = require("./fragcolorexpr");
1028 | class ContrastExpr extends expr_1.ExprVec4 {
1029 | constructor(contrast, col = fragcolorexpr_1.fcolor()) {
1030 | super(expr_1.tag `contrast(${contrast}, ${col})`, ["uVal", "uCol"]);
1031 | this.contrast = contrast;
1032 | this.externalFuncs = [glslfunctions_1.glslFuncs.contrast];
1033 | }
1034 | /** sets the contrast */
1035 | setContrast(contrast) {
1036 | this.setUniform("uContrast" + this.id, contrast);
1037 | this.contrast = expr_1.wrapInValue(contrast);
1038 | }
1039 | }
1040 | exports.ContrastExpr = ContrastExpr;
1041 | /**
1042 | * changes the contrast of a color
1043 | * @param val float for how much to change the contrast by (should probably be
1044 | * between -1 and 1)
1045 | * @param col the color to increase the contrast of (defaults to current
1046 | * fragment color)
1047 | */
1048 | function contrast(val, col) {
1049 | return new ContrastExpr(expr_1.wrapInValue(val), col);
1050 | }
1051 | exports.contrast = contrast;
1052 |
1053 | },{"../glslfunctions":61,"./expr":25,"./fragcolorexpr":26}],21:[function(require,module,exports){
1054 | "use strict";
1055 | Object.defineProperty(exports, "__esModule", { value: true });
1056 | exports.depth2occlusion = exports.DepthToOcclusionExpr = void 0;
1057 | const channelsampleexpr_1 = require("./channelsampleexpr");
1058 | const expr_1 = require("./expr");
1059 | const vecexprs_1 = require("./vecexprs");
1060 | /** depth info to occlussion info expression */
1061 | class DepthToOcclusionExpr extends expr_1.ExprVec4 {
1062 | constructor(depthCol = channelsampleexpr_1.channel(0), newCol = expr_1.mut(vecexprs_1.pvec4(1, 1, 1, 1)), threshold = expr_1.mut(expr_1.pfloat(0.01))) {
1063 | super(expr_1.tag `depth2occlusion(${depthCol}, ${newCol}, ${threshold})`, [
1064 | "uDepth",
1065 | "uNewCol",
1066 | "uThreshold",
1067 | ]);
1068 | this.depthCol = depthCol;
1069 | this.newCol = newCol;
1070 | this.threshold = threshold;
1071 | }
1072 | setDepthColor(depthCol) {
1073 | this.setUniform("uDepth" + this.id, depthCol);
1074 | this.depthCol = depthCol;
1075 | }
1076 | setNewColor(newCol) {
1077 | this.setUniform("uNewCol" + this.id, newCol);
1078 | this.newCol = newCol;
1079 | }
1080 | setThreshold(threshold) {
1081 | this.setUniform("uThreshold" + this.id, threshold);
1082 | this.threshold = expr_1.wrapInValue(threshold);
1083 | }
1084 | }
1085 | exports.DepthToOcclusionExpr = DepthToOcclusionExpr;
1086 | /**
1087 | * converts a `1 / distance` depth texture to an occlusion texture, with all
1088 | * occluded geometry being rendered as black
1089 | * @param depthCol the color representing the inverse depth (defaults to
1090 | * sampling from channel 0)
1091 | * @param newCol the color to replace unoccluded areas by (defaults to white
1092 | * and is mutable by default)
1093 | * @param threshold values below this are not occluded (set to something low,
1094 | * like 0.1 or lower; defaults to 0.01 and is mutable by default)
1095 | */
1096 | function depth2occlusion(depthCol, newCol, threshold) {
1097 | return new DepthToOcclusionExpr(depthCol, newCol, expr_1.wrapInValue(threshold));
1098 | }
1099 | exports.depth2occlusion = depth2occlusion;
1100 |
1101 | },{"./channelsampleexpr":19,"./expr":25,"./vecexprs":59}],22:[function(require,module,exports){
1102 | "use strict";
1103 | Object.defineProperty(exports, "__esModule", { value: true });
1104 | exports.dof = exports.DoFLoop = void 0;
1105 | const mergepass_1 = require("../mergepass");
1106 | const arity2_1 = require("./arity2");
1107 | const blurexpr_1 = require("./blurexpr");
1108 | const channelsampleexpr_1 = require("./channelsampleexpr");
1109 | const expr_1 = require("./expr");
1110 | const gaussianexpr_1 = require("./gaussianexpr");
1111 | const getcompexpr_1 = require("./getcompexpr");
1112 | const opexpr_1 = require("./opexpr");
1113 | const vecexprs_1 = require("./vecexprs");
1114 | class DoFLoop extends mergepass_1.EffectLoop {
1115 | constructor(depth = expr_1.mut(expr_1.pfloat(0.3)), rad = expr_1.mut(expr_1.pfloat(0.01)), depthInfo = getcompexpr_1.getcomp(channelsampleexpr_1.channel(0), "r"), reps = 2, taps = 13) {
1116 | let guassianExpr = gaussianexpr_1.gaussian(depthInfo, depth, rad);
1117 | const side = blurexpr_1.gauss(vecexprs_1.vec2(arity2_1.a2("pow", opexpr_1.op(1, "-", guassianExpr), 4), 0), taps);
1118 | const up = blurexpr_1.gauss(vecexprs_1.vec2(0, arity2_1.a2("pow", opexpr_1.op(1, "-", guassianExpr), 4)), taps);
1119 | super([side, up], { num: reps });
1120 | this.gaussian = guassianExpr;
1121 | }
1122 | setDepth(depth) {
1123 | // this translates the gaussian curve to the side
1124 | this.gaussian.setA(depth);
1125 | }
1126 | setRadius(radius) {
1127 | // this scales the gaussian curve to focus on a larger band of depth
1128 | this.gaussian.setB(radius);
1129 | }
1130 | }
1131 | exports.DoFLoop = DoFLoop;
1132 | /**
1133 | * creates depth of field expression; all values are mutable by default
1134 | * @param depth float for what inverse depth to focus on (1 on top of the
1135 | * camera; 0 is infinity)
1136 | * @param rad float for how deep the band of in-focus geometry is (a value
1137 | * between 0.01 and 0.1 is reasonable)
1138 | * @param depthInfo float the expression that represents the inverse depth
1139 | * (defaults to sampling the red component from channel 0)
1140 | * @param reps how many times to repeat the gaussian blur
1141 | */
1142 | function dof(depth, rad, depthInfo, reps) {
1143 | return new DoFLoop(expr_1.wrapInValue(depth), expr_1.wrapInValue(rad), expr_1.wrapInValue(depthInfo), reps);
1144 | }
1145 | exports.dof = dof;
1146 |
1147 | },{"../mergepass":63,"./arity2":13,"./blurexpr":16,"./channelsampleexpr":19,"./expr":25,"./gaussianexpr":29,"./getcompexpr":30,"./opexpr":43,"./vecexprs":59}],23:[function(require,module,exports){
1148 | "use strict";
1149 | Object.defineProperty(exports, "__esModule", { value: true });
1150 | exports.edgecolor = exports.EdgeColorExpr = void 0;
1151 | const arity2_1 = require("./arity2");
1152 | const expr_1 = require("./expr");
1153 | const fragcolorexpr_1 = require("./fragcolorexpr");
1154 | const monochromeexpr_1 = require("./monochromeexpr");
1155 | const sobelexpr_1 = require("./sobelexpr");
1156 | const vecexprs_1 = require("./vecexprs");
1157 | /** edge color expression */
1158 | class EdgeColorExpr extends expr_1.WrappedExpr {
1159 | constructor(color, samplerNum, stepped = true) {
1160 | const expr = stepped
1161 | ? expr_1.cvec4(expr_1.tag `mix(${color}, ${fragcolorexpr_1.fcolor()}, ${monochromeexpr_1.monochrome(arity2_1.a2("step", vecexprs_1.vec4(0.5, 0.5, 0.5, 0.0), sobelexpr_1.sobel(samplerNum)))})`)
1162 | : expr_1.cvec4(expr_1.tag `mix(${color}, ${fragcolorexpr_1.fcolor()}, ${monochromeexpr_1.monochrome(sobelexpr_1.sobel(samplerNum))})`);
1163 | super(expr);
1164 | this.color = color;
1165 | this.expr = expr;
1166 | }
1167 | setColor(color) {
1168 | this.expr.setUniform("uCustomName0" + this.expr.id, color);
1169 | this.color = color;
1170 | }
1171 | }
1172 | exports.EdgeColorExpr = EdgeColorExpr;
1173 | /**
1174 | * creates a colored edge detection expression
1175 | * @param color what color to make the edge
1176 | * @param samplerNum where to sample from
1177 | * @param stepped whether to round the result of sobel edge detection (defaults
1178 | * to true)
1179 | */
1180 | function edgecolor(color, samplerNum, stepped) {
1181 | return new EdgeColorExpr(color, samplerNum, stepped);
1182 | }
1183 | exports.edgecolor = edgecolor;
1184 |
1185 | },{"./arity2":13,"./expr":25,"./fragcolorexpr":26,"./monochromeexpr":36,"./sobelexpr":54,"./vecexprs":59}],24:[function(require,module,exports){
1186 | "use strict";
1187 | Object.defineProperty(exports, "__esModule", { value: true });
1188 | exports.edge = exports.EdgeExpr = void 0;
1189 | const brightnessexpr_1 = require("./brightnessexpr");
1190 | const expr_1 = require("./expr");
1191 | const getcompexpr_1 = require("./getcompexpr");
1192 | const invertexpr_1 = require("./invertexpr");
1193 | const monochromeexpr_1 = require("./monochromeexpr");
1194 | const opexpr_1 = require("./opexpr");
1195 | const sobelexpr_1 = require("./sobelexpr");
1196 | class EdgeExpr extends expr_1.WrappedExpr {
1197 | constructor(mult = expr_1.mut(-1.0), samplerNum) {
1198 | const operator = opexpr_1.op(getcompexpr_1.getcomp(invertexpr_1.invert(monochromeexpr_1.monochrome(sobelexpr_1.sobel(samplerNum))), "r"), "*", mult);
1199 | super(brightnessexpr_1.brightness(operator));
1200 | this.mult = mult;
1201 | this.operator = operator;
1202 | }
1203 | setMult(mult) {
1204 | this.operator.setRight(mult);
1205 | this.mult = expr_1.wrapInValue(mult);
1206 | }
1207 | }
1208 | exports.EdgeExpr = EdgeExpr;
1209 | /**
1210 | * returns an expression highlights edges where they appear
1211 | * @param style `"dark"` for dark edges and `"light"` for light edges, or a
1212 | * custom number or expression (between -1 and 1) for a more gray style of edge
1213 | * @param samplerNum where to sample from
1214 | */
1215 | function edge(style, samplerNum) {
1216 | const mult = style === "dark" ? -1 : style === "light" ? 1 : style;
1217 | return new EdgeExpr(expr_1.wrapInValue(mult), samplerNum);
1218 | }
1219 | exports.edge = edge;
1220 |
1221 | },{"./brightnessexpr":17,"./expr":25,"./getcompexpr":30,"./invertexpr":34,"./monochromeexpr":36,"./opexpr":43,"./sobelexpr":54}],25:[function(require,module,exports){
1222 | "use strict";
1223 | Object.defineProperty(exports, "__esModule", { value: true });
1224 | exports.tag = exports.wrapInValue = exports.pfloat = exports.Operator = exports.WrappedExpr = exports.ExprVec4 = exports.ExprVec3 = exports.ExprVec2 = exports.float = exports.ExprFloat = exports.BasicFloat = exports.ExprVec = exports.BasicVec4 = exports.BasicVec3 = exports.BasicVec2 = exports.BasicVec = exports.PrimitiveVec4 = exports.PrimitiveVec3 = exports.PrimitiveVec2 = exports.PrimitiveVec = exports.PrimitiveFloat = exports.Primitive = exports.mut = exports.Mutable = exports.cvec4 = exports.cvec3 = exports.cvec2 = exports.cfloat = exports.Expr = void 0;
1225 | const mergepass_1 = require("../mergepass");
1226 | const webglprogramloop_1 = require("../webglprogramloop");
1227 | const utils_1 = require("../utils");
1228 | /**
1229 | * adds a `.` after a number if needed (e.g converts `1` to `"1."` but leaves
1230 | * `1.2` as `"1.2"`)
1231 | * @param num number to convert
1232 | */
1233 | function toGLSLFloatString(num) {
1234 | let str = "" + num;
1235 | if (!str.includes("."))
1236 | str += ".";
1237 | return str;
1238 | }
1239 | class Expr {
1240 | constructor(sourceLists, defaultNames) {
1241 | // update me on change to needs
1242 | this.needs = {
1243 | neighborSample: false,
1244 | centerSample: false,
1245 | sceneBuffer: false,
1246 | timeUniform: false,
1247 | mouseUniform: false,
1248 | passCount: false,
1249 | extraBuffers: new Set(),
1250 | };
1251 | this.uniformValChangeMap = {};
1252 | this.defaultNameMap = {};
1253 | this.externalFuncs = [];
1254 | this.sourceCode = "";
1255 | this.funcIndex = 0;
1256 | this.regionBranded = false;
1257 | this.id = "_id_" + Expr.count;
1258 | Expr.count++;
1259 | if (sourceLists.sections.length - sourceLists.values.length !== 1) {
1260 | // this cannot happen if you use `tag` to destructure a template string
1261 | throw new Error("wrong lengths for source and values");
1262 | }
1263 | if (sourceLists.values.length !== defaultNames.length) {
1264 | console.log(sourceLists);
1265 | console.log(defaultNames);
1266 | throw new Error("default names list length doesn't match values list length");
1267 | }
1268 | this.sourceLists = sourceLists;
1269 | this.defaultNames = defaultNames;
1270 | }
1271 | applyUniforms(gl, uniformLocs) {
1272 | for (const name in this.uniformValChangeMap) {
1273 | const loc = uniformLocs[name];
1274 | if (this.uniformValChangeMap[name].changed) {
1275 | //this.uniformValChangeMap[name].changed = false;
1276 | this.uniformValChangeMap[name].val.applyUniform(gl, loc.locs[loc.counter]);
1277 | }
1278 | // increment and reset the counter to wrap back around to first location
1279 | loc.counter++;
1280 | loc.counter %= loc.locs.length;
1281 | // once we have wrapped then we know all uniforms have been changed
1282 | if (loc.counter === 0) {
1283 | this.uniformValChangeMap[name].changed = false;
1284 | }
1285 | }
1286 | }
1287 | getSampleNum(mult = 1) {
1288 | return this.needs.neighborSample
1289 | ? mult
1290 | : this.sourceLists.values
1291 | .map((v) => v.getSampleNum())
1292 | .reduce((acc, curr) => acc + curr, 0) > 0
1293 | ? mult
1294 | : 0;
1295 | }
1296 | /**
1297 | * set a uniform by name directly
1298 | * @param name uniform name in the source code
1299 | * @param newVal value to set the uniform to
1300 | */
1301 | setUniform(name, newVal) {
1302 | var _a, _b;
1303 | newVal = wrapInValue(newVal);
1304 | const originalName = name;
1305 | if (typeof newVal === "number") {
1306 | newVal = wrapInValue(newVal);
1307 | }
1308 | if (!(newVal instanceof Primitive)) {
1309 | throw new Error("cannot set a non-primitive");
1310 | }
1311 | // if name does not exist, try mapping default name to new name
1312 | if (((_a = this.uniformValChangeMap[name]) === null || _a === void 0 ? void 0 : _a.val) === undefined) {
1313 | name = this.defaultNameMap[name];
1314 | }
1315 | const oldVal = (_b = this.uniformValChangeMap[name]) === null || _b === void 0 ? void 0 : _b.val;
1316 | if (oldVal === undefined) {
1317 | throw new Error("tried to set uniform " +
1318 | name +
1319 | " which doesn't exist. original name: " +
1320 | originalName);
1321 | }
1322 | if (oldVal.typeString() !== newVal.typeString()) {
1323 | throw new Error("tried to set uniform " + name + " to a new type");
1324 | }
1325 | this.uniformValChangeMap[name].val = newVal;
1326 | this.uniformValChangeMap[name].changed = true;
1327 | }
1328 | /**
1329 | * parses this expression into a string, adding info as it recurses into
1330 | * nested expressions
1331 | */
1332 | parse(buildInfo) {
1333 | this.sourceCode = "";
1334 | buildInfo.exprs.push(this);
1335 | buildInfo.needs = webglprogramloop_1.updateNeeds(buildInfo.needs, this.needs);
1336 | // add each of the external funcs to the builder
1337 | this.externalFuncs.forEach((func) => buildInfo.externalFuncs.add(func));
1338 | // put all of the values between all of the source sections
1339 | for (let i = 0; i < this.sourceLists.values.length; i++) {
1340 | this.sourceCode +=
1341 | this.sourceLists.sections[i] +
1342 | this.sourceLists.values[i].parse(buildInfo, this.defaultNames[i], this);
1343 | }
1344 | // TODO does sourceCode have to be a member?
1345 | this.sourceCode += this.sourceLists.sections[this.sourceLists.sections.length - 1];
1346 | return this.sourceCode;
1347 | }
1348 | addFuncs(funcs) {
1349 | this.externalFuncs.push(...funcs);
1350 | return this;
1351 | }
1352 | brandExprWithChannel(funcIndex, samplerNum) {
1353 | utils_1.brandWithChannel(this.sourceLists, this.externalFuncs, this.needs, funcIndex, samplerNum);
1354 | return this;
1355 | }
1356 | brandExprWithRegion(space) {
1357 | utils_1.brandWithRegion(this, this.funcIndex, space);
1358 | for (const v of this.sourceLists.values) {
1359 | v.brandExprWithRegion(space);
1360 | }
1361 | return this;
1362 | }
1363 | }
1364 | exports.Expr = Expr;
1365 | /**
1366 | * increments for each expression created; used to uniquely id each expression
1367 | */
1368 | Expr.count = 0;
1369 | function genCustomNames(sourceLists) {
1370 | const names = [];
1371 | for (let i = 0; i < sourceLists.values.length; i++) {
1372 | names.push("uCustomName" + i);
1373 | }
1374 | return names;
1375 | }
1376 | /** create a custom float function (use with [[tag]]) */
1377 | function cfloat(sourceLists, externalFuncs = []) {
1378 | return new ExprFloat(sourceLists, genCustomNames(sourceLists)).addFuncs(externalFuncs);
1379 | }
1380 | exports.cfloat = cfloat;
1381 | /** create a custom vec2 function (use with [[tag]]) */
1382 | function cvec2(sourceLists, externalFuncs = []) {
1383 | return new ExprVec2(sourceLists, genCustomNames(sourceLists)).addFuncs(externalFuncs);
1384 | }
1385 | exports.cvec2 = cvec2;
1386 | /** create a custom vec3 function (use with [[tag]]) */
1387 | function cvec3(sourceLists, externalFuncs = []) {
1388 | return new ExprVec3(sourceLists, genCustomNames(sourceLists)).addFuncs(externalFuncs);
1389 | }
1390 | exports.cvec3 = cvec3;
1391 | /** create a custom vec4 function (use with [[tag]]) */
1392 | function cvec4(sourceLists, externalFuncs = []) {
1393 | return new ExprVec4(sourceLists, genCustomNames(sourceLists)).addFuncs(externalFuncs);
1394 | }
1395 | exports.cvec4 = cvec4;
1396 | class Mutable {
1397 | constructor(primitive, name) {
1398 | this.primitive = primitive;
1399 | this.name = name;
1400 | }
1401 | parse(buildInfo, defaultName, enc) {
1402 | if (enc === undefined) {
1403 | throw new Error("tried to put a mutable expression at the top level");
1404 | }
1405 | // accept the default name if given no name
1406 | if (this.name === undefined)
1407 | this.name = defaultName + enc.id;
1408 | // set to true so they are set to their default values on first draw
1409 | buildInfo.uniformTypes[this.name] = this.primitive.typeString();
1410 | // add the name mapping
1411 | enc.uniformValChangeMap[this.name] = {
1412 | val: this.primitive,
1413 | changed: true,
1414 | };
1415 | // add the new type to the map
1416 | enc.defaultNameMap[defaultName + enc.id] = this.name;
1417 | return this.name;
1418 | }
1419 | applyUniform(gl, loc) {
1420 | this.primitive.applyUniform(gl, loc);
1421 | }
1422 | typeString() {
1423 | return this.primitive.typeString();
1424 | }
1425 | getSampleNum() {
1426 | return 0;
1427 | }
1428 | brandExprWithRegion(space) {
1429 | return this;
1430 | }
1431 | }
1432 | exports.Mutable = Mutable;
1433 | /**
1434 | * makes a primitive value mutable. wrapping a [[PrimitiveVec]] or
1435 | * [[PrimitiveFloat]] in [[mut]] before passing it into an expression will
1436 | * allow you to use the setters on that expression to change those values at
1437 | * runtime
1438 | * @param val the primitive float or primitive vec to make mutable
1439 | * @param name the optional name for the uniform
1440 | */
1441 | function mut(val, name) {
1442 | const primitive = typeof val === "number" ? wrapInValue(val) : val;
1443 | return new Mutable(primitive, name);
1444 | }
1445 | exports.mut = mut;
1446 | class Primitive {
1447 | parse() {
1448 | return this.toString();
1449 | }
1450 | getSampleNum() {
1451 | return 0;
1452 | }
1453 | brandExprWithRegion(space) {
1454 | return this;
1455 | }
1456 | }
1457 | exports.Primitive = Primitive;
1458 | class PrimitiveFloat extends Primitive {
1459 | constructor(num) {
1460 | if (!isFinite(num))
1461 | throw new Error("number not finite");
1462 | super();
1463 | this.value = num;
1464 | }
1465 | toString() {
1466 | let str = "" + this.value;
1467 | if (!str.includes("."))
1468 | str += ".";
1469 | return str;
1470 | }
1471 | typeString() {
1472 | return "float";
1473 | }
1474 | applyUniform(gl, loc) {
1475 | gl.uniform1f(loc, this.value);
1476 | }
1477 | }
1478 | exports.PrimitiveFloat = PrimitiveFloat;
1479 | class PrimitiveVec extends Primitive {
1480 | constructor(comps) {
1481 | super();
1482 | this.values = comps;
1483 | }
1484 | typeString() {
1485 | return ("vec" + this.values.length);
1486 | }
1487 | toString() {
1488 | return `${this.typeString()}(${this.values
1489 | .map((n) => toGLSLFloatString(n))
1490 | .join(", ")})`;
1491 | }
1492 | }
1493 | exports.PrimitiveVec = PrimitiveVec;
1494 | class PrimitiveVec2 extends PrimitiveVec {
1495 | applyUniform(gl, loc) {
1496 | gl.uniform2f(loc, this.values[0], this.values[1]);
1497 | }
1498 | }
1499 | exports.PrimitiveVec2 = PrimitiveVec2;
1500 | class PrimitiveVec3 extends PrimitiveVec {
1501 | applyUniform(gl, loc) {
1502 | gl.uniform3f(loc, this.values[0], this.values[1], this.values[2]);
1503 | }
1504 | }
1505 | exports.PrimitiveVec3 = PrimitiveVec3;
1506 | class PrimitiveVec4 extends PrimitiveVec {
1507 | applyUniform(gl, loc) {
1508 | gl.uniform4f(loc, this.values[0], this.values[1], this.values[2], this.values[3]);
1509 | }
1510 | }
1511 | exports.PrimitiveVec4 = PrimitiveVec4;
1512 | class BasicVec extends Expr {
1513 | constructor(sourceLists, defaultNames) {
1514 | super(sourceLists, defaultNames);
1515 | // this cast is fine as long as you only instantiate these with the
1516 | // shorthand version and not the constructor
1517 | const values = sourceLists.values;
1518 | this.values = values;
1519 | this.defaultNames = defaultNames;
1520 | }
1521 | typeString() {
1522 | return ("vec" + this.values.length);
1523 | }
1524 | /** sets a component of the vector */
1525 | setComp(index, primitive) {
1526 | if (index < 0 || index >= this.values.length) {
1527 | throw new Error("out of bounds of setting component");
1528 | }
1529 | this.setUniform(this.defaultNames[index] + this.id, wrapInValue(primitive));
1530 | }
1531 | }
1532 | exports.BasicVec = BasicVec;
1533 | class BasicVec2 extends BasicVec {
1534 | constructor() {
1535 | super(...arguments);
1536 | this.bvec2 = undefined; // brand for nominal typing
1537 | }
1538 | }
1539 | exports.BasicVec2 = BasicVec2;
1540 | class BasicVec3 extends BasicVec {
1541 | constructor() {
1542 | super(...arguments);
1543 | this.bvec3 = undefined; // brand for nominal typing
1544 | }
1545 | }
1546 | exports.BasicVec3 = BasicVec3;
1547 | class BasicVec4 extends BasicVec {
1548 | constructor() {
1549 | super(...arguments);
1550 | this.bvec4 = undefined; // brand for nominal typing
1551 | }
1552 | }
1553 | exports.BasicVec4 = BasicVec4;
1554 | class ExprVec extends Expr {
1555 | constructor(sourceLists, defaultNames) {
1556 | super(sourceLists, defaultNames);
1557 | const values = sourceLists.values;
1558 | this.values = values;
1559 | this.defaultNames = defaultNames;
1560 | }
1561 | }
1562 | exports.ExprVec = ExprVec;
1563 | class BasicFloat extends Expr {
1564 | constructor(sourceLists, defaultNames) {
1565 | super(sourceLists, defaultNames);
1566 | this.float = undefined; // brand for nominal typing
1567 | }
1568 | setVal(primitive) {
1569 | this.setUniform("uFloat" + this.id, wrapInValue(primitive));
1570 | }
1571 | typeString() {
1572 | return "float";
1573 | }
1574 | }
1575 | exports.BasicFloat = BasicFloat;
1576 | class ExprFloat extends Expr {
1577 | constructor(sourceLists, defaultNames) {
1578 | super(sourceLists, defaultNames);
1579 | this.float = undefined; // brand for nominal typing
1580 | }
1581 | setVal(primitive) {
1582 | this.setUniform("uFloat" + this.id, wrapInValue(primitive));
1583 | }
1584 | typeString() {
1585 | return "float";
1586 | }
1587 | }
1588 | exports.ExprFloat = ExprFloat;
1589 | function float(value) {
1590 | if (typeof value === "number")
1591 | value = wrapInValue(value);
1592 | return new BasicFloat({ sections: ["", ""], values: [value] }, ["uFloat"]);
1593 | }
1594 | exports.float = float;
1595 | class ExprVec2 extends ExprVec {
1596 | constructor() {
1597 | super(...arguments);
1598 | this.vec2 = undefined; // brand for nominal typing
1599 | }
1600 | typeString() {
1601 | return "vec2";
1602 | }
1603 | }
1604 | exports.ExprVec2 = ExprVec2;
1605 | class ExprVec3 extends ExprVec {
1606 | constructor() {
1607 | super(...arguments);
1608 | this.vec3 = undefined; // brand for nominal typing
1609 | }
1610 | typeString() {
1611 | return "vec3";
1612 | }
1613 | }
1614 | exports.ExprVec3 = ExprVec3;
1615 | class ExprVec4 extends ExprVec {
1616 | constructor() {
1617 | super(...arguments);
1618 | this.vec4 = undefined; // brand for nominal typing
1619 | }
1620 | repeat(num) {
1621 | return new mergepass_1.EffectLoop([this], { num: num });
1622 | }
1623 | genPrograms(gl, vShader, uniformLocs, shaders) {
1624 | return new mergepass_1.EffectLoop([this], { num: 1 }).genPrograms(gl, vShader, uniformLocs, shaders);
1625 | }
1626 | typeString() {
1627 | return "vec4";
1628 | }
1629 | }
1630 | exports.ExprVec4 = ExprVec4;
1631 | class WrappedExpr {
1632 | constructor(expr) {
1633 | this.expr = expr;
1634 | }
1635 | typeString() {
1636 | return this.expr.typeString();
1637 | }
1638 | parse(buildInfo, defaultName, enc) {
1639 | return this.expr.parse(buildInfo, defaultName, enc);
1640 | }
1641 | getSampleNum() {
1642 | return this.expr.getSampleNum();
1643 | }
1644 | brandExprWithRegion(space) {
1645 | return this.expr.brandExprWithRegion(space);
1646 | }
1647 | }
1648 | exports.WrappedExpr = WrappedExpr;
1649 | class Operator extends Expr {
1650 | constructor(ret, sourceLists, defaultNames) {
1651 | super(sourceLists, defaultNames);
1652 | this.ret = ret;
1653 | }
1654 | typeString() {
1655 | return this.ret.typeString();
1656 | }
1657 | }
1658 | exports.Operator = Operator;
1659 | /** creates a primitive float */
1660 | function pfloat(num) {
1661 | return new PrimitiveFloat(num);
1662 | }
1663 | exports.pfloat = pfloat;
1664 | function wrapInValue(num) {
1665 | if (num === undefined)
1666 | return undefined;
1667 | if (typeof num === "number")
1668 | return pfloat(num);
1669 | return num;
1670 | }
1671 | exports.wrapInValue = wrapInValue;
1672 | /**
1673 | * takes a template strings array and converts it to a source list; very useful
1674 | * for [[cfloat]], [[cvec2]], [[cvec3]] and [[cvec4]]
1675 | */
1676 | function tag(strings, ...values) {
1677 | return { sections: strings.concat([]), values: values };
1678 | }
1679 | exports.tag = tag;
1680 |
1681 | },{"../mergepass":63,"../utils":65,"../webglprogramloop":66}],26:[function(require,module,exports){
1682 | "use strict";
1683 | Object.defineProperty(exports, "__esModule", { value: true });
1684 | exports.fcolor = exports.FragColorExpr = void 0;
1685 | const expr_1 = require("./expr");
1686 | /** fragment color expression */
1687 | class FragColorExpr extends expr_1.ExprVec4 {
1688 | constructor() {
1689 | super(expr_1.tag `gl_FragColor`, []);
1690 | this.needs.centerSample = true;
1691 | }
1692 | }
1693 | exports.FragColorExpr = FragColorExpr;
1694 | /** creates an expression that evaluates to the fragment color */
1695 | function fcolor() {
1696 | return new FragColorExpr();
1697 | }
1698 | exports.fcolor = fcolor;
1699 |
1700 | },{"./expr":25}],27:[function(require,module,exports){
1701 | "use strict";
1702 | Object.defineProperty(exports, "__esModule", { value: true });
1703 | exports.pixel = exports.FragCoordExpr = void 0;
1704 | const expr_1 = require("./expr");
1705 | /** frag coord expression (xy components only) */
1706 | class FragCoordExpr extends expr_1.ExprVec2 {
1707 | constructor() {
1708 | super(expr_1.tag `gl_FragCoord.xy`, []);
1709 | }
1710 | }
1711 | exports.FragCoordExpr = FragCoordExpr;
1712 | /**
1713 | * creates an expression that evaluates to the frag coord in pixels (samplers
1714 | * take normalized coordinates, so you might want [[nfcoord]] instead)
1715 | */
1716 | function pixel() {
1717 | return new FragCoordExpr();
1718 | }
1719 | exports.pixel = pixel;
1720 |
1721 | },{"./expr":25}],28:[function(require,module,exports){
1722 | "use strict";
1723 | Object.defineProperty(exports, "__esModule", { value: true });
1724 | exports.fxaa = void 0;
1725 | const expr_1 = require("./expr");
1726 | const glslfunctions_1 = require("../glslfunctions");
1727 | /** FXAA expression */
1728 | class FXAAExpr extends expr_1.ExprVec4 {
1729 | constructor() {
1730 | super(expr_1.tag `fxaa()`, []);
1731 | this.externalFuncs = [glslfunctions_1.glslFuncs.fxaa];
1732 | this.needs.neighborSample = true;
1733 | }
1734 | }
1735 | /** FXAA antaliasing expression */
1736 | function fxaa() {
1737 | return new FXAAExpr();
1738 | }
1739 | exports.fxaa = fxaa;
1740 |
1741 | },{"../glslfunctions":61,"./expr":25}],29:[function(require,module,exports){
1742 | "use strict";
1743 | Object.defineProperty(exports, "__esModule", { value: true });
1744 | exports.gaussian = exports.GaussianExpr = void 0;
1745 | const glslfunctions_1 = require("../glslfunctions");
1746 | const expr_1 = require("./expr");
1747 | /** gaussian expression */
1748 | class GaussianExpr extends expr_1.ExprFloat {
1749 | constructor(x, a, b) {
1750 | super(expr_1.tag `gaussian(${x}, ${a}, ${b})`, ["uFloatX", "uFloatA", "uFloatB"]);
1751 | this.x = x;
1752 | this.a = a;
1753 | this.b = b;
1754 | this.externalFuncs = [glslfunctions_1.glslFuncs.gaussian];
1755 | }
1756 | setX(x) {
1757 | this.setUniform("uFloatX" + this.id, x);
1758 | this.x = expr_1.wrapInValue(x);
1759 | }
1760 | setA(a) {
1761 | this.setUniform("uFloatA" + this.id, a);
1762 | this.a = expr_1.wrapInValue(a);
1763 | }
1764 | setB(b) {
1765 | this.setUniform("uFloatB" + this.id, b);
1766 | this.b = expr_1.wrapInValue(b);
1767 | }
1768 | }
1769 | exports.GaussianExpr = GaussianExpr;
1770 | /**
1771 | * gaussian function that defaults to normal distribution
1772 | * @param x x position in the curve
1773 | * @param a horizontal position of peak (defaults to 0 for normal distribution)
1774 | * @param b horizontal stretch of the curve (defaults to 1 for normal distribution)
1775 | */
1776 | function gaussian(x, a = 0, b = 1) {
1777 | return new GaussianExpr(expr_1.wrapInValue(x), expr_1.wrapInValue(a), expr_1.wrapInValue(b));
1778 | }
1779 | exports.gaussian = gaussian;
1780 |
1781 | },{"../glslfunctions":61,"./expr":25}],30:[function(require,module,exports){
1782 | "use strict";
1783 | Object.defineProperty(exports, "__esModule", { value: true });
1784 | exports.get4comp = exports.get3comp = exports.get2comp = exports.getcomp = exports.Get4CompExpr = exports.Get3CompExpr = exports.Get2CompExpr = exports.GetCompExpr = exports.checkLegalComponents = exports.typeStringToLength = void 0;
1785 | const expr_1 = require("./expr");
1786 | // TODO this should probably be somewhere else
1787 | /** @ignore */
1788 | function typeStringToLength(str) {
1789 | switch (str) {
1790 | case "float":
1791 | return 1;
1792 | case "vec2":
1793 | return 2;
1794 | case "vec3":
1795 | return 3;
1796 | case "vec4":
1797 | return 4;
1798 | }
1799 | }
1800 | exports.typeStringToLength = typeStringToLength;
1801 | /** @ignore */
1802 | function genCompSource(vec, components) {
1803 | return {
1804 | sections: ["", "." + components],
1805 | values: [vec],
1806 | };
1807 | }
1808 | /**
1809 | * checks if components accessing a vector are legal. components can be illegal
1810 | * if they mix sets (e.g. `v.rgzw`) or contain characters outside of any set
1811 | * (e.g. `v.lmno`)
1812 | * @param comps components string
1813 | * @param vec vector being accessed
1814 | */
1815 | function checkLegalComponents(comps, vec) {
1816 | const check = (range, domain) => {
1817 | let inside = 0;
1818 | let outside = 0;
1819 | for (const c of range) {
1820 | domain.includes(c) ? inside++ : outside++;
1821 | }
1822 | return inside === inside && !outside;
1823 | };
1824 | const inLen = typeStringToLength(vec.typeString());
1825 | const rgbaCheck = check(comps, "rgba".substr(0, inLen));
1826 | const xyzwCheck = check(comps, "xyzw".substr(0, inLen));
1827 | const stpqCheck = check(comps, "stpq".substr(0, inLen));
1828 | if (!(rgbaCheck || xyzwCheck || stpqCheck)) {
1829 | throw new Error("component sets are mixed or incorrect entirely");
1830 | }
1831 | }
1832 | exports.checkLegalComponents = checkLegalComponents;
1833 | /**
1834 | * performs all validity checks of [[checkLegalComponents]] and checks if the
1835 | * number of accessed components does not exceed the size of the vector being
1836 | * assigned to
1837 | * @param comps components string
1838 | * @param outLen length of the resultant vector
1839 | * @param vec vector being accessed
1840 | */
1841 | function checkGetComponents(comps, outLen, vec) {
1842 | if (comps.length > outLen)
1843 | throw new Error("too many components");
1844 | checkLegalComponents(comps, vec);
1845 | }
1846 | /** get component expression */
1847 | class GetCompExpr extends expr_1.ExprFloat {
1848 | constructor(vec, comps) {
1849 | checkGetComponents(comps, 1, vec);
1850 | super(genCompSource(vec, comps), ["uVec1Min"]);
1851 | this.vec1Min = vec;
1852 | }
1853 | setVec(vec) {
1854 | this.setUniform("uVec1Min", vec);
1855 | this.vec1Min = vec;
1856 | }
1857 | }
1858 | exports.GetCompExpr = GetCompExpr;
1859 | /** get 2 components expression */
1860 | class Get2CompExpr extends expr_1.ExprVec2 {
1861 | constructor(vec, comps) {
1862 | checkGetComponents(comps, 2, vec);
1863 | super(genCompSource(vec, comps), ["uVec2Min"]);
1864 | this.vec2Min = vec;
1865 | }
1866 | setVec(vec) {
1867 | this.setUniform("uVec2Min", vec);
1868 | this.vec2Min = vec;
1869 | }
1870 | }
1871 | exports.Get2CompExpr = Get2CompExpr;
1872 | /** get 3 components expression */
1873 | class Get3CompExpr extends expr_1.ExprVec3 {
1874 | constructor(vec, comps) {
1875 | checkGetComponents(comps, 3, vec);
1876 | super(genCompSource(vec, comps), ["uVec3Min"]);
1877 | this.vec3Min = vec;
1878 | }
1879 | setVec(vec) {
1880 | this.setUniform("uVec3Min", vec);
1881 | this.vec3Min = vec;
1882 | }
1883 | }
1884 | exports.Get3CompExpr = Get3CompExpr;
1885 | /** get 3 components expression */
1886 | class Get4CompExpr extends expr_1.ExprVec4 {
1887 | constructor(vec, comps) {
1888 | checkGetComponents(comps, 4, vec);
1889 | super(genCompSource(vec, comps), ["uVec4Min"]);
1890 | this.vec4Min = vec;
1891 | }
1892 | setVec(vec) {
1893 | this.setUniform("uVec4Min", vec);
1894 | this.vec4Min = vec;
1895 | }
1896 | }
1897 | exports.Get4CompExpr = Get4CompExpr;
1898 | /**
1899 | * creates an expression that gets 1 component from a vector
1900 | * @param vec the vector to get components of
1901 | * @param comps components string
1902 | */
1903 | function getcomp(vec, comps) {
1904 | return new GetCompExpr(vec, comps);
1905 | }
1906 | exports.getcomp = getcomp;
1907 | /**
1908 | * creates an expression that gets 2 components from a vector
1909 | * @param vec the vector to get components of
1910 | * @param comps components string
1911 | */
1912 | function get2comp(vec, comps) {
1913 | return new Get2CompExpr(vec, comps);
1914 | }
1915 | exports.get2comp = get2comp;
1916 | /**
1917 | * creates an expression that gets 3 components from a vector
1918 | * @param vec the vector to get components of
1919 | * @param comps components string
1920 | */
1921 | function get3comp(vec, comps) {
1922 | return new Get3CompExpr(vec, comps);
1923 | }
1924 | exports.get3comp = get3comp;
1925 | /**
1926 | * creates an expression that gets 4 components from a vector
1927 | * @param vec the vector to get components of
1928 | * @param comps components string
1929 | */
1930 | function get4comp(vec, comps) {
1931 | return new Get4CompExpr(vec, comps);
1932 | }
1933 | exports.get4comp = get4comp;
1934 |
1935 | },{"./expr":25}],31:[function(require,module,exports){
1936 | "use strict";
1937 | Object.defineProperty(exports, "__esModule", { value: true });
1938 | exports.godrays = exports.GodRaysExpr = void 0;
1939 | const glslfunctions_1 = require("../glslfunctions");
1940 | const expr_1 = require("./expr");
1941 | const fragcolorexpr_1 = require("./fragcolorexpr");
1942 | const vecexprs_1 = require("./vecexprs");
1943 | /**
1944 | * @ignore
1945 | * the number of samples in the source code already
1946 | */
1947 | const DEFAULT_SAMPLES = 100;
1948 | /** godrays expression */
1949 | class GodRaysExpr extends expr_1.ExprVec4 {
1950 | // sane godray defaults from https://github.com/Erkaman/glsl-godrays/blob/master/example/index.js
1951 | constructor(col = fragcolorexpr_1.fcolor(), exposure = expr_1.mut(1.0), decay = expr_1.mut(1.0), density = expr_1.mut(1.0), weight = expr_1.mut(0.01), lightPos = expr_1.mut(vecexprs_1.pvec2(0.5, 0.5)), samplerNum = 0, numSamples = DEFAULT_SAMPLES, convertDepth) {
1952 | // TODO the metaprogramming here is not so good!
1953 | // leaving off the function call section for now (we addd it back later)
1954 | const sourceLists = expr_1.tag `${col}, ${exposure}, ${decay}, ${density}, ${weight}, ${lightPos}, ${convertDepth !== undefined ? convertDepth.threshold : expr_1.float(0)}, ${convertDepth !== undefined ? convertDepth.newColor : vecexprs_1.vec4(0, 0, 0, 0)})`;
1955 | // TODO make this more generic
1956 | // append the _ onto the function name
1957 | // also add _depth if this is a version of the function that uses depth buffer
1958 | const customName = `godrays${convertDepth !== undefined ? "_depth" : ""}${numSamples !== 100 ? "_s" + numSamples : ""}(`;
1959 | sourceLists.sections[0] = customName;
1960 | super(sourceLists, [
1961 | "uCol",
1962 | "uExposure",
1963 | "uDecay",
1964 | "uDensity",
1965 | "uWeight",
1966 | "uLightPos",
1967 | "uThreshold",
1968 | "uNewColor",
1969 | ]);
1970 | this.col = col;
1971 | this.exposure = exposure;
1972 | this.decay = decay;
1973 | this.density = density;
1974 | this.weight = weight;
1975 | this.lightPos = lightPos;
1976 | this.threshold = convertDepth === null || convertDepth === void 0 ? void 0 : convertDepth.threshold;
1977 | this.newColor = convertDepth === null || convertDepth === void 0 ? void 0 : convertDepth.newColor;
1978 | // will be 1 if needs to convert depth, and 0 otherwise
1979 | this.funcIndex = ~~(convertDepth !== undefined);
1980 | let customGodRayFunc = glslfunctions_1.glslFuncs.godrays
1981 | .split("godrays(")
1982 | .join(customName)
1983 | .replace(`NUM_SAMPLES = ${DEFAULT_SAMPLES}`, "NUM_SAMPLES = " + numSamples);
1984 | if (convertDepth !== undefined) {
1985 | // with regex, uncomment the line in the source code that does the
1986 | // conversion (if you think about it that's basically what a preprocessor
1987 | // does...)
1988 | customGodRayFunc = customGodRayFunc.replace(/\/\/uncomment\s/g, "");
1989 | this.externalFuncs.push(glslfunctions_1.glslFuncs.depth2occlusion);
1990 | }
1991 | this.externalFuncs.push(customGodRayFunc);
1992 | this.brandExprWithChannel(this.funcIndex, samplerNum);
1993 | }
1994 | /** sets the light color */
1995 | setColor(color) {
1996 | this.setUniform("uCol" + this.id, color);
1997 | this.col = color;
1998 | }
1999 | /** sets the exposure */
2000 | setExposure(exposure) {
2001 | this.setUniform("uExposure" + this.id, exposure);
2002 | this.exposure = expr_1.wrapInValue(exposure);
2003 | }
2004 | /** sets the decay */
2005 | setDecay(decay) {
2006 | this.setUniform("uDecay" + this.id, decay);
2007 | this.decay = expr_1.wrapInValue(decay);
2008 | }
2009 | /** sets the density */
2010 | setDensity(density) {
2011 | this.setUniform("uDensity" + this.id, density);
2012 | this.density = expr_1.wrapInValue(density);
2013 | }
2014 | /** sets the weight */
2015 | setWeight(weight) {
2016 | this.setUniform("uWeight" + this.id, weight);
2017 | this.weight = expr_1.wrapInValue(weight);
2018 | }
2019 | /** sets the light position */
2020 | setLightPos(lightPos) {
2021 | this.setUniform("uLightPos" + this.id, lightPos);
2022 | this.lightPos = lightPos;
2023 | }
2024 | // these only matter when you're using a depth buffer and not an occlusion
2025 | // buffer (although right now, you'll still be able to set them)
2026 | setThreshold(threshold) {
2027 | this.setUniform("uThreshold" + this.id, threshold);
2028 | this.threshold = expr_1.wrapInValue(threshold);
2029 | }
2030 | setNewColor(newColor) {
2031 | this.setUniform("uNewColor" + this.id, newColor);
2032 | this.newColor = newColor;
2033 | }
2034 | }
2035 | exports.GodRaysExpr = GodRaysExpr;
2036 | /**
2037 | * create a godrays expression which requires an occlusion map; all values are
2038 | * mutable by default
2039 | * @param options object that defines godrays properties (has sane defaults)
2040 | */
2041 | function godrays(options = {}) {
2042 | return new GodRaysExpr(options.color, expr_1.wrapInValue(options.exposure), expr_1.wrapInValue(options.decay), expr_1.wrapInValue(options.density), expr_1.wrapInValue(options.weight), options.lightPos, options.samplerNum, options.numSamples, options.convertDepth === undefined
2043 | ? undefined
2044 | : {
2045 | threshold: expr_1.wrapInValue(options.convertDepth.threshold),
2046 | newColor: options.convertDepth.newColor,
2047 | });
2048 | }
2049 | exports.godrays = godrays;
2050 |
2051 | },{"../glslfunctions":61,"./expr":25,"./fragcolorexpr":26,"./vecexprs":59}],32:[function(require,module,exports){
2052 | "use strict";
2053 | Object.defineProperty(exports, "__esModule", { value: true });
2054 | exports.grain = exports.GrainExpr = void 0;
2055 | const glslfunctions_1 = require("../glslfunctions");
2056 | const expr_1 = require("./expr");
2057 | // TODO consider getting rid of this since it's easy to make your own with
2058 | // `random` and `brightness`
2059 | /** grain expression */
2060 | class GrainExpr extends expr_1.ExprVec4 {
2061 | constructor(grain) {
2062 | super(expr_1.tag `vec4((1.0 - ${grain} * random(gl_FragCoord.xy)) * gl_FragColor.rgb, gl_FragColor.a);`, ["uGrain"]);
2063 | this.grain = grain;
2064 | this.externalFuncs = [glslfunctions_1.glslFuncs.random];
2065 | this.needs.centerSample = true;
2066 | }
2067 | /** sets the grain level */
2068 | setGrain(grain) {
2069 | this.setUniform("uGrain" + this.id, grain);
2070 | this.grain = expr_1.wrapInValue(grain);
2071 | }
2072 | }
2073 | exports.GrainExpr = GrainExpr;
2074 | /**
2075 | * creates an expression that adds random grain
2076 | * @param val how much the grain should impact the image (0 to 1 is reasonable)
2077 | */
2078 | function grain(val) {
2079 | return new GrainExpr(expr_1.wrapInValue(val));
2080 | }
2081 | exports.grain = grain;
2082 |
2083 | },{"../glslfunctions":61,"./expr":25}],33:[function(require,module,exports){
2084 | "use strict";
2085 | Object.defineProperty(exports, "__esModule", { value: true });
2086 | exports.hsv2rgb = exports.HSVToRGBExpr = void 0;
2087 | const expr_1 = require("./expr");
2088 | const glslfunctions_1 = require("../glslfunctions");
2089 | /** HSV to RGB expression */
2090 | class HSVToRGBExpr extends expr_1.ExprVec4 {
2091 | constructor(color) {
2092 | super(expr_1.tag `hsv2rgb(${color})`, ["uHSVCol"]);
2093 | this.color = color;
2094 | this.externalFuncs = [glslfunctions_1.glslFuncs.hsv2rgb];
2095 | }
2096 | /** sets the color to convert */
2097 | setColor(color) {
2098 | this.setUniform("uHSVCol", color);
2099 | this.color = color;
2100 | }
2101 | }
2102 | exports.HSVToRGBExpr = HSVToRGBExpr;
2103 | /**
2104 | * converts a color (with an alpha compoment) from hsv to rgb
2105 | * @param col the hsva color to convert to rgba
2106 | */
2107 | function hsv2rgb(col) {
2108 | return new HSVToRGBExpr(col);
2109 | }
2110 | exports.hsv2rgb = hsv2rgb;
2111 |
2112 | },{"../glslfunctions":61,"./expr":25}],34:[function(require,module,exports){
2113 | "use strict";
2114 | Object.defineProperty(exports, "__esModule", { value: true });
2115 | exports.invert = exports.InvertExpr = void 0;
2116 | const expr_1 = require("./expr");
2117 | const glslfunctions_1 = require("../glslfunctions");
2118 | /** invert expression */
2119 | class InvertExpr extends expr_1.ExprVec4 {
2120 | constructor(color) {
2121 | super(expr_1.tag `invert(${color})`, ["uColor"]);
2122 | this.externalFuncs = [glslfunctions_1.glslFuncs.invert];
2123 | this.color = color;
2124 | }
2125 | /** sets the color */
2126 | setColor(color) {
2127 | this.setUniform("uColor", color);
2128 | this.color = color;
2129 | }
2130 | }
2131 | exports.InvertExpr = InvertExpr;
2132 | /**
2133 | * creates an expression that inverts the color, keeping the original alpha
2134 | */
2135 | function invert(col) {
2136 | return new InvertExpr(col);
2137 | }
2138 | exports.invert = invert;
2139 |
2140 | },{"../glslfunctions":61,"./expr":25}],35:[function(require,module,exports){
2141 | "use strict";
2142 | Object.defineProperty(exports, "__esModule", { value: true });
2143 | exports.len = exports.LenExpr = void 0;
2144 | const expr_1 = require("./expr");
2145 | /** length expression */
2146 | class LenExpr extends expr_1.ExprFloat {
2147 | constructor(vec) {
2148 | super(expr_1.tag `length(${vec})`, ["uVec"]);
2149 | this.vec = vec;
2150 | }
2151 | setVec(vec) {
2152 | this.setUniform("uVec" + this.id, vec);
2153 | this.vec = vec;
2154 | }
2155 | }
2156 | exports.LenExpr = LenExpr;
2157 | /** creates an expreession that calculates the length of a vector */
2158 | function len(vec) {
2159 | return new LenExpr(vec);
2160 | }
2161 | exports.len = len;
2162 |
2163 | },{"./expr":25}],36:[function(require,module,exports){
2164 | "use strict";
2165 | Object.defineProperty(exports, "__esModule", { value: true });
2166 | exports.monochrome = exports.MonochromeExpr = void 0;
2167 | const expr_1 = require("./expr");
2168 | const glslfunctions_1 = require("../glslfunctions");
2169 | /** monochrome expression */
2170 | class MonochromeExpr extends expr_1.ExprVec4 {
2171 | constructor(color) {
2172 | super(expr_1.tag `monochrome(${color})`, ["uColor"]);
2173 | this.externalFuncs = [glslfunctions_1.glslFuncs.monochrome];
2174 | this.color = color;
2175 | }
2176 | /** sets the color */
2177 | setColor(color) {
2178 | this.setUniform("uColor", color);
2179 | this.color = color;
2180 | }
2181 | }
2182 | exports.MonochromeExpr = MonochromeExpr;
2183 | /**
2184 | * creates an expression that converts a color into grayscale, keeping the
2185 | * original alpha
2186 | */
2187 | function monochrome(col) {
2188 | return new MonochromeExpr(col);
2189 | }
2190 | exports.monochrome = monochrome;
2191 |
2192 | },{"../glslfunctions":61,"./expr":25}],37:[function(require,module,exports){
2193 | "use strict";
2194 | Object.defineProperty(exports, "__esModule", { value: true });
2195 | exports.motionblur = exports.MotionBlurLoop = void 0;
2196 | const mergepass_1 = require("../mergepass");
2197 | const channelsampleexpr_1 = require("./channelsampleexpr");
2198 | const expr_1 = require("./expr");
2199 | const fragcolorexpr_1 = require("./fragcolorexpr");
2200 | const opexpr_1 = require("./opexpr");
2201 | /** frame averaging motion blur loop */
2202 | class MotionBlurLoop extends mergepass_1.EffectLoop {
2203 | constructor(target = 0, persistence = expr_1.float(expr_1.mut(0.3))) {
2204 | const col1 = opexpr_1.op(channelsampleexpr_1.channel(target), "*", persistence);
2205 | const col2 = opexpr_1.op(fragcolorexpr_1.fcolor(), "*", opexpr_1.op(1, "-", persistence));
2206 | const effects = [
2207 | mergepass_1.loop([opexpr_1.op(col1, "+", col2)]).target(target),
2208 | channelsampleexpr_1.channel(target),
2209 | ];
2210 | super(effects, { num: 1 });
2211 | this.persistence = persistence;
2212 | }
2213 | /** set the persistence (keep between 0 and 1) */
2214 | setPersistence(float) {
2215 | if (!(this.persistence instanceof expr_1.BasicFloat))
2216 | throw new Error("persistence expression not basic float");
2217 | this.persistence.setVal(float);
2218 | }
2219 | }
2220 | exports.MotionBlurLoop = MotionBlurLoop;
2221 | /**
2222 | * creates a frame averaging motion blur effect
2223 | * @param target the channel where your accumulation buffer is (defaults to 0,
2224 | * which you might be using for something like the depth texture, so be sure to
2225 | * change this to suit your needs)
2226 | * @param persistence close to 0 is more ghostly, and close to 1 is nearly no
2227 | * motion blur at all (defaults to 0.3)
2228 | */
2229 | function motionblur(target, persistence) {
2230 | return new MotionBlurLoop(target, expr_1.wrapInValue(persistence));
2231 | }
2232 | exports.motionblur = motionblur;
2233 |
2234 | },{"../mergepass":63,"./channelsampleexpr":19,"./expr":25,"./fragcolorexpr":26,"./opexpr":43}],38:[function(require,module,exports){
2235 | "use strict";
2236 | Object.defineProperty(exports, "__esModule", { value: true });
2237 | exports.mouse = exports.MouseExpr = void 0;
2238 | const expr_1 = require("./expr");
2239 | /** mouse position expression */
2240 | class MouseExpr extends expr_1.ExprVec2 {
2241 | constructor() {
2242 | super(expr_1.tag `uMouse`, []);
2243 | this.needs.mouseUniform = true;
2244 | }
2245 | }
2246 | exports.MouseExpr = MouseExpr;
2247 | /**
2248 | * creates an expression that evaluates to a vector representing the mouse
2249 | * position in pixels
2250 | */
2251 | function mouse() {
2252 | return new MouseExpr();
2253 | }
2254 | exports.mouse = mouse;
2255 |
2256 | },{"./expr":25}],39:[function(require,module,exports){
2257 | "use strict";
2258 | Object.defineProperty(exports, "__esModule", { value: true });
2259 | exports.center = exports.NormCenterFragCoordExpr = void 0;
2260 | const expr_1 = require("./expr");
2261 | /** normalized centered frag coord expression */
2262 | class NormCenterFragCoordExpr extends expr_1.ExprVec2 {
2263 | constructor() {
2264 | super(expr_1.tag `(gl_FragCoord.xy / uResolution - 0.5)`, []);
2265 | }
2266 | }
2267 | exports.NormCenterFragCoordExpr = NormCenterFragCoordExpr;
2268 | /**
2269 | * creates an expression that calculates the normalized centered coord
2270 | * (coordinates range from -0.5 to 0.5)
2271 | */
2272 | function center() {
2273 | return new NormCenterFragCoordExpr();
2274 | }
2275 | exports.center = center;
2276 |
2277 | },{"./expr":25}],40:[function(require,module,exports){
2278 | "use strict";
2279 | Object.defineProperty(exports, "__esModule", { value: true });
2280 | exports.norm = exports.NormExpr = void 0;
2281 | const expr_1 = require("./expr");
2282 | /** normalize expression */
2283 | class NormExpr extends expr_1.Operator {
2284 | constructor(vec) {
2285 | super(vec, expr_1.tag `normalize(${vec})`, ["uVec"]);
2286 | this.vec = vec;
2287 | }
2288 | /** sets the vec to normalize */
2289 | setVec(vec) {
2290 | this.setUniform("uVec" + this.id, vec);
2291 | this.vec = vec;
2292 | }
2293 | }
2294 | exports.NormExpr = NormExpr;
2295 | /** creates an expression that normalizes a vector */
2296 | function norm(vec) {
2297 | return new NormExpr(vec);
2298 | }
2299 | exports.norm = norm;
2300 |
2301 | },{"./expr":25}],41:[function(require,module,exports){
2302 | "use strict";
2303 | Object.defineProperty(exports, "__esModule", { value: true });
2304 | exports.pos = exports.NormFragCoordExpr = void 0;
2305 | const expr_1 = require("./expr");
2306 | /** normalized frag coord expression */
2307 | class NormFragCoordExpr extends expr_1.ExprVec2 {
2308 | constructor() {
2309 | // don't remove these parens! even if you think you are being clever about
2310 | // order of operations
2311 | super(expr_1.tag `(gl_FragCoord.xy / uResolution)`, []);
2312 | }
2313 | }
2314 | exports.NormFragCoordExpr = NormFragCoordExpr;
2315 | /**
2316 | * creates an expression that calculates the normalized frag coord (coordinates
2317 | * range from 0 to 1)
2318 | */
2319 | function pos() {
2320 | return new NormFragCoordExpr();
2321 | }
2322 | exports.pos = pos;
2323 |
2324 | },{"./expr":25}],42:[function(require,module,exports){
2325 | "use strict";
2326 | Object.defineProperty(exports, "__esModule", { value: true });
2327 | exports.nmouse = exports.NormMouseExpr = void 0;
2328 | const expr_1 = require("./expr");
2329 | /** normalized mouse position expression */
2330 | class NormMouseExpr extends expr_1.ExprVec2 {
2331 | constructor() {
2332 | super(expr_1.tag `(uMouse / uResolution.xy)`, []);
2333 | this.needs.mouseUniform = true;
2334 | }
2335 | }
2336 | exports.NormMouseExpr = NormMouseExpr;
2337 | /**
2338 | * creates an expression that calculates the normalized mouse position
2339 | * (coordinates range from 0 to 1)
2340 | */
2341 | function nmouse() {
2342 | return new NormMouseExpr();
2343 | }
2344 | exports.nmouse = nmouse;
2345 |
2346 | },{"./expr":25}],43:[function(require,module,exports){
2347 | "use strict";
2348 | Object.defineProperty(exports, "__esModule", { value: true });
2349 | exports.op = exports.OpExpr = void 0;
2350 | const expr_1 = require("./expr");
2351 | function genOpSourceList(left, op, right) {
2352 | return {
2353 | sections: ["(", ` ${op} `, ")"],
2354 | values: [left, right],
2355 | };
2356 | }
2357 | class OpExpr extends expr_1.Operator {
2358 | constructor(left, op, right) {
2359 | super(left, genOpSourceList(left, op, right), ["uLeft", "uRight"]);
2360 | this.left = left;
2361 | this.right = right;
2362 | }
2363 | setLeft(left) {
2364 | this.setUniform("uLeft" + this.id, left);
2365 | this.left = expr_1.wrapInValue(left);
2366 | }
2367 | setRight(right) {
2368 | this.setUniform("uRight" + this.id, right);
2369 | this.right = expr_1.wrapInValue(right);
2370 | }
2371 | }
2372 | exports.OpExpr = OpExpr;
2373 | // implementation
2374 | /**
2375 | * creates an arithmetic operator expression
2376 | * @param left expression left of operator
2377 | * @param op string representing arithmetic operator
2378 | * @param right expression right of operator
2379 | */
2380 | function op(left, op, right) {
2381 | return new OpExpr(expr_1.wrapInValue(left), op, expr_1.wrapInValue(right));
2382 | }
2383 | exports.op = op;
2384 |
2385 | },{"./expr":25}],44:[function(require,module,exports){
2386 | "use strict";
2387 | Object.defineProperty(exports, "__esModule", { value: true });
2388 | exports.fractalize = exports.perlin = exports.PerlinExpr = void 0;
2389 | const glslfunctions_1 = require("../glslfunctions");
2390 | const expr_1 = require("./expr");
2391 | const opexpr_1 = require("./opexpr");
2392 | /** Perlin noise expression */
2393 | class PerlinExpr extends expr_1.ExprFloat {
2394 | // TODO include a default
2395 | constructor(pos) {
2396 | super(expr_1.tag `gradientnoise(${pos})`, ["uPos"]);
2397 | this.pos = pos;
2398 | this.externalFuncs = [glslfunctions_1.glslFuncs.random2, glslfunctions_1.glslFuncs.gradientnoise];
2399 | }
2400 | /** sets the position to calculate noise value of */
2401 | setPos(pos) {
2402 | this.setUniform("uPos", pos);
2403 | this.pos = pos;
2404 | }
2405 | }
2406 | exports.PerlinExpr = PerlinExpr;
2407 | /**
2408 | * creates a perlin noise expression; values range from -1 to 1 but they tend
2409 | * to be grayer than the [[simplex]] implementation
2410 | * @param pos position
2411 | */
2412 | function perlin(pos) {
2413 | return new PerlinExpr(pos);
2414 | }
2415 | exports.perlin = perlin;
2416 | /**
2417 | * take any function from a position to a float, and repeatedly sum calls to it
2418 | * with doubling frequency and halving amplitude (works well with [[simplex]]
2419 | * and [[perlin]])
2420 | * @param pos position
2421 | * @param octaves how many layers deep to make the fractal
2422 | * @param func the function to fractalize
2423 | */
2424 | function fractalize(pos, octaves, func) {
2425 | if (octaves < 0)
2426 | throw new Error("octaves can't be < 0");
2427 | const recurse = (pos, size, level) => {
2428 | if (level <= 0)
2429 | return expr_1.pfloat(0);
2430 | return opexpr_1.op(func(opexpr_1.op(pos, "/", size * 2)), "+", recurse(pos, size / 2, level - 1));
2431 | };
2432 | return recurse(pos, 0.5, octaves);
2433 | }
2434 | exports.fractalize = fractalize;
2435 |
2436 | },{"../glslfunctions":61,"./expr":25,"./opexpr":43}],45:[function(require,module,exports){
2437 | "use strict";
2438 | Object.defineProperty(exports, "__esModule", { value: true });
2439 | exports.pblur = exports.PowerBlurLoop = void 0;
2440 | const mergepass_1 = require("../mergepass");
2441 | const blurexpr_1 = require("./blurexpr");
2442 | const vecexprs_1 = require("./vecexprs");
2443 | const expr_1 = require("./expr");
2444 | const baseLog = (x, y) => Math.log(y) / Math.log(x);
2445 | // TODO consider getting rid of this, as it pretty much never looks good
2446 | /** power blur loop */
2447 | class PowerBlurLoop extends mergepass_1.EffectLoop {
2448 | constructor(size) {
2449 | const side = blurexpr_1.gauss(expr_1.mut(vecexprs_1.pvec2(size, 0)));
2450 | const up = blurexpr_1.gauss(expr_1.mut(vecexprs_1.pvec2(0, size)));
2451 | const reps = Math.ceil(baseLog(2, size));
2452 | super([side, up], {
2453 | num: reps + 1,
2454 | });
2455 | this.size = size;
2456 | this.loopInfo.func = (i) => {
2457 | const distance = this.size / Math.pow(2, i);
2458 | up.setDirection(vecexprs_1.pvec2(0, distance));
2459 | side.setDirection(vecexprs_1.pvec2(distance, 0));
2460 | };
2461 | }
2462 | /** sets the size of the radius */
2463 | setSize(size) {
2464 | this.size = size;
2465 | this.loopInfo.num = Math.ceil(baseLog(2, size));
2466 | }
2467 | }
2468 | exports.PowerBlurLoop = PowerBlurLoop;
2469 | /**
2470 | * fast approximate blur for large blur radius that might look good in some cases
2471 | * @param size the radius of the blur
2472 | */
2473 | function pblur(size) {
2474 | return new PowerBlurLoop(size);
2475 | }
2476 | exports.pblur = pblur;
2477 |
2478 | },{"../mergepass":63,"./blurexpr":16,"./expr":25,"./vecexprs":59}],46:[function(require,module,exports){
2479 | "use strict";
2480 | Object.defineProperty(exports, "__esModule", { value: true });
2481 | exports.random = exports.RandomExpr = void 0;
2482 | const glslfunctions_1 = require("../glslfunctions");
2483 | const expr_1 = require("./expr");
2484 | const normfragcoordexpr_1 = require("./normfragcoordexpr");
2485 | /** psuedorandom number expression */
2486 | class RandomExpr extends expr_1.ExprFloat {
2487 | constructor(seed = normfragcoordexpr_1.pos()) {
2488 | super(expr_1.tag `random(${seed})`, ["uSeed"]);
2489 | this.seed = seed;
2490 | this.externalFuncs = [glslfunctions_1.glslFuncs.random];
2491 | }
2492 | /** sets the seed (vary this over time to get a moving effect) */
2493 | setSeed(seed) {
2494 | this.setUniform("uSeed", seed);
2495 | this.seed = seed;
2496 | }
2497 | }
2498 | exports.RandomExpr = RandomExpr;
2499 | /**
2500 | * creates expression that evaluates to a pseudorandom number between 0 and 1
2501 | * @param seed vec2 to to seed the random number (defaults to the normalized
2502 | * frag coord)
2503 | */
2504 | function random(seed) {
2505 | return new RandomExpr(seed);
2506 | }
2507 | exports.random = random;
2508 |
2509 | },{"../glslfunctions":61,"./expr":25,"./normfragcoordexpr":41}],47:[function(require,module,exports){
2510 | "use strict";
2511 | Object.defineProperty(exports, "__esModule", { value: true });
2512 | exports.region = void 0;
2513 | const mergepass_1 = require("../mergepass");
2514 | const expr_1 = require("./expr");
2515 | const getcompexpr_1 = require("./getcompexpr");
2516 | const normfragcoordexpr_1 = require("./normfragcoordexpr");
2517 | const opexpr_1 = require("./opexpr");
2518 | const ternaryexpr_1 = require("./ternaryexpr");
2519 | const fragcolorexpr_1 = require("./fragcolorexpr");
2520 | // form: x1, y1, x2, y2
2521 | function createDifferenceFloats(floats) {
2522 | const axes = "xy";
2523 | const differences = [];
2524 | if (floats.length !== 4) {
2525 | throw new Error("incorrect amount of points specified for region");
2526 | }
2527 | for (let i = 0; i < 2; i++) {
2528 | differences.push(opexpr_1.op(getcompexpr_1.getcomp(normfragcoordexpr_1.pos(), axes[i]), "-", floats[i]));
2529 | }
2530 | for (let i = 2; i < floats.length; i++) {
2531 | differences.push(opexpr_1.op(floats[i], "-", getcompexpr_1.getcomp(normfragcoordexpr_1.pos(), axes[i - 2])));
2532 | }
2533 | return differences;
2534 | }
2535 | /**
2536 | * restrict an effect to a region of the screen
2537 | * @param space top left, top right, bottom left, bottom right corners of the
2538 | * region, or just a number if you wish to sample from a channel as the region
2539 | * @param success expression for being inside the region
2540 | * @param failure expression for being outside the region
2541 | * @param not whether to invert the region
2542 | */
2543 | function region(space, success, failure, not = false) {
2544 | const floats = Array.isArray(space)
2545 | ? space.map((f) => expr_1.wrapInValue(f))
2546 | : typeof space === "number"
2547 | ? expr_1.wrapInValue(space)
2548 | : space;
2549 | if (failure instanceof mergepass_1.EffectLoop) {
2550 | if (!(success instanceof mergepass_1.EffectLoop)) {
2551 | [success, failure] = [failure, success]; // swap the order
2552 | not = !not; // invert the region
2553 | }
2554 | }
2555 | if (success instanceof mergepass_1.EffectLoop) {
2556 | if (!(failure instanceof mergepass_1.EffectLoop)) {
2557 | return success.regionWrap(floats, failure, true, not);
2558 | }
2559 | // double loop, so we have to do separately
2560 | return mergepass_1.loop([
2561 | success.regionWrap(floats, fragcolorexpr_1.fcolor(), false, not),
2562 | failure.regionWrap(floats, fragcolorexpr_1.fcolor(), true, !not),
2563 | ]);
2564 | }
2565 | return ternaryexpr_1.ternary(Array.isArray(floats) ? createDifferenceFloats(floats) : floats, success.brandExprWithRegion(floats), failure.brandExprWithRegion(floats), not);
2566 | }
2567 | exports.region = region;
2568 |
2569 | },{"../mergepass":63,"./expr":25,"./fragcolorexpr":26,"./getcompexpr":30,"./normfragcoordexpr":41,"./opexpr":43,"./ternaryexpr":55}],48:[function(require,module,exports){
2570 | "use strict";
2571 | Object.defineProperty(exports, "__esModule", { value: true });
2572 | exports.resolution = exports.ResolutionExpr = void 0;
2573 | const expr_1 = require("./expr");
2574 | /** resolution expression */
2575 | class ResolutionExpr extends expr_1.ExprVec2 {
2576 | constructor() {
2577 | super(expr_1.tag `uResolution`, []);
2578 | }
2579 | }
2580 | exports.ResolutionExpr = ResolutionExpr;
2581 | /** creates an expression that evaluates to a vector representing the resolution */
2582 | function resolution() {
2583 | return new ResolutionExpr();
2584 | }
2585 | exports.resolution = resolution;
2586 |
2587 | },{"./expr":25}],49:[function(require,module,exports){
2588 | "use strict";
2589 | Object.defineProperty(exports, "__esModule", { value: true });
2590 | exports.rgb2hsv = exports.RGBToHSVExpr = void 0;
2591 | const expr_1 = require("./expr");
2592 | const glslfunctions_1 = require("../glslfunctions");
2593 | /** RGB to HSV expression */
2594 | class RGBToHSVExpr extends expr_1.ExprVec4 {
2595 | constructor(color) {
2596 | super(expr_1.tag `rgb2hsv(${color})`, ["uRGBCol"]);
2597 | this.color = color;
2598 | this.externalFuncs = [glslfunctions_1.glslFuncs.rgb2hsv];
2599 | }
2600 | /** sets the color to convert */
2601 | setColor(color) {
2602 | this.setUniform("uRGBCol", color);
2603 | this.color = color;
2604 | }
2605 | }
2606 | exports.RGBToHSVExpr = RGBToHSVExpr;
2607 | /**
2608 | * creates an expression that converts a color (with an alpha component) from
2609 | * rgb to hsv
2610 | * @param col the rgba color to convert to hsva
2611 | */
2612 | function rgb2hsv(col) {
2613 | return new RGBToHSVExpr(col);
2614 | }
2615 | exports.rgb2hsv = rgb2hsv;
2616 |
2617 | },{"../glslfunctions":61,"./expr":25}],50:[function(require,module,exports){
2618 | "use strict";
2619 | Object.defineProperty(exports, "__esModule", { value: true });
2620 | exports.rotate = exports.RotateExpr = void 0;
2621 | const glslfunctions_1 = require("../glslfunctions");
2622 | const expr_1 = require("./expr");
2623 | /** rotate expression */
2624 | class RotateExpr extends expr_1.ExprVec2 {
2625 | constructor(vec, angle) {
2626 | super(expr_1.tag `rotate2d(${vec}, ${angle})`, ["uVec", "uAngle"]);
2627 | this.vec = vec;
2628 | this.angle = angle;
2629 | this.externalFuncs = [glslfunctions_1.glslFuncs.rotate2d];
2630 | }
2631 | /** set the vector to rotate */
2632 | setVec(vec) {
2633 | this.setUniform("uVec" + this.id, vec);
2634 | this.vec = vec;
2635 | }
2636 | /** set the angle to rotate by */
2637 | setAngle(angle) {
2638 | this.setUniform("uAngle" + this.id, angle);
2639 | this.angle = expr_1.wrapInValue(angle);
2640 | }
2641 | }
2642 | exports.RotateExpr = RotateExpr;
2643 | /**
2644 | * creates an expression that rotates a vector by a given angle
2645 | * @param vec the vector to rotate
2646 | * @param angle radians to rotate vector by
2647 | */
2648 | function rotate(vec, angle) {
2649 | return new RotateExpr(vec, expr_1.wrapInValue(angle));
2650 | }
2651 | exports.rotate = rotate;
2652 |
2653 | },{"../glslfunctions":61,"./expr":25}],51:[function(require,module,exports){
2654 | "use strict";
2655 | Object.defineProperty(exports, "__esModule", { value: true });
2656 | exports.input = exports.SceneSampleExpr = void 0;
2657 | const expr_1 = require("./expr");
2658 | const normfragcoordexpr_1 = require("./normfragcoordexpr");
2659 | /** scene sample expression */
2660 | class SceneSampleExpr extends expr_1.ExprVec4 {
2661 | constructor(coord = normfragcoordexpr_1.pos()) {
2662 | super(expr_1.tag `texture2D(uSceneSampler, ${coord})`, ["uCoord"]);
2663 | this.coord = coord;
2664 | this.needs.sceneBuffer = true;
2665 | }
2666 | /** sets coordinate where scene is being sampled from */
2667 | setCoord(coord) {
2668 | this.setUniform("uCoord", coord);
2669 | this.coord = coord;
2670 | }
2671 | }
2672 | exports.SceneSampleExpr = SceneSampleExpr;
2673 | /**
2674 | * creates an expression that samples the original scene
2675 | * @param vec where to sample the original scene texture (defaults to the
2676 | * normalized frag coord, but change this if you want to transform the
2677 | * coordinate space of the original image)
2678 | */
2679 | function input(vec) {
2680 | return new SceneSampleExpr(vec);
2681 | }
2682 | exports.input = input;
2683 |
2684 | },{"./expr":25,"./normfragcoordexpr":41}],52:[function(require,module,exports){
2685 | "use strict";
2686 | Object.defineProperty(exports, "__esModule", { value: true });
2687 | exports.SetColorExpr = void 0;
2688 | const expr_1 = require("./expr");
2689 | /**
2690 | * set fragment color expression (not needed for the user; used internally for
2691 | * wrapping any kind of [[Vec4]] in an [[ExprVec4]])
2692 | */
2693 | class SetColorExpr extends expr_1.ExprVec4 {
2694 | constructor(vec) {
2695 | super(expr_1.tag `(${vec})`, ["uVal"]);
2696 | this.vec = vec;
2697 | }
2698 | }
2699 | exports.SetColorExpr = SetColorExpr;
2700 |
2701 | },{"./expr":25}],53:[function(require,module,exports){
2702 | "use strict";
2703 | Object.defineProperty(exports, "__esModule", { value: true });
2704 | exports.simplex = exports.SimplexNoise = void 0;
2705 | const glslfunctions_1 = require("../glslfunctions");
2706 | const expr_1 = require("./expr");
2707 | /** simplex noise expression */
2708 | class SimplexNoise extends expr_1.ExprFloat {
2709 | constructor(pos) {
2710 | super(expr_1.tag `simplexnoise(${pos})`, ["uPos"]);
2711 | this.pos = pos;
2712 | this.externalFuncs = [glslfunctions_1.glslFuncs.simplexhelpers, glslfunctions_1.glslFuncs.simplexnoise];
2713 | }
2714 | setPos(pos) {
2715 | this.setUniform("uPos", pos);
2716 | this.pos = pos;
2717 | }
2718 | }
2719 | exports.SimplexNoise = SimplexNoise;
2720 | /**
2721 | * creates a simplex noise expression; values range from -1 to 1
2722 | * @param pos position
2723 | */
2724 | function simplex(pos) {
2725 | return new SimplexNoise(pos);
2726 | }
2727 | exports.simplex = simplex;
2728 |
2729 | },{"../glslfunctions":61,"./expr":25}],54:[function(require,module,exports){
2730 | "use strict";
2731 | Object.defineProperty(exports, "__esModule", { value: true });
2732 | exports.sobel = exports.SobelExpr = void 0;
2733 | const glslfunctions_1 = require("../glslfunctions");
2734 | const expr_1 = require("./expr");
2735 | /** Sobel edge detection expression */
2736 | class SobelExpr extends expr_1.ExprVec4 {
2737 | constructor(samplerNum) {
2738 | super(expr_1.tag `sobel()`, []);
2739 | this.externalFuncs = [glslfunctions_1.glslFuncs.sobel];
2740 | this.brandExprWithChannel(0, samplerNum);
2741 | }
2742 | }
2743 | exports.SobelExpr = SobelExpr;
2744 | /**
2745 | * creates a Sobel edge detection expression that outputs the raw result; for
2746 | * more highly processed edge detection expressions, see [[edgecolor]] or
2747 | * [[edge]]
2748 | * @param samplerNum where to sample from
2749 | */
2750 | function sobel(samplerNum) {
2751 | return new SobelExpr(samplerNum);
2752 | }
2753 | exports.sobel = sobel;
2754 |
2755 | },{"../glslfunctions":61,"./expr":25}],55:[function(require,module,exports){
2756 | "use strict";
2757 | Object.defineProperty(exports, "__esModule", { value: true });
2758 | exports.ternary = exports.TernaryExpr = void 0;
2759 | const expr_1 = require("./expr");
2760 | function genTernarySourceList(floats, success, failure, not) {
2761 | const sourceList = {
2762 | sections: [`(${not ? "!" : ""}(`],
2763 | values: [],
2764 | };
2765 | let counter = 0;
2766 | // generate the boolean expression
2767 | if (floats !== null) {
2768 | for (const f of floats) {
2769 | counter++;
2770 | const last = counter === floats.length;
2771 | sourceList.values.push(f);
2772 | sourceList.sections.push(` > 0.${last ? ") ? " : " && "}`);
2773 | }
2774 | }
2775 | else {
2776 | sourceList.sections[0] += "uCount == 0) ? ";
2777 | }
2778 | // generate the success expression and colon
2779 | sourceList.values.push(success);
2780 | sourceList.sections.push(" : ");
2781 | // generate the failure expression
2782 | sourceList.values.push(failure);
2783 | sourceList.sections.push(")");
2784 | return sourceList;
2785 | }
2786 | class TernaryExpr extends expr_1.Operator {
2787 | constructor(floats, success, failure, not) {
2788 | super(success, genTernarySourceList(floats, success, failure, not), [
2789 | ...(floats !== null
2790 | ? Array.from(floats, (val, index) => "uFloat" + index)
2791 | : []),
2792 | "uSuccess",
2793 | "uFailure",
2794 | ]);
2795 | this.success = success;
2796 | this.failure = failure;
2797 | this.needs.passCount = floats === null;
2798 | }
2799 | }
2800 | exports.TernaryExpr = TernaryExpr;
2801 | /**
2802 | * creates a ternary expression; the boolean expression is if all the floats
2803 | * given are greater than 0
2804 | * @param floats if all these floats (or the single float) are above 0, then
2805 | * evaluates to success expression
2806 | * @param success
2807 | * @param failure
2808 | * @param not whether to invert the ternary
2809 | */
2810 | function ternary(floats, success, failure, not = false) {
2811 | // TODO make this type safe (ran into a type error here)
2812 | // wrap single float in array if need be
2813 | if (!Array.isArray(floats) && floats !== null)
2814 | floats = [floats].map((f) => expr_1.wrapInValue(f));
2815 | // TODO get rid of this cast
2816 | return new TernaryExpr(floats, expr_1.wrapInValue(success), expr_1.wrapInValue(failure), not);
2817 | }
2818 | exports.ternary = ternary;
2819 |
2820 | },{"./expr":25}],56:[function(require,module,exports){
2821 | "use strict";
2822 | Object.defineProperty(exports, "__esModule", { value: true });
2823 | exports.time = exports.TimeExpr = void 0;
2824 | const expr_1 = require("./expr");
2825 | /** time expression */
2826 | class TimeExpr extends expr_1.ExprFloat {
2827 | constructor() {
2828 | super(expr_1.tag `uTime`, []);
2829 | this.needs.timeUniform = true;
2830 | }
2831 | }
2832 | exports.TimeExpr = TimeExpr;
2833 | /** creates a time expression that evaluates to the current time */
2834 | function time() {
2835 | return new TimeExpr();
2836 | }
2837 | exports.time = time;
2838 |
2839 | },{"./expr":25}],57:[function(require,module,exports){
2840 | "use strict";
2841 | Object.defineProperty(exports, "__esModule", { value: true });
2842 | exports.translate = exports.TranslateExpr = void 0;
2843 | const expr_1 = require("./expr");
2844 | // really just adding two vecs together, but it might be confusing that there's
2845 | // rotate but no translate, so this is included. also it could make some
2846 | // operations more readable
2847 | /** sets the translate expression */
2848 | class TranslateExpr extends expr_1.ExprVec2 {
2849 | constructor(vec, pos) {
2850 | super(expr_1.tag `(${vec} + ${pos})`, ["uVec", "uPos"]);
2851 | this.vec = vec;
2852 | this.pos = pos;
2853 | }
2854 | /** sets the starting position */
2855 | setVec(vec) {
2856 | this.setUniform("uVec" + this.id, vec);
2857 | this.vec = vec;
2858 | }
2859 | /** sets how far the vector will be translated */
2860 | setPos(pos) {
2861 | this.setUniform("uPos" + this.id, pos);
2862 | this.pos = pos;
2863 | }
2864 | }
2865 | exports.TranslateExpr = TranslateExpr;
2866 | /** translates the position of a vector by another vector */
2867 | function translate(vec, pos) {
2868 | return new TranslateExpr(vec, pos);
2869 | }
2870 | exports.translate = translate;
2871 |
2872 | },{"./expr":25}],58:[function(require,module,exports){
2873 | "use strict";
2874 | Object.defineProperty(exports, "__esModule", { value: true });
2875 | exports.truedepth = exports.TrueDepthExpr = void 0;
2876 | const expr_1 = require("./expr");
2877 | const glslfunctions_1 = require("../glslfunctions");
2878 | /** true depth expression */
2879 | class TrueDepthExpr extends expr_1.ExprFloat {
2880 | constructor(depth) {
2881 | super(expr_1.tag `truedepth(${depth})`, ["uDist"]);
2882 | this.depth = depth;
2883 | this.externalFuncs = [glslfunctions_1.glslFuncs.truedepth];
2884 | }
2885 | /** sets the distance to convert to the true depth */
2886 | setDist(depth) {
2887 | this.setUniform("uDist", depth);
2888 | this.depth = expr_1.wrapInValue(depth);
2889 | }
2890 | }
2891 | exports.TrueDepthExpr = TrueDepthExpr;
2892 | /** calculates the linear depth from inverse depth value `1 / distance` */
2893 | function truedepth(depth) {
2894 | return new TrueDepthExpr(expr_1.wrapInValue(depth));
2895 | }
2896 | exports.truedepth = truedepth;
2897 |
2898 | },{"../glslfunctions":61,"./expr":25}],59:[function(require,module,exports){
2899 | "use strict";
2900 | Object.defineProperty(exports, "__esModule", { value: true });
2901 | exports.pvec4 = exports.pvec3 = exports.pvec2 = exports.vec4 = exports.vec3 = exports.vec2 = void 0;
2902 | const expr_1 = require("./expr");
2903 | /** @ignore */
2904 | function vecSourceList(...components) {
2905 | const sections = ["vec" + components.length + "("];
2906 | for (let i = 0; i < components.length - 1; i++) {
2907 | sections.push(", ");
2908 | }
2909 | const defaultNames = [];
2910 | for (let i = 0; i < components.length; i++) {
2911 | defaultNames.push("uComp" + i);
2912 | }
2913 | sections.push(")");
2914 | return [{ sections: sections, values: components }, defaultNames];
2915 | }
2916 | // expression vector shorthands
2917 | /** creates a basic vec2 expression */
2918 | function vec2(comp1, comp2) {
2919 | return new expr_1.BasicVec2(...vecSourceList(...[comp1, comp2].map((c) => expr_1.wrapInValue(c))));
2920 | }
2921 | exports.vec2 = vec2;
2922 | /** creates a basic vec3 expression */
2923 | function vec3(comp1, comp2, comp3) {
2924 | return new expr_1.BasicVec3(...vecSourceList(...[comp1, comp2, comp3].map((c) => expr_1.wrapInValue(c))));
2925 | }
2926 | exports.vec3 = vec3;
2927 | /** creates a basic vec4 expression */
2928 | function vec4(comp1, comp2, comp3, comp4) {
2929 | return new expr_1.BasicVec4(...vecSourceList(...[comp1, comp2, comp3, comp4].map((c) => expr_1.wrapInValue(c))));
2930 | }
2931 | exports.vec4 = vec4;
2932 | // primitive vector shorthands
2933 | /** creates a primitive vec2 expression */
2934 | function pvec2(comp1, comp2) {
2935 | return new expr_1.PrimitiveVec2([comp1, comp2]);
2936 | }
2937 | exports.pvec2 = pvec2;
2938 | /** creates a primitive vec3 expression */
2939 | function pvec3(comp1, comp2, comp3) {
2940 | return new expr_1.PrimitiveVec3([comp1, comp2, comp3]);
2941 | }
2942 | exports.pvec3 = pvec3;
2943 | /** creates a primitive vec4 expression */
2944 | function pvec4(comp1, comp2, comp3, comp4) {
2945 | return new expr_1.PrimitiveVec4([comp1, comp2, comp3, comp4]);
2946 | }
2947 | exports.pvec4 = pvec4;
2948 |
2949 | },{"./expr":25}],60:[function(require,module,exports){
2950 | "use strict";
2951 | Object.defineProperty(exports, "__esModule", { value: true });
2952 |
2953 | },{}],61:[function(require,module,exports){
2954 | "use strict";
2955 | Object.defineProperty(exports, "__esModule", { value: true });
2956 | exports.glslFuncs = void 0;
2957 | // adapted from The Book of Shaders
2958 | /** glsl source code for external functions */
2959 | exports.glslFuncs = {
2960 | // TODO bad to calculate single pixel width every time; maybe it can be a need
2961 | texture2D_region: `vec4 texture2D_region(
2962 | float r_x_min,
2963 | float r_y_min,
2964 | float r_x_max,
2965 | float r_y_max,
2966 | sampler2D sampler,
2967 | vec2 uv
2968 | ) {
2969 | vec2 d = vec2(1., 1.) / uResolution; // pixel width
2970 | return texture2D(sampler, clamp(uv, vec2(r_x_min + d.x, r_y_min + d.x), vec2(r_x_max - d.y, r_y_max - d.y)));
2971 | }`,
2972 | // TODO replace with a better one
2973 | // adapted from The Book of Shaders
2974 | random: `float random(vec2 st) {
2975 | return fract(sin(dot(st.xy / 99., vec2(12.9898, 78.233))) * 43758.5453123);
2976 | }`,
2977 | // adapted from The Book of Shaders
2978 | random2: `vec2 random2(vec2 st) {
2979 | st = vec2(dot(st,vec2(127.1,311.7)), dot(st,vec2(269.5,183.3)));
2980 | return -1.0 + 2.0*fract(sin(st)*43758.5453123);
2981 | }`,
2982 | rotate2d: `vec2 rotate2d(vec2 v, float angle) {
2983 | return mat2(cos(angle), -sin(angle), sin(angle), cos(angle)) * v;
2984 | }`,
2985 | // adapted from The Book of Shaders
2986 | hsv2rgb: `vec4 hsv2rgb(vec4 co){
2987 | vec3 c = co.xyz;
2988 | vec3 rgb = clamp(abs(mod(
2989 | c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
2990 | rgb = rgb * rgb * (3.0 - 2.0 * rgb);
2991 | vec3 hsv = c.z * mix(vec3(1.0), rgb, c.y);
2992 | return vec4(hsv.x, hsv.y, hsv.z, co.a);
2993 | }`,
2994 | // adapted from The Book of Shaders
2995 | rgb2hsv: `vec4 rgb2hsv(vec4 co){
2996 | vec3 c = co.rgb;
2997 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
2998 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
2999 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
3000 | float d = q.x - min(q.w, q.y);
3001 | float e = 1.0e-10;
3002 | return vec4(abs(q.z + (q.w - q.y) / (6.0 * d + e)),
3003 | d / (q.x + e),
3004 | q.x, co.a);
3005 | }`,
3006 | // all gaussian blurs adapted from:
3007 | // https://github.com/Jam3/glsl-fast-gaussian-blur/blob/master/5.glsl
3008 | gauss5: `vec4 gauss5(vec2 dir) {
3009 | vec2 uv = gl_FragCoord.xy / uResolution;
3010 | vec4 col = vec4(0.0);
3011 | vec2 off1 = vec2(1.3333333333333333) * dir;
3012 | col += texture2D(uSampler, uv) * 0.29411764705882354;
3013 | col += texture2D(uSampler, uv + (off1 / uResolution)) * 0.35294117647058826;
3014 | col += texture2D(uSampler, uv - (off1 / uResolution)) * 0.35294117647058826;
3015 | return col;
3016 | }`,
3017 | gauss9: `vec4 gauss9(vec2 dir) {
3018 | vec2 uv = gl_FragCoord.xy / uResolution;
3019 | vec4 col = vec4(0.0);
3020 | vec2 off1 = vec2(1.3846153846) * dir;
3021 | vec2 off2 = vec2(3.2307692308) * dir;
3022 | col += texture2D(uSampler, uv) * 0.2270270270;
3023 | col += texture2D(uSampler, uv + (off1 / uResolution)) * 0.3162162162;
3024 | col += texture2D(uSampler, uv - (off1 / uResolution)) * 0.3162162162;
3025 | col += texture2D(uSampler, uv + (off2 / uResolution)) * 0.0702702703;
3026 | col += texture2D(uSampler, uv - (off2 / uResolution)) * 0.0702702703;
3027 | return col;
3028 | }`,
3029 | gauss13: `vec4 gauss13(vec2 dir) {
3030 | vec2 uv = gl_FragCoord.xy / uResolution;
3031 | vec4 col = vec4(0.0);
3032 | vec2 off1 = vec2(1.411764705882353) * dir;
3033 | vec2 off2 = vec2(3.2941176470588234) * dir;
3034 | vec2 off3 = vec2(5.176470588235294) * dir;
3035 | col += texture2D(uSampler, uv) * 0.1964825501511404;
3036 | col += texture2D(uSampler, uv + (off1 / uResolution)) * 0.2969069646728344;
3037 | col += texture2D(uSampler, uv - (off1 / uResolution)) * 0.2969069646728344;
3038 | col += texture2D(uSampler, uv + (off2 / uResolution)) * 0.09447039785044732;
3039 | col += texture2D(uSampler, uv - (off2 / uResolution)) * 0.09447039785044732;
3040 | col += texture2D(uSampler, uv + (off3 / uResolution)) * 0.010381362401148057;
3041 | col += texture2D(uSampler, uv - (off3 / uResolution)) * 0.010381362401148057;
3042 | return col;
3043 | }`,
3044 | contrast: `vec4 contrast(float val, vec4 col) {
3045 | col.rgb /= col.a;
3046 | col.rgb = ((col.rgb - 0.5) * val) + 0.5;
3047 | col.rgb *= col.a;
3048 | return col;
3049 | }`,
3050 | brightness: `vec4 brightness(float val, vec4 col) {
3051 | col.rgb /= col.a;
3052 | col.rgb += val;
3053 | col.rgb *= col.a;
3054 | return col;
3055 | }`,
3056 | // adapted from https://www.shadertoy.com/view/ls3GWS which was adapted from
3057 | // http://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-opengl-test-radeon-geforce/3/
3058 | // original algorithm created by Timothy Lottes
3059 | fxaa: `vec4 fxaa() {
3060 | float FXAA_SPAN_MAX = 8.0;
3061 | float FXAA_REDUCE_MUL = 1.0 / FXAA_SPAN_MAX;
3062 | float FXAA_REDUCE_MIN = 1.0 / 128.0;
3063 | float FXAA_SUBPIX_SHIFT = 1.0 / 4.0;
3064 |
3065 | vec2 rcpFrame = 1. / uResolution.xy;
3066 | vec2 t_uv = gl_FragCoord.xy / uResolution.xy;
3067 | vec4 uv = vec4(t_uv, t_uv - (rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT)));
3068 |
3069 | vec3 rgbNW = texture2D(uSampler, uv.zw).xyz;
3070 | vec3 rgbNE = texture2D(uSampler, uv.zw + vec2(1,0) * rcpFrame.xy).xyz;
3071 | vec3 rgbSW = texture2D(uSampler, uv.zw + vec2(0,1) * rcpFrame.xy).xyz;
3072 | vec3 rgbSE = texture2D(uSampler, uv.zw + vec2(1,1) * rcpFrame.xy).xyz;
3073 | vec4 rgbMfull = texture2D(uSampler, uv.xy);
3074 | vec3 rgbM = rgbMfull.xyz;
3075 | float alpha = rgbMfull.a;
3076 |
3077 | vec3 luma = vec3(0.299, 0.587, 0.114);
3078 | float lumaNW = dot(rgbNW, luma);
3079 | float lumaNE = dot(rgbNE, luma);
3080 | float lumaSW = dot(rgbSW, luma);
3081 | float lumaSE = dot(rgbSE, luma);
3082 | float lumaM = dot(rgbM, luma);
3083 |
3084 | float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
3085 | float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
3086 |
3087 | vec2 dir;
3088 | dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
3089 | dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
3090 |
3091 | float dirReduce = max(
3092 | (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
3093 | float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
3094 |
3095 | dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
3096 | max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
3097 | dir * rcpDirMin)) * rcpFrame.xy;
3098 |
3099 | vec3 rgbA = (1.0 / 2.0) * (
3100 | texture2D(uSampler, uv.xy + dir * (1.0 / 3.0 - 0.5)).xyz +
3101 | texture2D(uSampler, uv.xy + dir * (2.0 / 3.0 - 0.5)).xyz);
3102 | vec3 rgbB = rgbA * (1.0 / 2.0) + (1.0 / 4.0) * (
3103 | texture2D(uSampler, uv.xy + dir * (0.0 / 3.0 - 0.5)).xyz +
3104 | texture2D(uSampler, uv.xy + dir * (3.0 / 3.0 - 0.5)).xyz);
3105 |
3106 | float lumaB = dot(rgbB, luma);
3107 |
3108 | if (lumaB < lumaMin || lumaB > lumaMax) {
3109 | return vec4(rgbA.r, rgbA.g, rgbA.b, alpha);
3110 | }
3111 |
3112 | return vec4(rgbB.r, rgbB.g, rgbB.b, alpha);
3113 | }`,
3114 | // normal curve is a = 0 and b = 1
3115 | gaussian: `float gaussian(float x, float a, float b) {
3116 | float e = 2.71828;
3117 | return pow(e, -pow(x - a, 2.) / b);
3118 | }`,
3119 | // for calculating the true distance from 0 to 1 depth buffer
3120 | // the small delta is to prevent division by zero, which is undefined behavior
3121 | truedepth: `float truedepth(float i) {
3122 | i = max(i, 0.00000001);
3123 | return (1. - i) / i;
3124 | }`,
3125 | // based off of https://fabiensanglard.net/lightScattering/index.php
3126 | godrays: `vec4 godrays(
3127 | vec4 col,
3128 | float exposure,
3129 | float decay,
3130 | float density,
3131 | float weight,
3132 | vec2 lightPos,
3133 | float threshold,
3134 | vec4 newColor
3135 | ) {
3136 | vec2 texCoord = gl_FragCoord.xy / uResolution;
3137 | vec2 deltaTexCoord = texCoord - lightPos;
3138 |
3139 | const int NUM_SAMPLES = 100;
3140 | deltaTexCoord *= 1. / float(NUM_SAMPLES) * density;
3141 | float illuminationDecay = 1.0;
3142 |
3143 | for (int i=0; i < NUM_SAMPLES; i++) {
3144 | texCoord -= deltaTexCoord;
3145 | vec4 sample = texture2D(uSampler, texCoord);
3146 | //uncomment sample = depth2occlusion(sample, newColor, threshold);
3147 | sample *= illuminationDecay * weight;
3148 | col += sample;
3149 | illuminationDecay *= decay;
3150 | }
3151 | return col * exposure;
3152 | }`,
3153 | depth2occlusion: `vec4 depth2occlusion(vec4 depthCol, vec4 newCol, float threshold) {
3154 | float red = 1. - ceil(depthCol.r - threshold);
3155 | return vec4(newCol.rgb * red, 1.0);
3156 | }`,
3157 | // adapted from The Book of Shaders, which was adapted from Inigo Quilez
3158 | // from this example: https://www.shadertoy.com/view/XdXGW8
3159 | gradientnoise: `float gradientnoise(vec2 st) {
3160 | vec2 i = floor(st);
3161 | vec2 f = fract(st);
3162 |
3163 | vec2 u = f * f * (3.0 - 2.0 * f);
3164 |
3165 | return mix(mix(dot(random2(i + vec2(0.0,0.0)), f - vec2(0.0, 0.0)),
3166 | dot(random2(i + vec2(1.0,0.0)), f - vec2(1.0, 0.0)), u.x),
3167 | mix(dot(random2(i + vec2(0.0,1.0)), f - vec2(0.0, 1.0)),
3168 | dot(random2(i + vec2(1.0,1.0)), f - vec2(1.0, 1.0)), u.x), u.y);
3169 | }`,
3170 | // adapted from The Book of Shaders
3171 | // https://thebookofshaders.com/edit.php#11/2d-snoise-clear.frag
3172 | // this was adapted from this fast implementation
3173 | // https://github.com/ashima/webgl-noise
3174 | // simplex noise invented by Ken Perlin
3175 | simplexnoise: `float simplexnoise(vec2 v) {
3176 | // Precompute values for skewed triangular grid
3177 | const vec4 C = vec4(0.211324865405187,
3178 | // (3.0-sqrt(3.0))/6.0
3179 | 0.366025403784439,
3180 | // 0.5*(sqrt(3.0)-1.0)
3181 | -0.577350269189626,
3182 | // -1.0 + 2.0 * C.x
3183 | 0.024390243902439);
3184 | // 1.0 / 41.0
3185 |
3186 | // First corner (x0)
3187 | vec2 i = floor(v + dot(v, C.yy));
3188 | vec2 x0 = v - i + dot(i, C.xx);
3189 |
3190 | // Other two corners (x1, x2)
3191 | vec2 i1 = vec2(0.0);
3192 | i1 = (x0.x > x0.y)? vec2(1.0, 0.0):vec2(0.0, 1.0);
3193 | vec2 x1 = x0.xy + C.xx - i1;
3194 | vec2 x2 = x0.xy + C.zz;
3195 |
3196 | // Do some permutations to avoid
3197 | // truncation effects in permutation
3198 | i = mod289_2(i);
3199 | vec3 p = permute(
3200 | permute( i.y + vec3(0.0, i1.y, 1.0))
3201 | + i.x + vec3(0.0, i1.x, 1.0 ));
3202 |
3203 | vec3 m = max(0.5 - vec3(
3204 | dot(x0,x0),
3205 | dot(x1,x1),
3206 | dot(x2,x2)
3207 | ), 0.0);
3208 |
3209 | m = m*m ;
3210 | m = m*m ;
3211 |
3212 | // Gradients:
3213 | // 41 pts uniformly over a line, mapped onto a diamond
3214 | // The ring size 17*17 = 289 is close to a multiple
3215 | // of 41 (41*7 = 287)
3216 |
3217 | vec3 x = 2.0 * fract(p * C.www) - 1.0;
3218 | vec3 h = abs(x) - 0.5;
3219 | vec3 ox = floor(x + 0.5);
3220 | vec3 a0 = x - ox;
3221 |
3222 | // Normalise gradients implicitly by scaling m
3223 | // Approximation of: m *= inversesqrt(a0*a0 + h*h);
3224 | m *= 1.79284291400159 - 0.85373472095314 * (a0*a0+h*h);
3225 |
3226 | // Compute final noise value at P
3227 | vec3 g = vec3(0.0);
3228 | g.x = a0.x * x0.x + h.x * x0.y;
3229 | g.yz = a0.yz * vec2(x1.x,x2.x) + h.yz * vec2(x1.y,x2.y);
3230 | return 130.0 * dot(m, g);
3231 | }`,
3232 | // only useful for simplex noise
3233 | simplexhelpers: `vec3 mod289_3(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
3234 | vec2 mod289_2(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
3235 | vec3 permute(vec3 x) { return mod289_3(((x*34.0)+1.0)*x); }`,
3236 | // sobel adapted from https://gist.github.com/Hebali/6ebfc66106459aacee6a9fac029d0115
3237 | sobel: `vec4 sobel() {
3238 | vec2 uv = gl_FragCoord.xy / uResolution;
3239 | vec4 k[8];
3240 |
3241 | float w = 1. / uResolution.x;
3242 | float h = 1. / uResolution.y;
3243 |
3244 | k[0] = texture2D(uSampler, uv + vec2(-w, -h));
3245 | k[1] = texture2D(uSampler, uv + vec2(0., -h));
3246 | k[2] = texture2D(uSampler, uv + vec2(w, -h));
3247 | k[3] = texture2D(uSampler, uv + vec2(-w, 0.));
3248 |
3249 | k[4] = texture2D(uSampler, uv + vec2(w, 0.));
3250 | k[5] = texture2D(uSampler, uv + vec2(-w, h));
3251 | k[6] = texture2D(uSampler, uv + vec2(0., h));
3252 | k[7] = texture2D(uSampler, uv + vec2(w, h));
3253 |
3254 | vec4 edge_h = k[2] + (2. * k[4]) + k[7] - (k[0] + (2. * k[3]) + k[5]);
3255 | vec4 edge_v = k[0] + (2. * k[1]) + k[2] - (k[5] + (2. * k[6]) + k[7]);
3256 | vec4 sob = sqrt(edge_h * edge_h + edge_v * edge_v);
3257 |
3258 | return vec4(1. - sob.rgb, 1.);
3259 | }`,
3260 | // inlining a similar function will substitute in the full expression for
3261 | // every component, so it's more efficient to have a function
3262 | monochrome: `vec4 monochrome(vec4 col) {
3263 | return vec4(vec3((col.r + col.g + col.b) / 3.), col.a);
3264 | }`,
3265 | invert: `vec4 invert(vec4 col) {
3266 | return vec4(vec3(1., 1., 1.) - col.rgb, col.a);
3267 | }`,
3268 | channel: `vec4 channel(vec2 uv, sampler2D sampler) {
3269 | return texture2D(sampler, uv);
3270 | }`,
3271 | };
3272 |
3273 | },{}],62:[function(require,module,exports){
3274 | "use strict";
3275 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3276 | if (k2 === undefined) k2 = k;
3277 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
3278 | }) : (function(o, m, k, k2) {
3279 | if (k2 === undefined) k2 = k;
3280 | o[k2] = m[k];
3281 | }));
3282 | var __exportStar = (this && this.__exportStar) || function(m, exports) {
3283 | for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
3284 | };
3285 | Object.defineProperty(exports, "__esModule", { value: true });
3286 | __exportStar(require("./mergepass"), exports);
3287 | __exportStar(require("./exprtypes"), exports);
3288 | __exportStar(require("./glslfunctions"), exports);
3289 | __exportStar(require("./settings"), exports);
3290 | __exportStar(require("./exprs/blurexpr"), exports);
3291 | __exportStar(require("./exprs/fragcolorexpr"), exports);
3292 | __exportStar(require("./exprs/vecexprs"), exports);
3293 | __exportStar(require("./exprs/opexpr"), exports);
3294 | __exportStar(require("./exprs/powerblur"), exports);
3295 | __exportStar(require("./exprs/blur2dloop"), exports);
3296 | __exportStar(require("./exprs/lenexpr"), exports);
3297 | __exportStar(require("./exprs/normexpr"), exports);
3298 | __exportStar(require("./exprs/fragcoordexpr"), exports);
3299 | __exportStar(require("./exprs/normfragcoordexpr"), exports);
3300 | __exportStar(require("./exprs/normcenterfragcoordexpr"), exports);
3301 | __exportStar(require("./exprs/scenesampleexpr"), exports);
3302 | __exportStar(require("./exprs/brightnessexpr"), exports);
3303 | __exportStar(require("./exprs/contrastexpr"), exports);
3304 | __exportStar(require("./exprs/grainexpr"), exports);
3305 | __exportStar(require("./exprs/getcompexpr"), exports);
3306 | __exportStar(require("./exprs/changecompexpr"), exports);
3307 | __exportStar(require("./exprs/rgbtohsvexpr"), exports);
3308 | __exportStar(require("./exprs/hsvtorgbexpr"), exports);
3309 | __exportStar(require("./exprs/timeexpr"), exports);
3310 | __exportStar(require("./exprs/arity1"), exports);
3311 | __exportStar(require("./exprs/arity2"), exports);
3312 | __exportStar(require("./exprs/fxaaexpr"), exports);
3313 | __exportStar(require("./exprs/channelsampleexpr"), exports);
3314 | __exportStar(require("./exprs/dofloop"), exports);
3315 | __exportStar(require("./exprs/truedepthexpr"), exports);
3316 | __exportStar(require("./exprs/godraysexpr"), exports);
3317 | __exportStar(require("./exprs/depthtoocclusionexpr"), exports);
3318 | __exportStar(require("./exprs/resolutionexpr"), exports);
3319 | __exportStar(require("./exprs/mouseexpr"), exports);
3320 | __exportStar(require("./exprs/rotateexpr"), exports);
3321 | __exportStar(require("./exprs/translateexpr"), exports);
3322 | __exportStar(require("./exprs/normmouseexpr"), exports);
3323 | __exportStar(require("./exprs/perlinexpr"), exports);
3324 | __exportStar(require("./exprs/simplexexpr"), exports);
3325 | __exportStar(require("./exprs/motionblurloop"), exports);
3326 | __exportStar(require("./exprs/randomexpr"), exports);
3327 | __exportStar(require("./exprs/sobelexpr"), exports);
3328 | __exportStar(require("./exprs/bloomloop"), exports);
3329 | __exportStar(require("./exprs/monochromeexpr"), exports);
3330 | __exportStar(require("./exprs/invertexpr"), exports);
3331 | __exportStar(require("./exprs/edgeexpr"), exports);
3332 | __exportStar(require("./exprs/edgecolorexpr"), exports);
3333 | __exportStar(require("./exprs/ternaryexpr"), exports);
3334 | __exportStar(require("./exprs/regiondecorator"), exports);
3335 | __exportStar(require("./exprs/expr"), exports);
3336 |
3337 | },{"./exprs/arity1":12,"./exprs/arity2":13,"./exprs/bloomloop":14,"./exprs/blur2dloop":15,"./exprs/blurexpr":16,"./exprs/brightnessexpr":17,"./exprs/changecompexpr":18,"./exprs/channelsampleexpr":19,"./exprs/contrastexpr":20,"./exprs/depthtoocclusionexpr":21,"./exprs/dofloop":22,"./exprs/edgecolorexpr":23,"./exprs/edgeexpr":24,"./exprs/expr":25,"./exprs/fragcolorexpr":26,"./exprs/fragcoordexpr":27,"./exprs/fxaaexpr":28,"./exprs/getcompexpr":30,"./exprs/godraysexpr":31,"./exprs/grainexpr":32,"./exprs/hsvtorgbexpr":33,"./exprs/invertexpr":34,"./exprs/lenexpr":35,"./exprs/monochromeexpr":36,"./exprs/motionblurloop":37,"./exprs/mouseexpr":38,"./exprs/normcenterfragcoordexpr":39,"./exprs/normexpr":40,"./exprs/normfragcoordexpr":41,"./exprs/normmouseexpr":42,"./exprs/opexpr":43,"./exprs/perlinexpr":44,"./exprs/powerblur":45,"./exprs/randomexpr":46,"./exprs/regiondecorator":47,"./exprs/resolutionexpr":48,"./exprs/rgbtohsvexpr":49,"./exprs/rotateexpr":50,"./exprs/scenesampleexpr":51,"./exprs/simplexexpr":53,"./exprs/sobelexpr":54,"./exprs/ternaryexpr":55,"./exprs/timeexpr":56,"./exprs/translateexpr":57,"./exprs/truedepthexpr":58,"./exprs/vecexprs":59,"./exprtypes":60,"./glslfunctions":61,"./mergepass":63,"./settings":64}],63:[function(require,module,exports){
3338 | "use strict";
3339 | Object.defineProperty(exports, "__esModule", { value: true });
3340 | exports.sendTexture = exports.makeTexture = exports.Merger = exports.loop = exports.EffectLoop = exports.EffectDictionary = void 0;
3341 | const codebuilder_1 = require("./codebuilder");
3342 | const expr_1 = require("./exprs/expr");
3343 | const fragcolorexpr_1 = require("./exprs/fragcolorexpr");
3344 | const regiondecorator_1 = require("./exprs/regiondecorator");
3345 | const scenesampleexpr_1 = require("./exprs/scenesampleexpr");
3346 | const setcolorexpr_1 = require("./exprs/setcolorexpr");
3347 | const ternaryexpr_1 = require("./exprs/ternaryexpr");
3348 | const settings_1 = require("./settings");
3349 | const webglprogramloop_1 = require("./webglprogramloop");
3350 | function wrapInSetColors(effects) {
3351 | return effects.map((e) => e instanceof expr_1.ExprVec4 || e instanceof EffectLoop ? e : new setcolorexpr_1.SetColorExpr(e));
3352 | }
3353 | // should be function of loop?
3354 | function processEffectMap(eMap) {
3355 | const result = {};
3356 | for (const name in eMap) {
3357 | const val = eMap[name];
3358 | result[name] = wrapInSetColors(val);
3359 | }
3360 | return result;
3361 | }
3362 | class EffectDictionary {
3363 | constructor(effectMap) {
3364 | this.effectMap = processEffectMap(effectMap);
3365 | }
3366 | toProgramMap(gl, vShader, uniformLocs, fShaders) {
3367 | const programMap = {};
3368 | let needs = {
3369 | neighborSample: false,
3370 | centerSample: false,
3371 | sceneBuffer: false,
3372 | timeUniform: false,
3373 | mouseUniform: false,
3374 | passCount: false,
3375 | extraBuffers: new Set(),
3376 | };
3377 | for (const name in this.effectMap) {
3378 | const effects = this.effectMap[name];
3379 | // wrap the given list of effects as a loop if need be
3380 | const effectLoop = new EffectLoop(effects, { num: 1 });
3381 | if (effectLoop.effects.length === 0) {
3382 | throw new Error("list of effects was empty");
3383 | }
3384 | const programLoop = effectLoop.genPrograms(gl, vShader, uniformLocs, fShaders);
3385 | // walk the tree to the final program
3386 | let atBottom = false;
3387 | let currProgramLoop = programLoop;
3388 | while (!atBottom) {
3389 | if (currProgramLoop.programElement instanceof webglprogramloop_1.WebGLProgramLeaf) {
3390 | // we traveled right and hit a program, so it must be the last
3391 | currProgramLoop.last = true;
3392 | atBottom = true;
3393 | }
3394 | else {
3395 | // set the current program loop to the last in the list
3396 | currProgramLoop =
3397 | currProgramLoop.programElement[currProgramLoop.programElement.length - 1];
3398 | }
3399 | }
3400 | needs = webglprogramloop_1.updateNeeds(needs, programLoop.getTotalNeeds());
3401 | programMap[name] = programLoop;
3402 | }
3403 | return { programMap, needs };
3404 | }
3405 | }
3406 | exports.EffectDictionary = EffectDictionary;
3407 | /** effect loop, which can loop over other effects or effect loops */
3408 | class EffectLoop {
3409 | constructor(effects, loopInfo) {
3410 | this.effects = wrapInSetColors(effects);
3411 | this.loopInfo = loopInfo;
3412 | }
3413 | /** @ignore */
3414 | getSampleNum(mult = 1, sliceStart = 0, sliceEnd = this.effects.length) {
3415 | mult *= this.loopInfo.num;
3416 | let acc = 0;
3417 | const sliced = this.effects.slice(sliceStart, sliceEnd);
3418 | for (const e of sliced) {
3419 | acc += e.getSampleNum(mult);
3420 | }
3421 | return acc;
3422 | }
3423 | /**
3424 | * @ignore
3425 | * places effects into loops broken up by sampling effects
3426 | */
3427 | regroup() {
3428 | let sampleCount = 0;
3429 | /** number of samples in all previous */
3430 | let prevSampleCount = 0;
3431 | let prevEffects = [];
3432 | const regroupedEffects = [];
3433 | let prevTarget;
3434 | let currTarget;
3435 | let mustBreakCounter = 0;
3436 | const breakOff = () => {
3437 | mustBreakCounter--;
3438 | if (prevEffects.length > 0) {
3439 | // break off all previous effects into their own loop
3440 | if (prevEffects.length === 1) {
3441 | // this is to prevent wrapping in another effect loop
3442 | regroupedEffects.push(prevEffects[0]);
3443 | }
3444 | else {
3445 | regroupedEffects.push(new EffectLoop(prevEffects, { num: 1 }));
3446 | }
3447 | sampleCount -= prevSampleCount;
3448 | prevEffects = [];
3449 | }
3450 | };
3451 | for (const e of this.effects) {
3452 | const sampleNum = e.getSampleNum();
3453 | prevSampleCount = sampleCount;
3454 | sampleCount += sampleNum;
3455 | if (e instanceof EffectLoop) {
3456 | currTarget = e.loopInfo.target;
3457 | if (e.hasTargetSwitch()) {
3458 | mustBreakCounter = 2;
3459 | }
3460 | }
3461 | else {
3462 | // if it's not a loop it's assumed the target is that of outer loop
3463 | currTarget = this.loopInfo.target;
3464 | }
3465 | if (sampleCount > 0 ||
3466 | currTarget !== prevTarget ||
3467 | mustBreakCounter > 0) {
3468 | breakOff();
3469 | }
3470 | prevEffects.push(e);
3471 | prevTarget = currTarget;
3472 | }
3473 | // push on all the straggling effects after the grouping is done
3474 | breakOff();
3475 | return regroupedEffects;
3476 | }
3477 | genPrograms(gl, vShader, uniformLocs, shaders) {
3478 | // validate
3479 | const fullSampleNum = this.getSampleNum() / this.loopInfo.num;
3480 | const firstSampleNum = this.getSampleNum(undefined, 0, 1) / this.loopInfo.num;
3481 | const restSampleNum = this.getSampleNum(undefined, 1) / this.loopInfo.num;
3482 | if (!this.hasTargetSwitch() &&
3483 | (fullSampleNum === 0 || (firstSampleNum === 1 && restSampleNum === 0))) {
3484 | const codeBuilder = new codebuilder_1.CodeBuilder(this);
3485 | const program = codeBuilder.compileProgram(gl, vShader, uniformLocs, shaders);
3486 | return program;
3487 | }
3488 | // otherwise, regroup and try again on regrouped loops
3489 | this.effects = this.regroup();
3490 | return new webglprogramloop_1.WebGLProgramLoop(this.effects.map((e) => e.genPrograms(gl, vShader, uniformLocs, shaders)), this.loopInfo, gl);
3491 | }
3492 | /**
3493 | * changes the render target of an effect loop (-1 targest the scene texture;
3494 | * this is used internally)
3495 | */
3496 | target(num) {
3497 | this.loopInfo.target = num;
3498 | return this;
3499 | }
3500 | /** @ignore */
3501 | hasTargetSwitch() {
3502 | for (const e of this.effects) {
3503 | if (e instanceof EffectLoop) {
3504 | if (e.loopInfo.target !== this.loopInfo.target || e.hasTargetSwitch())
3505 | return true;
3506 | }
3507 | }
3508 | return false;
3509 | }
3510 | /** @ignore */
3511 | regionWrap(space, failure, finalPath = true, not) {
3512 | this.effects = this.effects.map((e, index) =>
3513 | // loops that aren't all the way to the right can't terminate the count ternery
3514 | // don't wrap fcolors in a ternery (it's redundant)
3515 | e instanceof EffectLoop
3516 | ? e.regionWrap(space, failure, index === this.effects.length - 1, not)
3517 | : new setcolorexpr_1.SetColorExpr(regiondecorator_1.region(space, e.brandExprWithRegion(space), index === this.effects.length - 1 && finalPath
3518 | ? !(failure instanceof fragcolorexpr_1.FragColorExpr)
3519 | ? ternaryexpr_1.ternary(null, failure, fragcolorexpr_1.fcolor())
3520 | : failure
3521 | : fragcolorexpr_1.fcolor(), not)));
3522 | return this;
3523 | }
3524 | }
3525 | exports.EffectLoop = EffectLoop;
3526 | /** creates an effect loop */
3527 | function loop(effects, rep = 1) {
3528 | return new EffectLoop(effects, { num: rep });
3529 | }
3530 | exports.loop = loop;
3531 | /** @ignore */
3532 | const V_SOURCE = `attribute vec2 aPosition;
3533 | void main() {
3534 | gl_Position = vec4(aPosition, 0.0, 1.0);
3535 | }\n`;
3536 | /** class that can merge effects */
3537 | class Merger {
3538 | /**
3539 | * constructs the object that runs the effects
3540 | * @param effects list of effects that define the final effect
3541 | * @param source the source image or texture
3542 | * @param gl the target rendering context
3543 | * @param options additional options for the texture
3544 | */
3545 | constructor(effects, source, gl, options) {
3546 | this.uniformLocs = {};
3547 | /** additional channels */
3548 | this.channels = [];
3549 | this.fShaders = [];
3550 | this.textureMode = source instanceof WebGLTexture;
3551 | // set channels if provided with channels
3552 | if ((options === null || options === void 0 ? void 0 : options.channels) !== undefined)
3553 | this.channels = options === null || options === void 0 ? void 0 : options.channels;
3554 | if (!(effects instanceof EffectDictionary)) {
3555 | effects = new EffectDictionary({ default: effects });
3556 | }
3557 | // add the copy to scene texture if in texture mode
3558 | if (this.textureMode) {
3559 | if (settings_1.settings.verbosity > 1) {
3560 | console.log("we are in texture mode!");
3561 | }
3562 | for (const name in effects.effectMap) {
3563 | const list = effects.effectMap[name];
3564 | list.unshift(loop([scenesampleexpr_1.input()]).target(-1));
3565 | }
3566 | }
3567 | this.source = source;
3568 | this.gl = gl;
3569 | this.options = options;
3570 | // set the viewport
3571 | this.gl.viewport(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight);
3572 | // set up the vertex buffer
3573 | const vertexBuffer = this.gl.createBuffer();
3574 | if (vertexBuffer === null) {
3575 | throw new Error("problem creating vertex buffer");
3576 | }
3577 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
3578 | const vertexArray = [-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1];
3579 | const triangles = new Float32Array(vertexArray);
3580 | this.gl.bufferData(this.gl.ARRAY_BUFFER, triangles, this.gl.STATIC_DRAW);
3581 | // save the vertex buffer reference just so we can delete it later
3582 | this.vertexBuffer = vertexBuffer;
3583 | // compile the simple vertex shader (2 big triangles)
3584 | const vShader = this.gl.createShader(this.gl.VERTEX_SHADER);
3585 | if (vShader === null) {
3586 | throw new Error("problem creating the vertex shader");
3587 | }
3588 | // save the vertex shader reference just so we can delete it later
3589 | this.vShader = vShader;
3590 | this.gl.shaderSource(vShader, V_SOURCE);
3591 | this.gl.compileShader(vShader);
3592 | // make textures
3593 | this.tex = {
3594 | // make the front texture the source if we're given a texture instead of
3595 | // an image
3596 | back: {
3597 | name: "orig_back",
3598 | tex: source instanceof WebGLTexture
3599 | ? source
3600 | : makeTexture(this.gl, this.options),
3601 | },
3602 | front: { name: "orig_front", tex: makeTexture(this.gl, this.options) },
3603 | scene: undefined,
3604 | bufTextures: [],
3605 | };
3606 | // create the framebuffer
3607 | const framebuffer = gl.createFramebuffer();
3608 | if (framebuffer === null) {
3609 | throw new Error("problem creating the framebuffer");
3610 | }
3611 | this.framebuffer = framebuffer;
3612 | const { programMap, needs } = effects.toProgramMap(this.gl, this.vShader, this.uniformLocs, this.fShaders);
3613 | this.programMap = programMap;
3614 | if (needs.sceneBuffer || this.textureMode) {
3615 | // we always create a scene texture if we're in texture mode
3616 | this.tex.scene = {
3617 | name: "scene",
3618 | tex: makeTexture(this.gl, this.options),
3619 | };
3620 | }
3621 | if (programMap["default"] === undefined) {
3622 | throw new Error("no default program");
3623 | }
3624 | this.programLoop = programMap["default"];
3625 | // create x amount of empty textures based on buffers needed
3626 | const channelsNeeded = Math.max(...needs.extraBuffers) + 1;
3627 | const channelsSupplied = this.channels.length;
3628 | if (channelsNeeded > channelsSupplied) {
3629 | throw new Error("not enough channels supplied for this effect");
3630 | }
3631 | for (let i = 0; i < this.channels.length; i++) {
3632 | const texOrImage = this.channels[i];
3633 | if (!(texOrImage instanceof WebGLTexture)) {
3634 | // create a new texture; we will update this with the image source every draw
3635 | const texture = makeTexture(this.gl, this.options);
3636 | this.tex.bufTextures.push({ name: "tex_channel_" + i, tex: texture });
3637 | }
3638 | else {
3639 | // this is already a texture; the user will handle updating this
3640 | this.tex.bufTextures.push({
3641 | name: "img_channel_" + i,
3642 | tex: texOrImage,
3643 | });
3644 | }
3645 | }
3646 | if (settings_1.settings.verbosity > 0) {
3647 | console.log(effects);
3648 | console.log(this.programMap);
3649 | }
3650 | }
3651 | /**
3652 | * use the source and channels to draw effect to target context; mouse
3653 | * position (as with all positions) are stored from the bottom left corner as
3654 | * this is how texture data is stored
3655 | * @param timeVal number to set the time uniform to (supply this if you plan to
3656 | * use [[time]])
3657 | * @param mouseX the x position of the mouse (supply this if you plan to use
3658 | * [[mouse]] or [[nmouse]])
3659 | * @param mouseY the y position of the mouse (supply this if you plan to use
3660 | * [[mouse]] or [[nmouse]])
3661 | */
3662 | draw(timeVal = 0, mouseX = 0, mouseY = 0) {
3663 | this.gl.activeTexture(this.gl.TEXTURE0 + settings_1.settings.offset);
3664 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.tex.back.tex);
3665 | sendTexture(this.gl, this.source);
3666 | // TODO only do unbinding and rebinding in texture mode
3667 | // TODO see if we need to unbind
3668 | this.gl.bindTexture(this.gl.TEXTURE_2D, null);
3669 | // bind the scene buffer
3670 | if (this.programLoop.getTotalNeeds().sceneBuffer &&
3671 | this.tex.scene !== undefined) {
3672 | this.gl.activeTexture(this.gl.TEXTURE1 + settings_1.settings.offset);
3673 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.tex.scene.tex);
3674 | sendTexture(this.gl, this.source);
3675 | // TODO see if we need to unbind
3676 | this.gl.bindTexture(this.gl.TEXTURE_2D, null);
3677 | }
3678 | // bind the additional buffers
3679 | let counter = 0;
3680 | for (const b of this.channels) {
3681 | // TODO check for texture limit
3682 | this.gl.activeTexture(this.gl.TEXTURE2 + counter + settings_1.settings.offset);
3683 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.tex.bufTextures[counter].tex);
3684 | sendTexture(this.gl, b);
3685 | // TODO see if we need to unbind (this gets rid of the error)
3686 | this.gl.bindTexture(this.gl.TEXTURE_2D, null);
3687 | counter++;
3688 | }
3689 | this.programLoop.run(this.gl, this.tex, this.framebuffer, this.uniformLocs, this.programLoop.last, { timeVal: timeVal, mouseX: mouseX, mouseY: mouseY });
3690 | }
3691 | /**
3692 | * delete all resources created by construction of this [[Merger]]; use right before
3693 | * intentionally losing a reference to this merger object. this is useful if you want
3694 | * to construct another [[Merger]] to use new effects
3695 | */
3696 | delete() {
3697 | // TODO do we have to do something with VertexAttribArray?
3698 | // call bind with null on all textures
3699 | for (let i = 0; i < 2 + this.tex.bufTextures.length; i++) {
3700 | // this gets rid of final texture, scene texture and channels
3701 | this.gl.activeTexture(this.gl.TEXTURE0 + i + settings_1.settings.offset);
3702 | this.gl.bindTexture(this.gl.TEXTURE_2D, null);
3703 | }
3704 | // call bind with null on all vertex buffers (just 1)
3705 | this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
3706 | // call bind with null on all frame buffers (just 1)
3707 | // (this might be redundant because this happens at end of draw call)
3708 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
3709 | // delete all programs
3710 | this.programLoop.delete(this.gl);
3711 | // delete all textures
3712 | this.gl.deleteTexture(this.tex.front.tex);
3713 | this.gl.deleteTexture(this.tex.back.tex);
3714 | for (const c of this.tex.bufTextures) {
3715 | this.gl.deleteTexture(c.tex);
3716 | }
3717 | // delete all vertex buffers (just 1)
3718 | this.gl.deleteBuffer(this.vertexBuffer);
3719 | // delete all frame buffers (just 1)
3720 | this.gl.deleteFramebuffer(this.framebuffer);
3721 | // delete all vertex shaders (just 1)
3722 | this.gl.deleteShader(this.vShader);
3723 | // delete all fragment shaders
3724 | for (const f of this.fShaders) {
3725 | this.gl.deleteShader(f);
3726 | }
3727 | }
3728 | /**
3729 | * changes the current program loop
3730 | * @param str key in the program map
3731 | */
3732 | changeProgram(str) {
3733 | if (this.programMap[str] === undefined) {
3734 | throw new Error(`program "${str}" doesn't exist on this merger`);
3735 | }
3736 | this.programLoop = this.programMap[str];
3737 | }
3738 | }
3739 | exports.Merger = Merger;
3740 | /** creates a texture given a context and options */
3741 | function makeTexture(gl, options) {
3742 | const texture = gl.createTexture();
3743 | if (texture === null) {
3744 | throw new Error("problem creating texture");
3745 | }
3746 | // flip the order of the pixels, or else it displays upside down
3747 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
3748 | // bind the texture after creating it
3749 | gl.bindTexture(gl.TEXTURE_2D, texture);
3750 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
3751 | const filterMode = (f) => f === undefined || f === "linear" ? gl.LINEAR : gl.NEAREST;
3752 | // how to map texture element
3753 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode(options === null || options === void 0 ? void 0 : options.minFilterMode));
3754 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode(options === null || options === void 0 ? void 0 : options.maxFilterMode));
3755 | if ((options === null || options === void 0 ? void 0 : options.edgeMode) !== "wrap") {
3756 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
3757 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
3758 | }
3759 | return texture;
3760 | }
3761 | exports.makeTexture = makeTexture;
3762 | /** copies onto texture */
3763 | function sendTexture(gl, src) {
3764 | // if you are using textures instead of images, the user is responsible for
3765 | // updating that texture, so just return
3766 | if (src instanceof WebGLTexture || src === null)
3767 | return;
3768 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);
3769 | }
3770 | exports.sendTexture = sendTexture;
3771 |
3772 | },{"./codebuilder":11,"./exprs/expr":25,"./exprs/fragcolorexpr":26,"./exprs/regiondecorator":47,"./exprs/scenesampleexpr":51,"./exprs/setcolorexpr":52,"./exprs/ternaryexpr":55,"./settings":64,"./webglprogramloop":66}],64:[function(require,module,exports){
3773 | "use strict";
3774 | Object.defineProperty(exports, "__esModule", { value: true });
3775 | exports.settings = void 0;
3776 | exports.settings = {
3777 | /**
3778 | * set to 1 if you want reasonable logging for debugging, such as the
3779 | * generated GLSL code and program tree. set to 100 if you want texture debug
3780 | * info (you probably don't want to do this, as it logs many lines every
3781 | * frame!)
3782 | */
3783 | verbosity: 0,
3784 | /** texture offset */
3785 | offset: 0,
3786 | };
3787 |
3788 | },{}],65:[function(require,module,exports){
3789 | "use strict";
3790 | Object.defineProperty(exports, "__esModule", { value: true });
3791 | exports.brandWithRegion = exports.brandWithChannel = exports.captureAndAppend = void 0;
3792 | const glslfunctions_1 = require("./glslfunctions");
3793 | /** @ignore */
3794 | function captureAndAppend(str, reg, suffix) {
3795 | const matches = str.match(reg);
3796 | if (matches === null)
3797 | throw new Error("no match in the given string");
3798 | return str.replace(reg, matches[0] + suffix);
3799 | }
3800 | exports.captureAndAppend = captureAndAppend;
3801 | /** @ignore */
3802 | function nameExtractor(sourceLists, extra) {
3803 | const origFuncName = sourceLists.sections[0];
3804 | const ending = origFuncName[origFuncName.length - 1] === ")" ? ")" : "";
3805 | const newFuncName = origFuncName.substr(0, origFuncName.length - 1 - ~~(ending === ")")) +
3806 | extra +
3807 | "(" +
3808 | ending;
3809 | return { origFuncName, newFuncName, ending };
3810 | }
3811 | /** @ignore */
3812 | function brandWithChannel(sourceLists, funcs, needs, funcIndex, samplerNum) {
3813 | samplerNum === undefined || samplerNum === -1
3814 | ? (needs.neighborSample = true)
3815 | : (needs.extraBuffers = new Set([samplerNum]));
3816 | if (samplerNum === undefined || samplerNum === -1)
3817 | return;
3818 | const { origFuncName, newFuncName, ending } = nameExtractor(sourceLists, samplerNum !== undefined ? "_" + samplerNum : "");
3819 | sourceLists.sections[0] = sourceLists.sections[0]
3820 | .split(origFuncName)
3821 | .join(newFuncName);
3822 | funcs[funcIndex] = funcs[funcIndex]
3823 | .split(origFuncName)
3824 | .join(newFuncName)
3825 | .split("uSampler")
3826 | .join("uBufferSampler" + samplerNum);
3827 | }
3828 | exports.brandWithChannel = brandWithChannel;
3829 | /** @ignore */
3830 | function brandWithRegion(expr, funcIndex, space) {
3831 | // if it's not a rectangle region we can't do anything so just return
3832 | if (!Array.isArray(space))
3833 | return;
3834 | const sourceLists = expr.sourceLists;
3835 | const funcs = expr.externalFuncs;
3836 | const needs = expr.needs;
3837 | if (expr.regionBranded ||
3838 | (!needs.neighborSample && needs.extraBuffers.size === 0))
3839 | return;
3840 | const { origFuncName, newFuncName, ending } = nameExtractor(sourceLists, "_region");
3841 | const openFuncName = newFuncName.substr(0, newFuncName.length - ~~(ending === ")"));
3842 | const newFuncDeclaration = openFuncName +
3843 | "float r_x_min, float r_y_min, float r_x_max, float r_y_max" +
3844 | (ending === ")" ? ")" : ", ");
3845 | const origTextureName = "texture2D(";
3846 | const newTextureName = "texture2D_region(r_x_min, r_y_min, r_x_max, r_y_max, ";
3847 | // replace name in the external function and `texture2D` and sampler
3848 | // (assumes the sampling function is the first external function)
3849 | funcs[funcIndex] = funcs[funcIndex]
3850 | .split(origFuncName)
3851 | .join(newFuncDeclaration)
3852 | .split(origTextureName)
3853 | .join(newTextureName);
3854 | // shift the original name off the list
3855 | sourceLists.sections.shift();
3856 | // add the close paren if we're opening up a function with 0 args
3857 | if (ending === ")")
3858 | sourceLists.sections.unshift(")");
3859 | // add commas (one less if it is a 0 arg function call)
3860 | for (let i = 0; i < 4 - ~~(ending === ")"); i++) {
3861 | sourceLists.sections.unshift(", ");
3862 | }
3863 | // add the new name to the beginning of the list
3864 | sourceLists.sections.unshift(newFuncName.substr(0, newFuncName.length - ~~(ending === ")")));
3865 | // add values from region data
3866 | sourceLists.values.unshift(...space);
3867 | // put the texture access wrapper at the beginning
3868 | funcs.unshift(glslfunctions_1.glslFuncs.texture2D_region);
3869 | expr.regionBranded = true;
3870 | }
3871 | exports.brandWithRegion = brandWithRegion;
3872 |
3873 | },{"./glslfunctions":61}],66:[function(require,module,exports){
3874 | "use strict";
3875 | Object.defineProperty(exports, "__esModule", { value: true });
3876 | exports.WebGLProgramLoop = exports.WebGLProgramLeaf = exports.updateNeeds = void 0;
3877 | const settings_1 = require("./settings");
3878 | // update me on change to needs
3879 | function updateNeeds(acc, curr) {
3880 | return {
3881 | neighborSample: acc.neighborSample || curr.neighborSample,
3882 | centerSample: acc.centerSample || curr.centerSample,
3883 | sceneBuffer: acc.sceneBuffer || curr.sceneBuffer,
3884 | timeUniform: acc.timeUniform || curr.timeUniform,
3885 | mouseUniform: acc.mouseUniform || curr.mouseUniform,
3886 | passCount: acc.passCount || curr.passCount,
3887 | extraBuffers: new Set([...acc.extraBuffers, ...curr.extraBuffers]),
3888 | };
3889 | }
3890 | exports.updateNeeds = updateNeeds;
3891 | class WebGLProgramLeaf {
3892 | constructor(program, totalNeeds, effects) {
3893 | this.program = program;
3894 | this.totalNeeds = totalNeeds;
3895 | this.effects = effects;
3896 | }
3897 | }
3898 | exports.WebGLProgramLeaf = WebGLProgramLeaf;
3899 | /** @ignore */
3900 | function getLoc(programElement, gl, name) {
3901 | gl.useProgram(programElement.program);
3902 | const loc = gl.getUniformLocation(programElement.program, name);
3903 | if (loc === null) {
3904 | throw new Error("could not get the " + name + " uniform location");
3905 | }
3906 | return loc;
3907 | }
3908 | /** recursive data structure of compiled programs */
3909 | class WebGLProgramLoop {
3910 | constructor(programElement, loopInfo, gl) {
3911 | //effects: Expr[];
3912 | this.last = false;
3913 | this.counter = 0;
3914 | this.programElement = programElement;
3915 | this.loopInfo = loopInfo;
3916 | if (this.programElement instanceof WebGLProgramLeaf) {
3917 | if (gl === undefined) {
3918 | throw new Error("program element is a program but context is undefined");
3919 | }
3920 | if (this.programElement.totalNeeds.timeUniform) {
3921 | this.timeLoc = getLoc(this.programElement, gl, "uTime");
3922 | }
3923 | if (this.programElement.totalNeeds.mouseUniform) {
3924 | this.mouseLoc = getLoc(this.programElement, gl, "uMouse");
3925 | }
3926 | if (this.programElement.totalNeeds.passCount) {
3927 | this.countLoc = getLoc(this.programElement, gl, "uCount");
3928 | }
3929 | }
3930 | }
3931 | /** get all needs from all programs */
3932 | getTotalNeeds() {
3933 | // go through needs of program loop
3934 | if (!(this.programElement instanceof WebGLProgramLeaf)) {
3935 | const allNeeds = [];
3936 | for (const p of this.programElement) {
3937 | allNeeds.push(p.getTotalNeeds());
3938 | }
3939 | return allNeeds.reduce(updateNeeds);
3940 | }
3941 | return this.programElement.totalNeeds;
3942 | }
3943 | /**
3944 | * recursively uses all programs in the loop, binding the appropriate
3945 | * textures and setting the appropriate uniforms; the user should only have
3946 | * to call [[draw]] on [[Merger]] and never this function directly
3947 | */
3948 | run(gl, tex, framebuffer, uniformLocs, last, defaultUniforms, outerLoop) {
3949 | let savedTexture;
3950 | if (this.loopInfo.target !== undefined &&
3951 | // if there is a target switch:
3952 | (outerLoop === null || outerLoop === void 0 ? void 0 : outerLoop.loopInfo.target) !== this.loopInfo.target) {
3953 | // swap out the back texture for the channel texture if this loop has
3954 | // an alternate render target
3955 | savedTexture = tex.back;
3956 | if (this.loopInfo.target !== -1) {
3957 | tex.back = tex.bufTextures[this.loopInfo.target];
3958 | }
3959 | else {
3960 | if (tex.scene === undefined) {
3961 | throw new Error("tried to target -1 but scene texture was undefined");
3962 | }
3963 | tex.back = tex.scene;
3964 | }
3965 | tex.bufTextures[this.loopInfo.target] = savedTexture;
3966 | if (settings_1.settings.verbosity > 99)
3967 | console.log("saved texture: " + savedTexture.name);
3968 | }
3969 | // setup for program leaf
3970 | if (this.programElement instanceof WebGLProgramLeaf) {
3971 | // bind the scene texture if needed
3972 | if (this.programElement.totalNeeds.sceneBuffer) {
3973 | if (tex.scene === undefined) {
3974 | throw new Error("needs scene buffer, but scene texture is somehow undefined");
3975 | }
3976 | gl.activeTexture(gl.TEXTURE1 + settings_1.settings.offset);
3977 | if (this.loopInfo.target === -1) {
3978 | gl.bindTexture(gl.TEXTURE_2D, savedTexture.tex);
3979 | }
3980 | else {
3981 | gl.bindTexture(gl.TEXTURE_2D, tex.scene.tex);
3982 | }
3983 | }
3984 | // bind all extra channel textures if needed
3985 | for (const n of this.programElement.totalNeeds.extraBuffers) {
3986 | gl.activeTexture(gl.TEXTURE2 + n + settings_1.settings.offset);
3987 | gl.bindTexture(gl.TEXTURE_2D, tex.bufTextures[n].tex);
3988 | }
3989 | // use the current program
3990 | gl.useProgram(this.programElement.program);
3991 | // apply all uniforms
3992 | for (const effect of this.programElement.effects) {
3993 | effect.applyUniforms(gl, uniformLocs);
3994 | }
3995 | // set time uniform if needed
3996 | if (this.programElement.totalNeeds.timeUniform) {
3997 | if (this.timeLoc === undefined ||
3998 | defaultUniforms.timeVal === undefined) {
3999 | throw new Error("time or location is undefined");
4000 | }
4001 | gl.uniform1f(this.timeLoc, defaultUniforms.timeVal);
4002 | }
4003 | // set mouse uniforms if needed
4004 | if (this.programElement.totalNeeds.mouseUniform) {
4005 | if (this.mouseLoc === undefined ||
4006 | defaultUniforms.mouseX === undefined ||
4007 | defaultUniforms.mouseY === undefined) {
4008 | throw new Error("mouse uniform or location is undefined");
4009 | }
4010 | gl.uniform2f(this.mouseLoc, defaultUniforms.mouseX, defaultUniforms.mouseY);
4011 | }
4012 | // set count uniform if needed
4013 | if (this.programElement.totalNeeds.passCount && outerLoop !== undefined) {
4014 | if (this.countLoc === undefined) {
4015 | throw new Error("count location is undefined");
4016 | }
4017 | if (outerLoop !== undefined) {
4018 | gl.uniform1i(this.countLoc, outerLoop.counter);
4019 | }
4020 | this.counter++;
4021 | const mod = outerLoop === undefined ? 1 : outerLoop.loopInfo.num;
4022 | this.counter %= mod;
4023 | }
4024 | }
4025 | for (let i = 0; i < this.loopInfo.num; i++) {
4026 | const newLast = i === this.loopInfo.num - 1;
4027 | if (this.programElement instanceof WebGLProgramLeaf) {
4028 | if (newLast && last && this.last) {
4029 | // we are on the final pass of the final loop, so draw screen by
4030 | // setting to the default framebuffer
4031 | gl.bindFramebuffer(gl.FRAMEBUFFER, null);
4032 | }
4033 | else {
4034 | // we have to bounce between two textures
4035 | gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
4036 | // use the framebuffer to write to front texture
4037 | gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex.front.tex, 0);
4038 | }
4039 | // allows us to read from `texBack`
4040 | // default sampler is 0, so `uSampler` uniform will always sample from texture 0
4041 | gl.activeTexture(gl.TEXTURE0 + settings_1.settings.offset);
4042 | gl.bindTexture(gl.TEXTURE_2D, tex.back.tex);
4043 | // use our last program as the draw program
4044 | gl.drawArrays(gl.TRIANGLES, 0, 6);
4045 | if (settings_1.settings.verbosity > 99) {
4046 | console.log("intermediate back", tex.back.name);
4047 | console.log("intermediate front", tex.front.name);
4048 | }
4049 | // swap back and front
4050 | [tex.back, tex.front] = [tex.front, tex.back];
4051 | // deactivate and unbind all the channel textures needed
4052 | for (const n of this.programElement.totalNeeds.extraBuffers) {
4053 | gl.activeTexture(gl.TEXTURE2 + n + settings_1.settings.offset);
4054 | gl.bindTexture(gl.TEXTURE_2D, null);
4055 | }
4056 | gl.activeTexture(gl.TEXTURE1 + settings_1.settings.offset);
4057 | gl.bindTexture(gl.TEXTURE_2D, null);
4058 | }
4059 | else {
4060 | if (this.loopInfo.func !== undefined) {
4061 | this.loopInfo.func(i);
4062 | }
4063 | for (const p of this.programElement) {
4064 | p.run(gl, tex, framebuffer, uniformLocs, newLast, defaultUniforms, this // this is now the outer loop
4065 | );
4066 | }
4067 | }
4068 | }
4069 | // swap the textures back if we were temporarily using a channel texture
4070 | if (savedTexture !== undefined) {
4071 | const target = this.loopInfo.target;
4072 | if (settings_1.settings.verbosity > 99) {
4073 | console.log("pre final back", tex.back.name);
4074 | console.log("pre final front", tex.front.name);
4075 | }
4076 | // back texture is really the front texture because it was just swapped
4077 | if (this.loopInfo.target !== -1) {
4078 | tex.bufTextures[target] = tex.back;
4079 | }
4080 | else {
4081 | if (tex.scene === undefined) {
4082 | throw new Error("tried to replace -1 but scene texture was undefined");
4083 | }
4084 | tex.scene = tex.back;
4085 | }
4086 | tex.back = savedTexture;
4087 | if (settings_1.settings.verbosity > 99) {
4088 | console.log("post final back", tex.back.name);
4089 | console.log("post final front", tex.front.name);
4090 | console.log("channel texture", tex.bufTextures[target].name);
4091 | }
4092 | }
4093 | }
4094 | delete(gl) {
4095 | if (this.programElement instanceof WebGLProgramLeaf) {
4096 | gl.deleteProgram(this.programElement.program);
4097 | }
4098 | else {
4099 | for (const p of this.programElement) {
4100 | p.delete(gl);
4101 | }
4102 | }
4103 | }
4104 | }
4105 | exports.WebGLProgramLoop = WebGLProgramLoop;
4106 |
4107 | },{"./settings":64}]},{},[9]);
4108 | // @ts-nocheck
4109 | {
4110 | const addToProto = (pr, name, add) => {
4111 | if (p5.prototype.hasOwnProperty(name)) {
4112 | throw new Error("p5 already has this: " + name);
4113 | }
4114 | pr[name] = add;
4115 | };
4116 |
4117 | const pr = p5.prototype;
4118 | // this avoids collisions with names in p5 and changes to camelCase
4119 | addToProto(pr, "foggyRays", MP.foggyrays);
4120 | addToProto(pr, "vignette", MP.vignette);
4121 | addToProto(pr, "blurAndTrace", MP.blurandtrace);
4122 | addToProto(pr, "lightBands", MP.lightbands);
4123 | addToProto(pr, "noiseDisplacement", MP.noisedisplacement);
4124 | addToProto(pr, "oldFilm", MP.oldfilm);
4125 | addToProto(pr, "kaleidoscope", MP.kaleidoscope);
4126 | addToProto(pr, "effectLoop", MP.loop);
4127 | addToProto(pr, "gauss", MP.gauss);
4128 | addToProto(pr, "fColor", MP.fcolor);
4129 | addToProto(pr, "vec2", MP.vec2);
4130 | addToProto(pr, "vec3", MP.vec3);
4131 | addToProto(pr, "vec4", MP.vec4);
4132 | addToProto(pr, "pVec2", MP.pvec2);
4133 | addToProto(pr, "pVec3", MP.pvec3);
4134 | addToProto(pr, "pVec4", MP.pvec4);
4135 | addToProto(pr, "op", MP.op);
4136 | addToProto(pr, "blur2d", MP.blur2d);
4137 | addToProto(pr, "len", MP.len);
4138 | addToProto(pr, "normalize", MP.norm);
4139 | addToProto(pr, "pixel", MP.pixel);
4140 | addToProto(pr, "pos", MP.pos);
4141 | addToProto(pr, "center", MP.center);
4142 | addToProto(pr, "input", MP.input);
4143 | addToProto(pr, "bright", MP.brightness);
4144 | addToProto(pr, "contrast", MP.contrast);
4145 | addToProto(pr, "grain", MP.grain);
4146 | addToProto(pr, "getComp", MP.getcomp);
4147 | addToProto(pr, "get2Comp", MP.get2comp);
4148 | addToProto(pr, "get3Comp", MP.get3comp);
4149 | addToProto(pr, "get4Comp", MP.get4comp);
4150 | addToProto(pr, "changeComp", MP.changecomp);
4151 | addToProto(pr, "rgbToHsv", MP.rgb2hsv);
4152 | addToProto(pr, "hsvToRgb", MP.hsv2rgb);
4153 | addToProto(pr, "time", MP.time);
4154 | addToProto(pr, "a1", MP.a1);
4155 | addToProto(pr, "a2", MP.a2);
4156 | addToProto(pr, "fxaa", MP.fxaa);
4157 | addToProto(pr, "channel", MP.channel);
4158 | addToProto(pr, "depthOfField", MP.dof);
4159 | addToProto(pr, "trueDepth", MP.truedepth);
4160 | addToProto(pr, "godrays", MP.godrays);
4161 | addToProto(pr, "depthToOcclusion", MP.depth2occlusion);
4162 | addToProto(pr, "resolution", MP.resolution);
4163 | addToProto(pr, "mouse", MP.mouse);
4164 | addToProto(pr, "rotate2d", MP.rotate);
4165 | addToProto(pr, "translate2d", MP.translate);
4166 | addToProto(pr, "nMouse", MP.nmouse);
4167 | addToProto(pr, "perlin", MP.perlin);
4168 | addToProto(pr, "simplex", MP.simplex);
4169 | addToProto(pr, "motionBlur", MP.motionblur);
4170 | addToProto(pr, "randomFloat", MP.random);
4171 | addToProto(pr, "sobel", MP.sobel);
4172 | addToProto(pr, "bloom", MP.bloom);
4173 | addToProto(pr, "monochrome", MP.monochrome);
4174 | addToProto(pr, "invert", MP.invert);
4175 | addToProto(pr, "edge", MP.edge);
4176 | addToProto(pr, "edgeColor", MP.edgecolor);
4177 | addToProto(pr, "ternary", MP.ternary);
4178 | addToProto(pr, "region", MP.region);
4179 | addToProto(pr, "cFloat", MP.cfloat);
4180 | addToProto(pr, "cVec2", MP.cvec2);
4181 | addToProto(pr, "cVec3", MP.cvec3);
4182 | addToProto(pr, "cVec4", MP.cvec4);
4183 | addToProto(pr, "mut", MP.mut);
4184 | addToProto(pr, "basicFloat", MP.float);
4185 | addToProto(pr, "pFloat", MP.pfloat);
4186 | addToProto(pr, "tag", MP.tag);
4187 | addToProto(pr, "celShade", MP.celshade);
4188 |
4189 | addToProto(pr, "__info", {
4190 | replaced: false,
4191 | orig: null,
4192 | canvas: null,
4193 | gl: null,
4194 | verbosity: 0,
4195 | startTime: 0,
4196 | mousePos: { x: 0, y: 0 },
4197 | effects: [],
4198 | channels: [],
4199 | });
4200 |
4201 | console.log(pr.__info);
4202 |
4203 | addToProto(pr, "addEffects", function () {
4204 | pr.__info.effects.push(...arguments);
4205 | });
4206 |
4207 | addToProto(pr, "addChannels", function () {
4208 | pr.__info.channels.push(...arguments);
4209 | });
4210 |
4211 | const info = p5.prototype.__info;
4212 |
4213 | function mpInit() {
4214 | if (info.verbosity > 0) console.log("mp init");
4215 | }
4216 |
4217 | function mpPre() {
4218 | if (info.replaced || !info.effects) return;
4219 | if (info.verbosity > 0) console.log("mp pre x1");
4220 |
4221 | info.startTime = new Date().getTime();
4222 |
4223 | info.orig = document.getElementById("defaultCanvas0");
4224 |
4225 | if (!info.orig) throw new Error("mergepass couldn't get the p5 canvas");
4226 | const parent = info.orig.parentElement;
4227 | parent.style.position = "relative";
4228 |
4229 | info.canvas = document.createElement("canvas");
4230 |
4231 | info.canvas.width = info.orig.width;
4232 | info.canvas.height = info.orig.height;
4233 | info.canvas.style.width = info.orig.style.width;
4234 | info.canvas.style.height = info.orig.style.height;
4235 |
4236 | info.gl = info.canvas.getContext("webgl2");
4237 | if (!info.gl) throw new Error("mergepass couldn't get the webgl2 context");
4238 |
4239 | parent.appendChild(info.canvas);
4240 |
4241 | info.merger = new MP.Merger(pr.__info.effects, info.orig, info.gl, {
4242 | channels: pr.__info.channels,
4243 | });
4244 |
4245 | const align = (c, z) => {
4246 | c.style.position = "absolute";
4247 | c.style.left = 0;
4248 | c.style.top = 0;
4249 | c.style.zIndex = z;
4250 | };
4251 |
4252 | align(info.canvas, 0);
4253 | align(info.orig, 1);
4254 |
4255 | info.orig.style.visibility = "hidden";
4256 |
4257 | info.canvas.addEventListener("mousemove", (e) => {
4258 | const rect = info.orig.getBoundingClientRect();
4259 | info.mousePos.x =
4260 | (info.canvas.width * (e.clientX - rect.left)) / rect.width;
4261 | info.mousePos.y =
4262 | (info.canvas.height * (rect.height - (e.clientY - rect.top))) /
4263 | rect.height;
4264 | });
4265 |
4266 | info.replaced = true;
4267 | }
4268 |
4269 | function mpPost() {
4270 | if (info.verbosity > 1) console.log("mp post");
4271 | if (!info.effects) return;
4272 | const time = info.startTime - new Date().getTime();
4273 | info.merger.draw(time / 1000, info.mousePos.x, info.mousePos.y);
4274 | }
4275 |
4276 | p5.prototype.registerMethod("pre", mpPre);
4277 | p5.prototype.registerMethod("init", mpInit);
4278 | p5.prototype.registerMethod("post", mpPost);
4279 | }
4280 |
--------------------------------------------------------------------------------