diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c2059a0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+post5.js
diff --git a/README.md b/README.md
index 15de55d..39c8010 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,8 @@
# post5
post5 is a library for p5 that enables you to do interesting post-processing
-effects with the power of WebGL2. It wraps
+effects with the power of WebGL2. You can build it or download it from the
+"releases" section on the sidebar in GitHub. It wraps
[merge-pass](https://github.com/bandaloo/merge-pass) and
[postpre](https://github.com/bandaloo/postpre).
@@ -9,7 +10,8 @@ Check out the
[merge-pass live example](https://www.bandaloo.fun/merge-pass/example.html)
and the [postpre live example](https://www.bandaloo.fun/postpre/example.html)
to get an idea of how to nest and sequence these effects in interesting ways.
-Also check out the included examples in this repo.
+Also check out the included examples in this repo or the examples
+[in the web editor](https://editor.p5js.org/bandaloo/collections/KKmpKHP-V).
To get started, all you need to do is include the `post5.js` script after
the `p5` script and before your sketch script:
@@ -18,7 +20,7 @@ the `p5` script and before your sketch script:
-
+
@@ -26,6 +28,92 @@ the `p5` script and before your sketch script:
```
+## Mappings from merge-pass and postpre to post5
+
+This library is really just a thin wrapper for merge-pass and postpre.
+(Although the default arguments for the provided functions will get you
+pretty far, a number of things could be done to make this easier to use
+without TypeScript and the surrounding tooling.) As mentioned previously,
+check out the
+[merge-pass live example](https://www.bandaloo.fun/merge-pass/example.html)
+and the [postpre live example](https://www.bandaloo.fun/postpre/example.html)
+for examples on how to use this library. Below is a table to keep track of
+the mappings in post5; you want to use the names in the left column. Most are
+just changed to camelCase, but some names had to change totally due to naming
+conflicts with p5.
+
+| post5 | merge-pass/postpre |
+| ----------------- | ------------------ |
+| foggyRays | foggyrays |
+| vignette | vignette |
+| blurAndTrace | blurandtrace |
+| lightBands | lightbands |
+| noiseDisplacement | noisedisplacement |
+| oldFilm | oldfilm |
+| kaleidoscope | kaleidoscope |
+| effectLoop | loop |
+| gauss | gauss |
+| fColor | fcolor |
+| vec2 | vec2 |
+| vec3 | vec3 |
+| vec4 | vec4 |
+| pVec2 | pvec2 |
+| pVec3 | pvec3 |
+| pVec4 | pvec4 |
+| op | op |
+| blur2d | blur2d |
+| len | len |
+| normalize | norm |
+| pixel | pixel |
+| pos | pos |
+| center | center |
+| input | input |
+| bright | brightness |
+| contrast | contrast |
+| grain | grain |
+| getComp | getcomp |
+| get2Comp | get2comp |
+| get3Comp | get3comp |
+| get4Comp | get4comp |
+| changeComp | changecomp |
+| rgbToHsv | rgb2hsv |
+| hsvToRgb | hsv2rgb |
+| time | time |
+| a1 | a1 |
+| a2 | a2 |
+| fxaa | fxaa |
+| channel | channel |
+| depthOfField | dof |
+| trueDepth | truedepth |
+| godrays | godrays |
+| depthToOcclusion | depth2occlusion |
+| resolution | resolution |
+| mouse | mouse |
+| rotate2d | rotate |
+| translate2d | translate |
+| nMouse | nmouse |
+| perlin | perlin |
+| simplex | simplex |
+| motionBlur | motionblur |
+| randomFloat | random |
+| sobel | sobel |
+| bloom | bloom |
+| monochrome | monochrome |
+| invert | invert |
+| edge | edge |
+| edgeColor | edgecolor |
+| ternary | ternary |
+| region | region |
+| cFloat | cfloat |
+| cVec2 | cvec2 |
+| cVec3 | cvec3 |
+| cVec4 | cvec4 |
+| mut | mut |
+| basicFloat | float |
+| pFloat | pfloat |
+| tag | tag |
+| celShade | celshade |
+
## Building
(This build process will be replaced with an easier one soon. postpre will be
@@ -35,7 +123,5 @@ This repo includes `p5bundle.js` produced by the `npm run p5` script in the
postpre package available [here](https://github.com/bandaloo/postpre).
Running `sh build.sh` literally justs concatenates `p5bundle.js` with
`p5extensions.js` (which does the extending of the p5 prototype) to produce
-`post5.js`. This file is committed for convenience. also, `p5.js` version
-1.1.9 is also included so that the examples work out the gate. The included
-examples use `post5.js` so run `sh build.sh` after making changes to
-`p5extensions.js`.
+`post5.js`. The included examples use `post5.js` so run `sh build.sh` after
+making changes to `p5extensions.js`.
diff --git a/build.sh b/build.sh
index e3cda75..a448287 100644
--- a/build.sh
+++ b/build.sh
@@ -1,2 +1,3 @@
#!/bin/bash
-cat p5bundle.js p5extensions.js > post5.js
+echo "/* post5 0.2.1 | (c) 2020, Cole Granof | MIT License */" > post5.js
+cat p5bundle.js p5extensions.js >> post5.js
diff --git a/examples/blurexample.html b/examples/blurexample.html
index e44ca17..c3626a3 100644
--- a/examples/blurexample.html
+++ b/examples/blurexample.html
@@ -1,7 +1,7 @@
-
+
diff --git a/examples/colordistexample.html b/examples/colordistexample.html
index df83ceb..1af319a 100644
--- a/examples/colordistexample.html
+++ b/examples/colordistexample.html
@@ -1,7 +1,7 @@
-
+
diff --git a/examples/hueexample.html b/examples/hueexample.html
index 042fd44..51c3afe 100644
--- a/examples/hueexample.html
+++ b/examples/hueexample.html
@@ -1,7 +1,7 @@
-
+
diff --git a/examples/inkyexample.html b/examples/inkyexample.html
index 4d8f461..8db1cc4 100644
--- a/examples/inkyexample.html
+++ b/examples/inkyexample.html
@@ -1,7 +1,7 @@
-
+
diff --git a/examples/instanceexample.html b/examples/instanceexample.html
index c40eed4..376dc48 100644
--- a/examples/instanceexample.html
+++ b/examples/instanceexample.html
@@ -1,7 +1,7 @@
-
+
diff --git a/examples/mandalaexample.html b/examples/mandalaexample.html
index fa7a44d..4e0ca1c 100644
--- a/examples/mandalaexample.html
+++ b/examples/mandalaexample.html
@@ -1,7 +1,7 @@
-
+
diff --git a/p5extensions.js b/p5extensions.js
index 499f50c..9a9b4f0 100644
--- a/p5extensions.js
+++ b/p5extensions.js
@@ -77,6 +77,7 @@
addToProto(pr, "basicFloat", MP.float);
addToProto(pr, "pFloat", MP.pfloat);
addToProto(pr, "tag", MP.tag);
+ addToProto(pr, "celShade", MP.celshade);
addToProto(pr, "__info", {
replaced: false,
diff --git a/post5.js b/post5.js
deleted file mode 100644
index b88d75d..0000000
--- a/post5.js
+++ /dev/null
@@ -1,4275 +0,0 @@
-// @ts-nocheck
-(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));
- 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())));
- this.periodFloat = periodFloat;
- this.speedFloat = speedFloat;
- this.intensityFloat = intensityFloat;
- this.period = period;
- this.speed = speed;
- this.intensity = intensity;
- }
- setPeriod(period) {
- this.periodFloat.setVal(merge_pass_1.wrapInValue(period));
- this.period = merge_pass_1.wrapInValue(period);
- }
- setSpeed(speed) {
- this.speedFloat.setVal(merge_pass_1.wrapInValue(speed));
- this.speed = merge_pass_1.wrapInValue(speed);
- }
- setIntensity(intensity) {
- this.intensityFloat.setVal(merge_pass_1.wrapInValue(intensity));
- this.speed = merge_pass_1.wrapInValue(intensity);
- }
-}
-exports.NoiseDisplacement = NoiseDisplacement;
-function noisedisplacement(period = merge_pass_1.mut(0.1), speed = merge_pass_1.mut(1), intensity = merge_pass_1.mut(0.005)) {
- return new NoiseDisplacement(merge_pass_1.wrapInValue(period), merge_pass_1.wrapInValue(speed), merge_pass_1.wrapInValue(intensity));
-}
-exports.noisedisplacement = noisedisplacement;
-
-},{"@bandaloo/merge-pass":62}],8:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.oldfilm = exports.OldFilm = void 0;
-const merge_pass_1 = require("@bandaloo/merge-pass");
-class OldFilm extends merge_pass_1.WrappedExpr {
- constructor(speckIntensity, lineIntensity, grainIntensity) {
- const speckIntensityFloat = merge_pass_1.float(speckIntensity);
- const lineIntensityFloat = merge_pass_1.float(lineIntensity);
- const grainIntensityFloat = merge_pass_1.float(grainIntensity);
- const ftime = merge_pass_1.a1("floor", merge_pass_1.op(merge_pass_1.time(), "*", 24));
- 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);
- const rate = 10;
- 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);
- 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));
- const lines = merge_pass_1.op(triangles, "*", stepping);
- 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));
- const fsimplex = merge_pass_1.op(merge_pass_1.op(merge_pass_1.simplex(merge_pass_1.op(spos, "*", 7)), "*", 0.44), "+", 0.5);
- const spots = merge_pass_1.op(merge_pass_1.a2("step", fsimplex, 0.08), "*", speckIntensityFloat);
- super(merge_pass_1.monochrome(merge_pass_1.brightness(spots, merge_pass_1.brightness(lines, merge_pass_1.brightness(grainy)))));
- this.speckIntensityFloat = speckIntensityFloat;
- this.lineIntensityFloat = lineIntensityFloat;
- this.grainIntensityFloat = grainIntensityFloat;
- this.speckIntensity = speckIntensity;
- this.lineIntensity = lineIntensity;
- this.grainIntensity = grainIntensity;
- }
- setSpeckIntensity(speckIntensity) {
- this.speckIntensityFloat.setVal(merge_pass_1.wrapInValue(speckIntensity));
- this.speckIntensity = merge_pass_1.wrapInValue(speckIntensity);
- }
- setLineIntensity(lineIntensity) {
- this.lineIntensityFloat.setVal(merge_pass_1.wrapInValue(lineIntensity));
- this.lineIntensity = merge_pass_1.wrapInValue(lineIntensity);
- }
- setGrainIntensity(grainIntensity) {
- this.grainIntensityFloat.setVal(merge_pass_1.wrapInValue(grainIntensity));
- this.grainIntensity = merge_pass_1.wrapInValue(grainIntensity);
- }
-}
-exports.OldFilm = OldFilm;
-function oldfilm(speckIntensity = merge_pass_1.mut(0.4), lineIntensity = merge_pass_1.mut(0.12), grainIntensity = merge_pass_1.mut(0.11)) {
- return new OldFilm(merge_pass_1.wrapInValue(speckIntensity), merge_pass_1.wrapInValue(lineIntensity), merge_pass_1.wrapInValue(grainIntensity));
-}
-exports.oldfilm = oldfilm;
-
-},{"@bandaloo/merge-pass":62}],9:[function(require,module,exports){
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-// @ts-nocheck
-const postpre = __importStar(require("./index"));
-const mergepass = __importStar(require("@bandaloo/merge-pass"));
-window.MP = Object.assign({}, postpre, mergepass);
-
-},{"./index":4,"@bandaloo/merge-pass":62}],10:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.vignette = exports.Vignette = void 0;
-const merge_pass_1 = require("@bandaloo/merge-pass");
-class Vignette extends merge_pass_1.EffectLoop {
- constructor(blurScalar, brightnessScalar, brightnessExponent) {
- const blurScalarFloat = merge_pass_1.float(blurScalar);
- const brightnessScalarFloat = merge_pass_1.float(brightnessScalar);
- const brightnessExponentFloat = merge_pass_1.float(brightnessExponent);
- const blurLen = merge_pass_1.op(merge_pass_1.len(merge_pass_1.center()), "*", blurScalarFloat);
- const blurExpr = merge_pass_1.blur2d(blurLen, blurLen);
- const brightLen = merge_pass_1.a2("pow", merge_pass_1.len(merge_pass_1.center()), brightnessExponentFloat);
- const brightExpr = merge_pass_1.brightness(merge_pass_1.op(brightLen, "*", merge_pass_1.op(brightnessScalarFloat, "*", -1)));
- super([blurExpr, brightExpr], { num: 1 });
- this.blurScalarFloat = blurScalarFloat;
- this.brightnessScalarFloat = brightnessScalarFloat;
- this.brightnessExponentFloat = brightnessExponentFloat;
- this.blurScalar = blurScalar;
- this.brightnessScalar = brightnessScalar;
- this.brightnessExponent = brightnessExponent;
- }
- setBlurScalar(blurScalar) {
- this.blurScalarFloat.setVal(merge_pass_1.wrapInValue(blurScalar));
- this.blurScalar = merge_pass_1.wrapInValue(blurScalar);
- }
- setBrightnessScalar(brightnessScalar) {
- this.brightnessScalarFloat.setVal(merge_pass_1.wrapInValue(brightnessScalar));
- this.brightnessScalar = merge_pass_1.wrapInValue(brightnessScalar);
- }
- setBrightnessExponent(brightnessExponent) {
- this.brightnessExponentFloat.setVal(merge_pass_1.wrapInValue(brightnessExponent));
- this.brightnessExponent = merge_pass_1.wrapInValue(brightnessExponent);
- }
-}
-exports.Vignette = Vignette;
-function vignette(blurScalar = merge_pass_1.mut(3), brightnessScalar = merge_pass_1.mut(1.8), brightnessExponent = merge_pass_1.mut(1.8)) {
- return new Vignette(merge_pass_1.wrapInValue(blurScalar), merge_pass_1.wrapInValue(brightnessScalar), merge_pass_1.wrapInValue(brightnessExponent));
-}
-exports.vignette = vignette;
-
-},{"@bandaloo/merge-pass":62}],11:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.CodeBuilder = exports.channelSamplerName = void 0;
-const expr_1 = require("./exprs/expr");
-const webglprogramloop_1 = require("./webglprogramloop");
-const settings_1 = require("./settings");
-/** @ignore */
-const FRAG_SET = ` gl_FragColor = texture2D(uSampler, gl_FragCoord.xy / uResolution);\n`;
-/** @ignore */
-const SCENE_SET = `uniform sampler2D uSceneSampler;\n`;
-/** @ignore */
-const TIME_SET = `uniform mediump float uTime;\n`;
-/** @ignore */
-const MOUSE_SET = `uniform mediump vec2 uMouse;\n`;
-/** @ignore */
-const COUNT_SET = `uniform int uCount;\n`;
-/** @ignore */
-const BOILERPLATE = `#ifdef GL_ES
-precision mediump float;
-#endif
-
-uniform sampler2D uSampler;
-uniform mediump vec2 uResolution;\n`;
-/**
- * returns the string name of the sampler uniform for code generation purposes
- * @param num channel number to sample from
- */
-function channelSamplerName(num) {
- // texture 2 sampler has number 0 (0 and 1 are used for back buffer and scene)
- return num === -1 ? "uSampler" : `uBufferSampler${num}`;
-}
-exports.channelSamplerName = channelSamplerName;
-/**
- * returns the string of the declaration of the sampler for code generation
- * purposes
- * @param num channel number to sample from
- */
-function channelSamplerDeclaration(num) {
- return `uniform sampler2D ${channelSamplerName(num)};`;
-}
-/** class that manages generation and compilation of GLSL code */
-class CodeBuilder {
- constructor(effectLoop) {
- this.calls = [];
- this.externalFuncs = new Set();
- this.uniformDeclarations = new Set();
- this.counter = 0;
- this.baseLoop = effectLoop;
- const buildInfo = {
- uniformTypes: {},
- externalFuncs: new Set(),
- exprs: [],
- // update me on change to needs
- needs: {
- centerSample: false,
- neighborSample: false,
- sceneBuffer: false,
- timeUniform: false,
- mouseUniform: false,
- passCount: false,
- extraBuffers: new Set(),
- },
- };
- this.addEffectLoop(effectLoop, 1, buildInfo);
- // add all the types to uniform declarations from the `BuildInfo` instance
- for (const name in buildInfo.uniformTypes) {
- const typeName = buildInfo.uniformTypes[name];
- this.uniformDeclarations.add(`uniform mediump ${typeName} ${name};`);
- }
- // add all external functions from the `BuildInfo` instance
- buildInfo.externalFuncs.forEach((func) => this.externalFuncs.add(func));
- this.totalNeeds = buildInfo.needs;
- this.exprs = buildInfo.exprs;
- }
- addEffectLoop(effectLoop, indentLevel, buildInfo, topLevel = true) {
- const needsLoop = !topLevel && effectLoop.loopInfo.num > 1;
- if (needsLoop) {
- const iName = "i" + this.counter;
- indentLevel++;
- const forStart = " ".repeat(indentLevel - 1) +
- `for (int ${iName} = 0; ${iName} < ${effectLoop.loopInfo.num}; ${iName}++) {`;
- this.calls.push(forStart);
- }
- for (const e of effectLoop.effects) {
- if (e instanceof expr_1.Expr) {
- e.parse(buildInfo);
- this.calls.push(" ".repeat(indentLevel) + "gl_FragColor = " + e.sourceCode + ";");
- this.counter++;
- }
- else {
- this.addEffectLoop(e, indentLevel, buildInfo, false);
- }
- }
- if (needsLoop) {
- this.calls.push(" ".repeat(indentLevel - 1) + "}");
- }
- }
- /** generate the code and compile the program into a loop */
- compileProgram(gl, vShader, uniformLocs, shaders = []) {
- // set up the fragment shader
- const fShader = gl.createShader(gl.FRAGMENT_SHADER);
- if (fShader === null) {
- throw new Error("problem creating fragment shader");
- }
- const fullCode = BOILERPLATE +
- (this.totalNeeds.sceneBuffer ? SCENE_SET : "") +
- (this.totalNeeds.timeUniform ? TIME_SET : "") +
- (this.totalNeeds.mouseUniform ? MOUSE_SET : "") +
- (this.totalNeeds.passCount ? COUNT_SET : "") +
- Array.from(this.totalNeeds.extraBuffers)
- .map((n) => channelSamplerDeclaration(n))
- .join("\n") +
- "\n" +
- [...this.uniformDeclarations].join("\n") +
- "\n" +
- [...this.externalFuncs].join("\n") +
- "\n" +
- "void main() {\n" +
- (this.totalNeeds.centerSample ? FRAG_SET : "") +
- this.calls.join("\n") +
- "\n}";
- if (settings_1.settings.verbosity > 0)
- console.log(fullCode);
- gl.shaderSource(fShader, fullCode);
- gl.compileShader(fShader);
- // set up the program
- const program = gl.createProgram();
- if (program === null) {
- throw new Error("problem creating program");
- }
- gl.attachShader(program, vShader);
- gl.attachShader(program, fShader);
- shaders.push(fShader);
- const shaderLog = (name, shader) => {
- const output = gl.getShaderInfoLog(shader);
- if (output)
- console.log(`${name} shader info log\n${output}`);
- };
- shaderLog("vertex", vShader);
- shaderLog("fragment", fShader);
- gl.linkProgram(program);
- // we need to use the program here so we can get uniform locations
- gl.useProgram(program);
- // find all uniform locations and add them to the dictionary
- for (const expr of this.exprs) {
- for (const name in expr.uniformValChangeMap) {
- const location = gl.getUniformLocation(program, name);
- if (location === null) {
- throw new Error("couldn't find uniform " + name);
- }
- // TODO enforce unique names in the same program
- if (uniformLocs[name] === undefined) {
- uniformLocs[name] = { locs: [], counter: 0 };
- }
- // assign the name to the location
- uniformLocs[name].locs.push(location);
- }
- }
- // set the uniform resolution (every program has this uniform)
- const uResolution = gl.getUniformLocation(program, "uResolution");
- gl.uniform2f(uResolution, gl.drawingBufferWidth, gl.drawingBufferHeight);
- if (this.totalNeeds.sceneBuffer) {
- // TODO allow for texture options for scene texture
- const location = gl.getUniformLocation(program, "uSceneSampler");
- // put the scene buffer in texture 1 (0 is used for the backbuffer)
- gl.uniform1i(location, 1 + settings_1.settings.offset);
- }
- // set all sampler uniforms
- for (const b of this.totalNeeds.extraBuffers) {
- const location = gl.getUniformLocation(program, channelSamplerName(b));
- // offset the texture location by 2 (0 and 1 are used for scene and original)
- gl.uniform1i(location, b + 2 + settings_1.settings.offset);
- }
- // set the default sampler if there is an offset
- if (settings_1.settings.offset !== 0) {
- const location = gl.getUniformLocation(program, "uSampler");
- gl.uniform1i(location, settings_1.settings.offset);
- }
- // TODO do we need to do this every time?
- // get attribute
- const position = gl.getAttribLocation(program, "aPosition");
- // enable the attribute
- gl.enableVertexAttribArray(position);
- // points to the vertices in the last bound array buffer
- gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
- return new webglprogramloop_1.WebGLProgramLoop(new webglprogramloop_1.WebGLProgramLeaf(program, this.totalNeeds, this.exprs), this.baseLoop.loopInfo, gl);
- }
-}
-exports.CodeBuilder = CodeBuilder;
-
-},{"./exprs/expr":25,"./settings":64,"./webglprogramloop":66}],12:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.a1 = exports.Arity1HomogenousExpr = void 0;
-const expr_1 = require("./expr");
-/** @ignore */
-function genArity1SourceList(name, val) {
- return {
- sections: [name + "(", ")"],
- values: [val],
- };
-}
-/** arity 1 homogenous function expression */
-class Arity1HomogenousExpr extends expr_1.Operator {
- constructor(val, operation) {
- super(val, genArity1SourceList(operation, val), ["uVal"]);
- this.val = val;
- }
- /** set the value being passed into the arity 1 homogenous function */
- setVal(val) {
- this.setUniform("uVal" + this.id, val);
- this.val = expr_1.wrapInValue(val);
- }
-}
-exports.Arity1HomogenousExpr = Arity1HomogenousExpr;
-/**
- * built-in functions that take in one `genType x` and return a `genType x`
- * @param name function name (see [[Arity1HomogenousName]] for valid function names)
- * @param val the `genType x` argument
- */
-function a1(name, val) {
- return new Arity1HomogenousExpr(expr_1.wrapInValue(val), name);
-}
-exports.a1 = a1;
-
-},{"./expr":25}],13:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.a2 = exports.Arity2HomogenousExpr = void 0;
-const expr_1 = require("./expr");
-// note: glsl has atan(y/x) as well as atan(y, x)
-/** @ignore */
-function genArity1SourceList(name, val1, val2) {
- return {
- sections: [name + "(", ",", ")"],
- values: [val1, val2],
- };
-}
-/** arity 2 homogenous function expression */
-class Arity2HomogenousExpr extends expr_1.Operator {
- constructor(name, val1, val2) {
- super(val1, genArity1SourceList(name, val1, val2), ["uVal1", "uVal2"]);
- this.val1 = val1;
- this.val2 = val2;
- }
- /** set the first value being passed into the arity 2 homogenous function */
- setFirstVal(val1) {
- this.setUniform("uVal1" + this.id, val1);
- this.val1 = expr_1.wrapInValue(val1);
- }
- /** set the second value being passed into the arity 2 homogenous function */
- setSecondVal(val2) {
- this.setUniform("uVal2" + this.id, val2);
- this.val2 = expr_1.wrapInValue(val2);
- }
-}
-exports.Arity2HomogenousExpr = Arity2HomogenousExpr;
-// implementation
-/**
- * built-in functions that take in two `genType x` arguments and return a `genType x`
- * @param name function name (see [[Arity2HomogenousName]] for valid function names)
- * @param val1 the first `genType x` argument
- * @param val2 the second `genType x` argument
- */
-function a2(name, val1, val2) {
- return new Arity2HomogenousExpr(name, expr_1.wrapInValue(val1), expr_1.wrapInValue(val2));
-}
-exports.a2 = a2;
-
-},{"./expr":25}],14:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.bloom = exports.BloomLoop = void 0;
-const mergepass_1 = require("../mergepass");
-const arity2_1 = require("./arity2");
-const blurexpr_1 = require("./blurexpr");
-const brightnessexpr_1 = require("./brightnessexpr");
-const channelsampleexpr_1 = require("./channelsampleexpr");
-const contrastexpr_1 = require("./contrastexpr");
-const expr_1 = require("./expr");
-const fragcolorexpr_1 = require("./fragcolorexpr");
-const opexpr_1 = require("./opexpr");
-const vecexprs_1 = require("./vecexprs");
-// TODO bloom uses `input` so it has to be the first
-// TODO maybe a way to update the scene buffer?
-/** bloom loop */
-class BloomLoop extends mergepass_1.EffectLoop {
- 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) {
- const bright = expr_1.cfloat(expr_1.tag `((${channelsampleexpr_1.channel(samplerNum)}.r + ${channelsampleexpr_1.channel(samplerNum)}.g + ${channelsampleexpr_1.channel(samplerNum)}.b) / 3.)`);
- const step = arity2_1.a2("step", bright, threshold);
- const col = expr_1.cvec4(expr_1.tag `vec4(${channelsampleexpr_1.channel(samplerNum)}.rgb * (1. - ${step}), 1.)`);
- const list = [
- mergepass_1.loop([col]).target(samplerNum),
- mergepass_1.loop([
- blurexpr_1.gauss(vecexprs_1.vec2(horizontal, 0), taps),
- blurexpr_1.gauss(vecexprs_1.vec2(0, vertical), taps),
- brightnessexpr_1.brightness(0.1),
- contrastexpr_1.contrast(boost),
- ], reps).target(samplerNum),
- opexpr_1.op(fragcolorexpr_1.fcolor(), "+", channelsampleexpr_1.channel(samplerNum)),
- ];
- super(list, { num: 1 });
- this.threshold = threshold;
- this.horizontal = horizontal;
- this.vertical = vertical;
- this.boost = boost;
- }
- /**
- * set the horizontal stretch of the blur effect (no greater than 1 for best
- * effect)
- */
- setHorizontal(num) {
- if (!(this.horizontal instanceof expr_1.BasicFloat))
- throw new Error("horizontal expression not basic float");
- this.horizontal.setVal(num);
- }
- /**
- * set the vertical stretch of the blur effect (no greater than 1 for best
- * effect)
- */
- setVertical(num) {
- if (!(this.vertical instanceof expr_1.BasicFloat))
- throw new Error("vertical expression not basic float");
- this.vertical.setVal(num);
- }
- /** set the treshold */
- setThreshold(num) {
- if (!(this.threshold instanceof expr_1.BasicFloat))
- throw new Error("threshold expression not basic float");
- this.threshold.setVal(num);
- }
- /** set the contrast boost */
- setBoost(num) {
- if (!(this.boost instanceof expr_1.BasicFloat))
- throw new Error("boost expression not basic float");
- this.boost.setVal(num);
- }
-}
-exports.BloomLoop = BloomLoop;
-/**
- * creates a bloom loop
- * @param threshold values below this brightness don't get blurred (0.4 is
- * about reasonable, which is also the default)
- * @param horizontal how much to blur vertically (defaults to 1 pixel)
- * @param vertical how much to blur horizontally (defaults to 1 pixel)
- * @param taps how many taps for the blur (defaults to 9)
- * @param reps how many times to loop the blur (defaults to 3)
- */
-function bloom(threshold, horizontal, vertical, boost, samplerNum, taps, reps) {
- return new BloomLoop(expr_1.wrapInValue(threshold), expr_1.wrapInValue(horizontal), expr_1.wrapInValue(vertical), expr_1.wrapInValue(boost), samplerNum, taps, reps);
-}
-exports.bloom = bloom;
-
-},{"../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){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.blur2d = exports.Blur2dLoop = void 0;
-const mergepass_1 = require("../mergepass");
-const blurexpr_1 = require("./blurexpr");
-const expr_1 = require("./expr");
-const vecexprs_1 = require("./vecexprs");
-/** 2D blur loop */
-class Blur2dLoop extends mergepass_1.EffectLoop {
- constructor(horizontal = expr_1.float(expr_1.mut(1)), vertical = expr_1.float(expr_1.mut(1)), reps = 2, taps, samplerNum) {
- const side = blurexpr_1.gauss(vecexprs_1.vec2(horizontal, 0), taps, samplerNum);
- const up = blurexpr_1.gauss(vecexprs_1.vec2(0, vertical), taps, samplerNum);
- super([side, up], { num: reps });
- this.horizontal = horizontal;
- this.vertical = vertical;
- }
- /**
- * set the horizontal stretch of the blur effect (no greater than 1 for best
- * effect)
- */
- setHorizontal(num) {
- if (!(this.horizontal instanceof expr_1.BasicFloat))
- throw new Error("horizontal expression not basic float");
- this.horizontal.setVal(num);
- }
- /**
- * set the vertical stretch of the blur effect (no greater than 1 for best
- * effect)
- */
- setVertical(num) {
- if (!(this.vertical instanceof expr_1.BasicFloat))
- throw new Error("vertical expression not basic float");
- this.vertical.setVal(num);
- }
-}
-exports.Blur2dLoop = Blur2dLoop;
-/**
- * creates a loop that runs a horizontal, then vertical gaussian blur (anything
- * more than 1 pixel in the horizontal or vertical direction will create a
- * ghosting effect, which is usually not desirable)
- * @param horizontalExpr float for the horizontal blur (1 pixel default)
- * @param verticalExpr float for the vertical blur (1 pixel default)
- * @param reps how many passes (defaults to 2)
- * @param taps how many taps (defaults to 5)
- * @param samplerNum change if you want to sample from a different channel and
- * the outer loop has a different target
- */
-function blur2d(horizontalExpr, verticalExpr, reps, taps, samplerNum) {
- return new Blur2dLoop(expr_1.wrapInValue(horizontalExpr), expr_1.wrapInValue(verticalExpr), reps, taps, samplerNum);
-}
-exports.blur2d = blur2d;
-
-},{"../mergepass":63,"./blurexpr":16,"./expr":25,"./vecexprs":59}],16:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.gauss = exports.BlurExpr = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-/** @ignore */
-function genBlurSource(direction, taps) {
- return {
- sections: [`gauss${taps}(`, ")"],
- values: [direction],
- };
-}
-/** @ignore */
-function tapsToFuncSource(taps) {
- switch (taps) {
- case 5:
- return glslfunctions_1.glslFuncs.gauss5;
- case 9:
- return glslfunctions_1.glslFuncs.gauss9;
- case 13:
- return glslfunctions_1.glslFuncs.gauss13;
- }
-}
-/** gaussian blur expression */
-class BlurExpr extends expr_1.ExprVec4 {
- constructor(direction, taps = 5, samplerNum) {
- // this is already guaranteed by typescript, but creates helpful error for
- // use in gibber or anyone just using javascript
- if (![5, 9, 13].includes(taps)) {
- throw new Error("taps for gauss blur can only be 5, 9 or 13");
- }
- super(genBlurSource(direction, taps), ["uDirection"]);
- this.direction = direction;
- this.externalFuncs = [tapsToFuncSource(taps)];
- this.brandExprWithChannel(0, samplerNum);
- }
- /** set the blur direction (keep magnitude no greater than 1 for best effect) */
- setDirection(direction) {
- this.setUniform("uDirection" + this.id, direction);
- this.direction = direction;
- }
-}
-exports.BlurExpr = BlurExpr;
-/**
- * creates expression that performs one pass of a gaussian blur
- * @param direction direction to blur (keep magnitude less than or equal to 1
- * for best effect)
- * @param taps number of taps (defaults to 5)
- * @param samplerNum which channel to sample from (default 0)
- */
-function gauss(direction, taps = 5, samplerNum) {
- return new BlurExpr(direction, taps, samplerNum);
-}
-exports.gauss = gauss;
-
-},{"../glslfunctions":61,"./expr":25}],17:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.brightness = exports.Brightness = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-const fragcolorexpr_1 = require("./fragcolorexpr");
-/** brightness expression */
-class Brightness extends expr_1.ExprVec4 {
- constructor(brightness, col = fragcolorexpr_1.fcolor()) {
- super(expr_1.tag `brightness(${brightness}, ${col})`, ["uBrightness", "uColor"]);
- this.brightness = brightness;
- this.externalFuncs = [glslfunctions_1.glslFuncs.brightness];
- }
- /** set the brightness (should probably be between -1 and 1) */
- setBrightness(brightness) {
- this.setUniform("uBrightness" + this.id, brightness);
- this.brightness = expr_1.wrapInValue(brightness);
- }
-}
-exports.Brightness = Brightness;
-/**
- * changes the brightness of a color
- * @param val float for how much to change the brightness by (should probably be
- * between -1 and 1)
- * @param col the color to increase the brightness of (defaults to current
- * fragment color)
- */
-function brightness(val, col) {
- return new Brightness(expr_1.wrapInValue(val), col);
-}
-exports.brightness = brightness;
-
-},{"../glslfunctions":61,"./expr":25,"./fragcolorexpr":26}],18:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.changecomp = exports.ChangeCompExpr = void 0;
-const expr_1 = require("./expr");
-const getcompexpr_1 = require("./getcompexpr");
-/** @ignore */
-function getChangeFunc(typ, id, setter, comps, op = "") {
- return `${typ} changecomp_${id}(${typ} col, ${setter.typeString()} setter) {
- col.${comps} ${op}= setter;
- return col;
-}`;
-}
-/**
- * throws a runtime error if component access is not valid, and disallows
- * duplicate components because duplicate components can not be in a left
- * expression. (for example `v.xyx = vec3(1., 2., 3.)` is illegal, but `v1.xyz
- * = v2.xyx` is legal.) also checks for type errors such as `v1.xy = vec3(1.,
- * 2., 3.)`; the right hand side can only be a `vec2` if only two components
- * are supplied
- * @param comps component string
- * @param setter how the components are being changed
- * @param vec the vector where components are being accessed
- */
-function checkChangeComponents(comps, setter, vec) {
- // setter has different length than components
- if (comps.length !== getcompexpr_1.typeStringToLength(setter.typeString())) {
- throw new Error("components length must be equal to the target float/vec");
- }
- // duplicate components
- if (duplicateComponents(comps)) {
- throw new Error("duplicate components not allowed on left side");
- }
- // legal components
- getcompexpr_1.checkLegalComponents(comps, vec);
-}
-/** @ignore */
-function duplicateComponents(comps) {
- return new Set(comps.split("")).size !== comps.length;
-}
-/** change component expression */
-class ChangeCompExpr extends expr_1.Operator {
- constructor(vec, setter, comps, op) {
- checkChangeComponents(comps, setter, vec);
- // part of name of custom function
- const operation = op === "+"
- ? "plus"
- : op === "-"
- ? "minus"
- : op === "*"
- ? "mult"
- : op === "/"
- ? "div"
- : "assign";
- const suffix = `${vec.typeString()}_${setter.typeString()}_${comps}_${operation}`;
- super(vec, { sections: [`changecomp_${suffix}(`, ", ", ")"], values: [vec, setter] }, ["uOriginal", "uNew"]);
- this.originalVec = vec;
- this.newVal = setter;
- this.externalFuncs = [
- getChangeFunc(vec.typeString(), suffix, setter, comps, op),
- ];
- }
- /** set the original vector */
- setOriginal(originalVec) {
- this.setUniform("uOriginal" + this.id, originalVec);
- this.originalVec = originalVec;
- }
- /** set the neww vector */
- setNew(newVal) {
- this.setUniform("uNew" + this.id, newVal);
- this.newVal = expr_1.wrapInValue(newVal);
- }
-}
-exports.ChangeCompExpr = ChangeCompExpr;
-/**
- * change the components of a vector
- * @param vec the vector to augment components of
- * @param setter the vector (or float, if only one component is changed) for
- * how to change the components
- * @param comps string representing the components to change (e.g. `"xy"` or
- * `"r"` or `"stpq"`.)
- * @param op optionally perform an operation on the original component
- * (defaults to no operation, just assigning that component to a new value)
- */
-function changecomp(vec, setter, comps, op) {
- return new ChangeCompExpr(vec, expr_1.wrapInValue(setter), comps, op);
-}
-exports.changecomp = changecomp;
-
-},{"./expr":25,"./getcompexpr":30}],19:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.channel = exports.ChannelSampleExpr = void 0;
-const codebuilder_1 = require("../codebuilder");
-const expr_1 = require("./expr");
-const normfragcoordexpr_1 = require("./normfragcoordexpr");
-const glslfunctions_1 = require("../glslfunctions");
-/** @ignore */
-function genChannelSampleSource(buf, coord) {
- return {
- sections: ["channel(", `, ${codebuilder_1.channelSamplerName(buf)})`],
- values: [coord],
- };
-}
-// TODO create a way to sample but not clamp by region
-/** channel sample expression */
-class ChannelSampleExpr extends expr_1.ExprVec4 {
- constructor(buf, coord = normfragcoordexpr_1.pos()) {
- super(genChannelSampleSource(buf, coord), ["uVec"]);
- this.coord = coord;
- this.externalFuncs = [glslfunctions_1.glslFuncs.channel];
- if (buf !== -1)
- this.needs.extraBuffers = new Set([buf]);
- else
- this.needs.neighborSample = true;
- }
- setCoord(coord) {
- this.setUniform("uVec", coord);
- this.coord = coord;
- }
-}
-exports.ChannelSampleExpr = ChannelSampleExpr;
-/**
- * creates an expression that samples from one of the user-defined channels.
- * don't sample from the same channel that you are using [[target]] on in a
- * loop, just use [[fcolor]]
- * @param channel which channel to sample from
- * @param vec where to sample the channel texture (defaults to the normalized
- * frag coord)
- */
-function channel(channel, vec) {
- return new ChannelSampleExpr(channel, vec);
-}
-exports.channel = channel;
-
-},{"../codebuilder":11,"../glslfunctions":61,"./expr":25,"./normfragcoordexpr":41}],20:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.contrast = exports.ContrastExpr = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-const fragcolorexpr_1 = require("./fragcolorexpr");
-class ContrastExpr extends expr_1.ExprVec4 {
- constructor(contrast, col = fragcolorexpr_1.fcolor()) {
- super(expr_1.tag `contrast(${contrast}, ${col})`, ["uVal", "uCol"]);
- this.contrast = contrast;
- this.externalFuncs = [glslfunctions_1.glslFuncs.contrast];
- }
- /** sets the contrast */
- setContrast(contrast) {
- this.setUniform("uContrast" + this.id, contrast);
- this.contrast = expr_1.wrapInValue(contrast);
- }
-}
-exports.ContrastExpr = ContrastExpr;
-/**
- * changes the contrast of a color
- * @param val float for how much to change the contrast by (should probably be
- * between -1 and 1)
- * @param col the color to increase the contrast of (defaults to current
- * fragment color)
- */
-function contrast(val, col) {
- return new ContrastExpr(expr_1.wrapInValue(val), col);
-}
-exports.contrast = contrast;
-
-},{"../glslfunctions":61,"./expr":25,"./fragcolorexpr":26}],21:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.depth2occlusion = exports.DepthToOcclusionExpr = void 0;
-const channelsampleexpr_1 = require("./channelsampleexpr");
-const expr_1 = require("./expr");
-const vecexprs_1 = require("./vecexprs");
-/** depth info to occlussion info expression */
-class DepthToOcclusionExpr extends expr_1.ExprVec4 {
- 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))) {
- super(expr_1.tag `depth2occlusion(${depthCol}, ${newCol}, ${threshold})`, [
- "uDepth",
- "uNewCol",
- "uThreshold",
- ]);
- this.depthCol = depthCol;
- this.newCol = newCol;
- this.threshold = threshold;
- }
- setDepthColor(depthCol) {
- this.setUniform("uDepth" + this.id, depthCol);
- this.depthCol = depthCol;
- }
- setNewColor(newCol) {
- this.setUniform("uNewCol" + this.id, newCol);
- this.newCol = newCol;
- }
- setThreshold(threshold) {
- this.setUniform("uThreshold" + this.id, threshold);
- this.threshold = expr_1.wrapInValue(threshold);
- }
-}
-exports.DepthToOcclusionExpr = DepthToOcclusionExpr;
-/**
- * converts a `1 / distance` depth texture to an occlusion texture, with all
- * occluded geometry being rendered as black
- * @param depthCol the color representing the inverse depth (defaults to
- * sampling from channel 0)
- * @param newCol the color to replace unoccluded areas by (defaults to white
- * and is mutable by default)
- * @param threshold values below this are not occluded (set to something low,
- * like 0.1 or lower; defaults to 0.01 and is mutable by default)
- */
-function depth2occlusion(depthCol, newCol, threshold) {
- return new DepthToOcclusionExpr(depthCol, newCol, expr_1.wrapInValue(threshold));
-}
-exports.depth2occlusion = depth2occlusion;
-
-},{"./channelsampleexpr":19,"./expr":25,"./vecexprs":59}],22:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.dof = exports.DoFLoop = void 0;
-const mergepass_1 = require("../mergepass");
-const arity2_1 = require("./arity2");
-const blurexpr_1 = require("./blurexpr");
-const channelsampleexpr_1 = require("./channelsampleexpr");
-const expr_1 = require("./expr");
-const gaussianexpr_1 = require("./gaussianexpr");
-const getcompexpr_1 = require("./getcompexpr");
-const opexpr_1 = require("./opexpr");
-const vecexprs_1 = require("./vecexprs");
-class DoFLoop extends mergepass_1.EffectLoop {
- 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) {
- let guassianExpr = gaussianexpr_1.gaussian(depthInfo, depth, rad);
- const side = blurexpr_1.gauss(vecexprs_1.vec2(arity2_1.a2("pow", opexpr_1.op(1, "-", guassianExpr), 4), 0), taps);
- const up = blurexpr_1.gauss(vecexprs_1.vec2(0, arity2_1.a2("pow", opexpr_1.op(1, "-", guassianExpr), 4)), taps);
- super([side, up], { num: reps });
- this.gaussian = guassianExpr;
- }
- setDepth(depth) {
- // this translates the gaussian curve to the side
- this.gaussian.setA(depth);
- }
- setRadius(radius) {
- // this scales the gaussian curve to focus on a larger band of depth
- this.gaussian.setB(radius);
- }
-}
-exports.DoFLoop = DoFLoop;
-/**
- * creates depth of field expression; all values are mutable by default
- * @param depth float for what inverse depth to focus on (1 on top of the
- * camera; 0 is infinity)
- * @param rad float for how deep the band of in-focus geometry is (a value
- * between 0.01 and 0.1 is reasonable)
- * @param depthInfo float the expression that represents the inverse depth
- * (defaults to sampling the red component from channel 0)
- * @param reps how many times to repeat the gaussian blur
- */
-function dof(depth, rad, depthInfo, reps) {
- return new DoFLoop(expr_1.wrapInValue(depth), expr_1.wrapInValue(rad), expr_1.wrapInValue(depthInfo), reps);
-}
-exports.dof = dof;
-
-},{"../mergepass":63,"./arity2":13,"./blurexpr":16,"./channelsampleexpr":19,"./expr":25,"./gaussianexpr":29,"./getcompexpr":30,"./opexpr":43,"./vecexprs":59}],23:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.edgecolor = exports.EdgeColorExpr = void 0;
-const arity2_1 = require("./arity2");
-const expr_1 = require("./expr");
-const fragcolorexpr_1 = require("./fragcolorexpr");
-const monochromeexpr_1 = require("./monochromeexpr");
-const sobelexpr_1 = require("./sobelexpr");
-const vecexprs_1 = require("./vecexprs");
-/** edge color expression */
-class EdgeColorExpr extends expr_1.WrappedExpr {
- constructor(color, samplerNum, stepped = true) {
- const expr = stepped
- ? 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)))})`)
- : expr_1.cvec4(expr_1.tag `mix(${color}, ${fragcolorexpr_1.fcolor()}, ${monochromeexpr_1.monochrome(sobelexpr_1.sobel(samplerNum))})`);
- super(expr);
- this.color = color;
- this.expr = expr;
- }
- setColor(color) {
- this.expr.setUniform("uCustomName0" + this.expr.id, color);
- this.color = color;
- }
-}
-exports.EdgeColorExpr = EdgeColorExpr;
-/**
- * creates a colored edge detection expression
- * @param color what color to make the edge
- * @param samplerNum where to sample from
- * @param stepped whether to round the result of sobel edge detection (defaults
- * to true)
- */
-function edgecolor(color, samplerNum, stepped) {
- return new EdgeColorExpr(color, samplerNum, stepped);
-}
-exports.edgecolor = edgecolor;
-
-},{"./arity2":13,"./expr":25,"./fragcolorexpr":26,"./monochromeexpr":36,"./sobelexpr":54,"./vecexprs":59}],24:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.edge = exports.EdgeExpr = void 0;
-const brightnessexpr_1 = require("./brightnessexpr");
-const expr_1 = require("./expr");
-const getcompexpr_1 = require("./getcompexpr");
-const invertexpr_1 = require("./invertexpr");
-const monochromeexpr_1 = require("./monochromeexpr");
-const opexpr_1 = require("./opexpr");
-const sobelexpr_1 = require("./sobelexpr");
-class EdgeExpr extends expr_1.WrappedExpr {
- constructor(mult = expr_1.mut(-1.0), samplerNum) {
- const operator = opexpr_1.op(getcompexpr_1.getcomp(invertexpr_1.invert(monochromeexpr_1.monochrome(sobelexpr_1.sobel(samplerNum))), "r"), "*", mult);
- super(brightnessexpr_1.brightness(operator));
- this.mult = mult;
- this.operator = operator;
- }
- setMult(mult) {
- this.operator.setRight(mult);
- this.mult = expr_1.wrapInValue(mult);
- }
-}
-exports.EdgeExpr = EdgeExpr;
-/**
- * returns an expression highlights edges where they appear
- * @param style `"dark"` for dark edges and `"light"` for light edges, or a
- * custom number or expression (between -1 and 1) for a more gray style of edge
- * @param samplerNum where to sample from
- */
-function edge(style, samplerNum) {
- const mult = style === "dark" ? -1 : style === "light" ? 1 : style;
- return new EdgeExpr(expr_1.wrapInValue(mult), samplerNum);
-}
-exports.edge = edge;
-
-},{"./brightnessexpr":17,"./expr":25,"./getcompexpr":30,"./invertexpr":34,"./monochromeexpr":36,"./opexpr":43,"./sobelexpr":54}],25:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-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;
-const mergepass_1 = require("../mergepass");
-const webglprogramloop_1 = require("../webglprogramloop");
-const utils_1 = require("../utils");
-/**
- * adds a `.` after a number if needed (e.g converts `1` to `"1."` but leaves
- * `1.2` as `"1.2"`)
- * @param num number to convert
- */
-function toGLSLFloatString(num) {
- let str = "" + num;
- if (!str.includes("."))
- str += ".";
- return str;
-}
-class Expr {
- constructor(sourceLists, defaultNames) {
- // update me on change to needs
- this.needs = {
- neighborSample: false,
- centerSample: false,
- sceneBuffer: false,
- timeUniform: false,
- mouseUniform: false,
- passCount: false,
- extraBuffers: new Set(),
- };
- this.uniformValChangeMap = {};
- this.defaultNameMap = {};
- this.externalFuncs = [];
- this.sourceCode = "";
- this.funcIndex = 0;
- this.regionBranded = false;
- this.id = "_id_" + Expr.count;
- Expr.count++;
- if (sourceLists.sections.length - sourceLists.values.length !== 1) {
- // this cannot happen if you use `tag` to destructure a template string
- throw new Error("wrong lengths for source and values");
- }
- if (sourceLists.values.length !== defaultNames.length) {
- console.log(sourceLists);
- console.log(defaultNames);
- throw new Error("default names list length doesn't match values list length");
- }
- this.sourceLists = sourceLists;
- this.defaultNames = defaultNames;
- }
- applyUniforms(gl, uniformLocs) {
- for (const name in this.uniformValChangeMap) {
- const loc = uniformLocs[name];
- if (this.uniformValChangeMap[name].changed) {
- //this.uniformValChangeMap[name].changed = false;
- this.uniformValChangeMap[name].val.applyUniform(gl, loc.locs[loc.counter]);
- }
- // increment and reset the counter to wrap back around to first location
- loc.counter++;
- loc.counter %= loc.locs.length;
- // once we have wrapped then we know all uniforms have been changed
- if (loc.counter === 0) {
- this.uniformValChangeMap[name].changed = false;
- }
- }
- }
- getSampleNum(mult = 1) {
- return this.needs.neighborSample
- ? mult
- : this.sourceLists.values
- .map((v) => v.getSampleNum())
- .reduce((acc, curr) => acc + curr, 0);
- }
- /**
- * set a uniform by name directly
- * @param name uniform name in the source code
- * @param newVal value to set the uniform to
- */
- setUniform(name, newVal) {
- var _a, _b;
- newVal = wrapInValue(newVal);
- const originalName = name;
- if (typeof newVal === "number") {
- newVal = wrapInValue(newVal);
- }
- if (!(newVal instanceof Primitive)) {
- throw new Error("cannot set a non-primitive");
- }
- // if name does not exist, try mapping default name to new name
- if (((_a = this.uniformValChangeMap[name]) === null || _a === void 0 ? void 0 : _a.val) === undefined) {
- name = this.defaultNameMap[name];
- }
- const oldVal = (_b = this.uniformValChangeMap[name]) === null || _b === void 0 ? void 0 : _b.val;
- if (oldVal === undefined) {
- throw new Error("tried to set uniform " +
- name +
- " which doesn't exist. original name: " +
- originalName);
- }
- if (oldVal.typeString() !== newVal.typeString()) {
- throw new Error("tried to set uniform " + name + " to a new type");
- }
- this.uniformValChangeMap[name].val = newVal;
- this.uniformValChangeMap[name].changed = true;
- }
- /**
- * parses this expression into a string, adding info as it recurses into
- * nested expressions
- */
- parse(buildInfo) {
- this.sourceCode = "";
- buildInfo.exprs.push(this);
- buildInfo.needs = webglprogramloop_1.updateNeeds(buildInfo.needs, this.needs);
- // add each of the external funcs to the builder
- this.externalFuncs.forEach((func) => buildInfo.externalFuncs.add(func));
- // put all of the values between all of the source sections
- for (let i = 0; i < this.sourceLists.values.length; i++) {
- this.sourceCode +=
- this.sourceLists.sections[i] +
- this.sourceLists.values[i].parse(buildInfo, this.defaultNames[i], this);
- }
- // TODO does sourceCode have to be a member?
- this.sourceCode += this.sourceLists.sections[this.sourceLists.sections.length - 1];
- return this.sourceCode;
- }
- addFuncs(funcs) {
- this.externalFuncs.push(...funcs);
- return this;
- }
- brandExprWithChannel(funcIndex, samplerNum) {
- utils_1.brandWithChannel(this.sourceLists, this.externalFuncs, this.needs, funcIndex, samplerNum);
- return this;
- }
- brandExprWithRegion(space) {
- utils_1.brandWithRegion(this, this.funcIndex, space);
- for (const v of this.sourceLists.values) {
- v.brandExprWithRegion(space);
- }
- return this;
- }
-}
-exports.Expr = Expr;
-/**
- * increments for each expression created; used to uniquely id each expression
- */
-Expr.count = 0;
-function genCustomNames(sourceLists) {
- const names = [];
- for (let i = 0; i < sourceLists.values.length; i++) {
- names.push("uCustomName" + i);
- }
- return names;
-}
-/** create a custom float function (use with [[tag]]) */
-function cfloat(sourceLists, externalFuncs = []) {
- return new ExprFloat(sourceLists, genCustomNames(sourceLists)).addFuncs(externalFuncs);
-}
-exports.cfloat = cfloat;
-/** create a custom vec2 function (use with [[tag]]) */
-function cvec2(sourceLists, externalFuncs = []) {
- return new ExprVec2(sourceLists, genCustomNames(sourceLists)).addFuncs(externalFuncs);
-}
-exports.cvec2 = cvec2;
-/** create a custom vec3 function (use with [[tag]]) */
-function cvec3(sourceLists, externalFuncs = []) {
- return new ExprVec3(sourceLists, genCustomNames(sourceLists)).addFuncs(externalFuncs);
-}
-exports.cvec3 = cvec3;
-/** create a custom vec4 function (use with [[tag]]) */
-function cvec4(sourceLists, externalFuncs = []) {
- return new ExprVec4(sourceLists, genCustomNames(sourceLists)).addFuncs(externalFuncs);
-}
-exports.cvec4 = cvec4;
-class Mutable {
- constructor(primitive, name) {
- this.primitive = primitive;
- this.name = name;
- }
- parse(buildInfo, defaultName, enc) {
- if (enc === undefined) {
- throw new Error("tried to put a mutable expression at the top level");
- }
- // accept the default name if given no name
- if (this.name === undefined)
- this.name = defaultName + enc.id;
- // set to true so they are set to their default values on first draw
- buildInfo.uniformTypes[this.name] = this.primitive.typeString();
- // add the name mapping
- enc.uniformValChangeMap[this.name] = {
- val: this.primitive,
- changed: true,
- };
- // add the new type to the map
- enc.defaultNameMap[defaultName + enc.id] = this.name;
- return this.name;
- }
- applyUniform(gl, loc) {
- this.primitive.applyUniform(gl, loc);
- }
- typeString() {
- return this.primitive.typeString();
- }
- getSampleNum() {
- return 0;
- }
- brandExprWithRegion(space) {
- return this;
- }
-}
-exports.Mutable = Mutable;
-/**
- * makes a primitive value mutable. wrapping a [[PrimitiveVec]] or
- * [[PrimitiveFloat]] in [[mut]] before passing it into an expression will
- * allow you to use the setters on that expression to change those values at
- * runtime
- * @param val the primitive float or primitive vec to make mutable
- * @param name the optional name for the uniform
- */
-function mut(val, name) {
- const primitive = typeof val === "number" ? wrapInValue(val) : val;
- return new Mutable(primitive, name);
-}
-exports.mut = mut;
-class Primitive {
- parse() {
- return this.toString();
- }
- getSampleNum() {
- return 0;
- }
- brandExprWithRegion(space) {
- return this;
- }
-}
-exports.Primitive = Primitive;
-class PrimitiveFloat extends Primitive {
- constructor(num) {
- if (!isFinite(num))
- throw new Error("number not finite");
- super();
- this.value = num;
- }
- toString() {
- let str = "" + this.value;
- if (!str.includes("."))
- str += ".";
- return str;
- }
- typeString() {
- return "float";
- }
- applyUniform(gl, loc) {
- gl.uniform1f(loc, this.value);
- }
-}
-exports.PrimitiveFloat = PrimitiveFloat;
-class PrimitiveVec extends Primitive {
- constructor(comps) {
- super();
- this.values = comps;
- }
- typeString() {
- return ("vec" + this.values.length);
- }
- toString() {
- return `${this.typeString()}(${this.values
- .map((n) => toGLSLFloatString(n))
- .join(", ")})`;
- }
-}
-exports.PrimitiveVec = PrimitiveVec;
-class PrimitiveVec2 extends PrimitiveVec {
- applyUniform(gl, loc) {
- gl.uniform2f(loc, this.values[0], this.values[1]);
- }
-}
-exports.PrimitiveVec2 = PrimitiveVec2;
-class PrimitiveVec3 extends PrimitiveVec {
- applyUniform(gl, loc) {
- gl.uniform3f(loc, this.values[0], this.values[1], this.values[2]);
- }
-}
-exports.PrimitiveVec3 = PrimitiveVec3;
-class PrimitiveVec4 extends PrimitiveVec {
- applyUniform(gl, loc) {
- gl.uniform4f(loc, this.values[0], this.values[1], this.values[2], this.values[3]);
- }
-}
-exports.PrimitiveVec4 = PrimitiveVec4;
-class BasicVec extends Expr {
- constructor(sourceLists, defaultNames) {
- super(sourceLists, defaultNames);
- // this cast is fine as long as you only instantiate these with the
- // shorthand version and not the constructor
- const values = sourceLists.values;
- this.values = values;
- this.defaultNames = defaultNames;
- }
- typeString() {
- return ("vec" + this.values.length);
- }
- /** sets a component of the vector */
- setComp(index, primitive) {
- if (index < 0 || index >= this.values.length) {
- throw new Error("out of bounds of setting component");
- }
- this.setUniform(this.defaultNames[index] + this.id, wrapInValue(primitive));
- }
-}
-exports.BasicVec = BasicVec;
-class BasicVec2 extends BasicVec {
- constructor() {
- super(...arguments);
- this.bvec2 = undefined; // brand for nominal typing
- }
-}
-exports.BasicVec2 = BasicVec2;
-class BasicVec3 extends BasicVec {
- constructor() {
- super(...arguments);
- this.bvec3 = undefined; // brand for nominal typing
- }
-}
-exports.BasicVec3 = BasicVec3;
-class BasicVec4 extends BasicVec {
- constructor() {
- super(...arguments);
- this.bvec4 = undefined; // brand for nominal typing
- }
-}
-exports.BasicVec4 = BasicVec4;
-class ExprVec extends Expr {
- constructor(sourceLists, defaultNames) {
- super(sourceLists, defaultNames);
- const values = sourceLists.values;
- this.values = values;
- this.defaultNames = defaultNames;
- }
-}
-exports.ExprVec = ExprVec;
-class BasicFloat extends Expr {
- constructor(sourceLists, defaultNames) {
- super(sourceLists, defaultNames);
- this.float = undefined; // brand for nominal typing
- }
- setVal(primitive) {
- this.setUniform("uFloat" + this.id, wrapInValue(primitive));
- }
- typeString() {
- return "float";
- }
-}
-exports.BasicFloat = BasicFloat;
-class ExprFloat extends Expr {
- constructor(sourceLists, defaultNames) {
- super(sourceLists, defaultNames);
- this.float = undefined; // brand for nominal typing
- }
- setVal(primitive) {
- this.setUniform("uFloat" + this.id, wrapInValue(primitive));
- }
- typeString() {
- return "float";
- }
-}
-exports.ExprFloat = ExprFloat;
-function float(value) {
- if (typeof value === "number")
- value = wrapInValue(value);
- return new BasicFloat({ sections: ["", ""], values: [value] }, ["uFloat"]);
-}
-exports.float = float;
-class ExprVec2 extends ExprVec {
- constructor() {
- super(...arguments);
- this.vec2 = undefined; // brand for nominal typing
- }
- typeString() {
- return "vec2";
- }
-}
-exports.ExprVec2 = ExprVec2;
-class ExprVec3 extends ExprVec {
- constructor() {
- super(...arguments);
- this.vec3 = undefined; // brand for nominal typing
- }
- typeString() {
- return "vec3";
- }
-}
-exports.ExprVec3 = ExprVec3;
-class ExprVec4 extends ExprVec {
- constructor() {
- super(...arguments);
- this.vec4 = undefined; // brand for nominal typing
- }
- repeat(num) {
- return new mergepass_1.EffectLoop([this], { num: num });
- }
- genPrograms(gl, vShader, uniformLocs, shaders) {
- return new mergepass_1.EffectLoop([this], { num: 1 }).genPrograms(gl, vShader, uniformLocs, shaders);
- }
- typeString() {
- return "vec4";
- }
-}
-exports.ExprVec4 = ExprVec4;
-class WrappedExpr {
- constructor(expr) {
- this.expr = expr;
- }
- typeString() {
- return this.expr.typeString();
- }
- parse(buildInfo, defaultName, enc) {
- return this.expr.parse(buildInfo, defaultName, enc);
- }
- getSampleNum() {
- return this.expr.getSampleNum();
- }
- brandExprWithRegion(space) {
- return this.expr.brandExprWithRegion(space);
- }
-}
-exports.WrappedExpr = WrappedExpr;
-class Operator extends Expr {
- constructor(ret, sourceLists, defaultNames) {
- super(sourceLists, defaultNames);
- this.ret = ret;
- }
- typeString() {
- return this.ret.typeString();
- }
-}
-exports.Operator = Operator;
-/** creates a primitive float */
-function pfloat(num) {
- return new PrimitiveFloat(num);
-}
-exports.pfloat = pfloat;
-function wrapInValue(num) {
- if (num === undefined)
- return undefined;
- if (typeof num === "number")
- return pfloat(num);
- return num;
-}
-exports.wrapInValue = wrapInValue;
-/**
- * takes a template strings array and converts it to a source list; very useful
- * for [[cfloat]], [[cvec2]], [[cvec3]] and [[cvec4]]
- */
-function tag(strings, ...values) {
- return { sections: strings.concat([]), values: values };
-}
-exports.tag = tag;
-
-},{"../mergepass":63,"../utils":65,"../webglprogramloop":66}],26:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.fcolor = exports.FragColorExpr = void 0;
-const expr_1 = require("./expr");
-/** fragment color expression */
-class FragColorExpr extends expr_1.ExprVec4 {
- constructor() {
- super(expr_1.tag `gl_FragColor`, []);
- this.needs.centerSample = true;
- }
-}
-exports.FragColorExpr = FragColorExpr;
-/** creates an expression that evaluates to the fragment color */
-function fcolor() {
- return new FragColorExpr();
-}
-exports.fcolor = fcolor;
-
-},{"./expr":25}],27:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.pixel = exports.FragCoordExpr = void 0;
-const expr_1 = require("./expr");
-/** frag coord expression (xy components only) */
-class FragCoordExpr extends expr_1.ExprVec2 {
- constructor() {
- super(expr_1.tag `gl_FragCoord.xy`, []);
- }
-}
-exports.FragCoordExpr = FragCoordExpr;
-/**
- * creates an expression that evaluates to the frag coord in pixels (samplers
- * take normalized coordinates, so you might want [[nfcoord]] instead)
- */
-function pixel() {
- return new FragCoordExpr();
-}
-exports.pixel = pixel;
-
-},{"./expr":25}],28:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.fxaa = void 0;
-const expr_1 = require("./expr");
-const glslfunctions_1 = require("../glslfunctions");
-/** FXAA expression */
-class FXAAExpr extends expr_1.ExprVec4 {
- constructor() {
- super(expr_1.tag `fxaa()`, []);
- this.externalFuncs = [glslfunctions_1.glslFuncs.fxaa];
- this.needs.neighborSample = true;
- }
-}
-/** FXAA antaliasing expression */
-function fxaa() {
- return new FXAAExpr();
-}
-exports.fxaa = fxaa;
-
-},{"../glslfunctions":61,"./expr":25}],29:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.gaussian = exports.GaussianExpr = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-/** gaussian expression */
-class GaussianExpr extends expr_1.ExprFloat {
- constructor(x, a, b) {
- super(expr_1.tag `gaussian(${x}, ${a}, ${b})`, ["uFloatX", "uFloatA", "uFloatB"]);
- this.x = x;
- this.a = a;
- this.b = b;
- this.externalFuncs = [glslfunctions_1.glslFuncs.gaussian];
- }
- setX(x) {
- this.setUniform("uFloatX" + this.id, x);
- this.x = expr_1.wrapInValue(x);
- }
- setA(a) {
- this.setUniform("uFloatA" + this.id, a);
- this.a = expr_1.wrapInValue(a);
- }
- setB(b) {
- this.setUniform("uFloatB" + this.id, b);
- this.b = expr_1.wrapInValue(b);
- }
-}
-exports.GaussianExpr = GaussianExpr;
-/**
- * gaussian function that defaults to normal distribution
- * @param x x position in the curve
- * @param a horizontal position of peak (defaults to 0 for normal distribution)
- * @param b horizontal stretch of the curve (defaults to 1 for normal distribution)
- */
-function gaussian(x, a = 0, b = 1) {
- return new GaussianExpr(expr_1.wrapInValue(x), expr_1.wrapInValue(a), expr_1.wrapInValue(b));
-}
-exports.gaussian = gaussian;
-
-},{"../glslfunctions":61,"./expr":25}],30:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.get4comp = exports.get3comp = exports.get2comp = exports.getcomp = exports.Get4CompExpr = exports.Get3CompExpr = exports.Get2CompExpr = exports.GetCompExpr = exports.checkLegalComponents = exports.typeStringToLength = void 0;
-const expr_1 = require("./expr");
-// TODO this should probably be somewhere else
-/** @ignore */
-function typeStringToLength(str) {
- switch (str) {
- case "float":
- return 1;
- case "vec2":
- return 2;
- case "vec3":
- return 3;
- case "vec4":
- return 4;
- }
-}
-exports.typeStringToLength = typeStringToLength;
-/** @ignore */
-function genCompSource(vec, components) {
- return {
- sections: ["", "." + components],
- values: [vec],
- };
-}
-/**
- * checks if components accessing a vector are legal. components can be illegal
- * if they mix sets (e.g. `v.rgzw`) or contain characters outside of any set
- * (e.g. `v.lmno`)
- * @param comps components string
- * @param vec vector being accessed
- */
-function checkLegalComponents(comps, vec) {
- const check = (range, domain) => {
- let inside = 0;
- let outside = 0;
- for (const c of range) {
- domain.includes(c) ? inside++ : outside++;
- }
- return inside === inside && !outside;
- };
- const inLen = typeStringToLength(vec.typeString());
- const rgbaCheck = check(comps, "rgba".substr(0, inLen));
- const xyzwCheck = check(comps, "xyzw".substr(0, inLen));
- const stpqCheck = check(comps, "stpq".substr(0, inLen));
- if (!(rgbaCheck || xyzwCheck || stpqCheck)) {
- throw new Error("component sets are mixed or incorrect entirely");
- }
-}
-exports.checkLegalComponents = checkLegalComponents;
-/**
- * performs all validity checks of [[checkLegalComponents]] and checks if the
- * number of accessed components does not exceed the size of the vector being
- * assigned to
- * @param comps components string
- * @param outLen length of the resultant vector
- * @param vec vector being accessed
- */
-function checkGetComponents(comps, outLen, vec) {
- if (comps.length > outLen)
- throw new Error("too many components");
- checkLegalComponents(comps, vec);
-}
-/** get component expression */
-class GetCompExpr extends expr_1.ExprFloat {
- constructor(vec, comps) {
- checkGetComponents(comps, 1, vec);
- super(genCompSource(vec, comps), ["uVec1Min"]);
- this.vec1Min = vec;
- }
- setVec(vec) {
- this.setUniform("uVec1Min", vec);
- this.vec1Min = vec;
- }
-}
-exports.GetCompExpr = GetCompExpr;
-/** get 2 components expression */
-class Get2CompExpr extends expr_1.ExprVec2 {
- constructor(vec, comps) {
- checkGetComponents(comps, 2, vec);
- super(genCompSource(vec, comps), ["uVec2Min"]);
- this.vec2Min = vec;
- }
- setVec(vec) {
- this.setUniform("uVec2Min", vec);
- this.vec2Min = vec;
- }
-}
-exports.Get2CompExpr = Get2CompExpr;
-/** get 3 components expression */
-class Get3CompExpr extends expr_1.ExprVec3 {
- constructor(vec, comps) {
- checkGetComponents(comps, 3, vec);
- super(genCompSource(vec, comps), ["uVec3Min"]);
- this.vec3Min = vec;
- }
- setVec(vec) {
- this.setUniform("uVec3Min", vec);
- this.vec3Min = vec;
- }
-}
-exports.Get3CompExpr = Get3CompExpr;
-/** get 3 components expression */
-class Get4CompExpr extends expr_1.ExprVec4 {
- constructor(vec, comps) {
- checkGetComponents(comps, 4, vec);
- super(genCompSource(vec, comps), ["uVec4Min"]);
- this.vec4Min = vec;
- }
- setVec(vec) {
- this.setUniform("uVec4Min", vec);
- this.vec4Min = vec;
- }
-}
-exports.Get4CompExpr = Get4CompExpr;
-/**
- * creates an expression that gets 1 component from a vector
- * @param vec the vector to get components of
- * @param comps components string
- */
-function getcomp(vec, comps) {
- return new GetCompExpr(vec, comps);
-}
-exports.getcomp = getcomp;
-/**
- * creates an expression that gets 2 components from a vector
- * @param vec the vector to get components of
- * @param comps components string
- */
-function get2comp(vec, comps) {
- return new Get2CompExpr(vec, comps);
-}
-exports.get2comp = get2comp;
-/**
- * creates an expression that gets 3 components from a vector
- * @param vec the vector to get components of
- * @param comps components string
- */
-function get3comp(vec, comps) {
- return new Get3CompExpr(vec, comps);
-}
-exports.get3comp = get3comp;
-/**
- * creates an expression that gets 4 components from a vector
- * @param vec the vector to get components of
- * @param comps components string
- */
-function get4comp(vec, comps) {
- return new Get4CompExpr(vec, comps);
-}
-exports.get4comp = get4comp;
-
-},{"./expr":25}],31:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.godrays = exports.GodRaysExpr = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-const fragcolorexpr_1 = require("./fragcolorexpr");
-const vecexprs_1 = require("./vecexprs");
-/**
- * @ignore
- * the number of samples in the source code already
- */
-const DEFAULT_SAMPLES = 100;
-/** godrays expression */
-class GodRaysExpr extends expr_1.ExprVec4 {
- // sane godray defaults from https://github.com/Erkaman/glsl-godrays/blob/master/example/index.js
- 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) {
- // TODO the metaprogramming here is not so good!
- // leaving off the function call section for now (we addd it back later)
- 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)})`;
- // TODO make this more generic
- // append the _ onto the function name
- // also add _depth if this is a version of the function that uses depth buffer
- const customName = `godrays${convertDepth !== undefined ? "_depth" : ""}${numSamples !== 100 ? "_s" + numSamples : ""}(`;
- sourceLists.sections[0] = customName;
- super(sourceLists, [
- "uCol",
- "uExposure",
- "uDecay",
- "uDensity",
- "uWeight",
- "uLightPos",
- "uThreshold",
- "uNewColor",
- ]);
- this.col = col;
- this.exposure = exposure;
- this.decay = decay;
- this.density = density;
- this.weight = weight;
- this.lightPos = lightPos;
- this.threshold = convertDepth === null || convertDepth === void 0 ? void 0 : convertDepth.threshold;
- this.newColor = convertDepth === null || convertDepth === void 0 ? void 0 : convertDepth.newColor;
- // will be 1 if needs to convert depth, and 0 otherwise
- this.funcIndex = ~~(convertDepth !== undefined);
- let customGodRayFunc = glslfunctions_1.glslFuncs.godrays
- .split("godrays(")
- .join(customName)
- .replace(`NUM_SAMPLES = ${DEFAULT_SAMPLES}`, "NUM_SAMPLES = " + numSamples);
- if (convertDepth !== undefined) {
- // with regex, uncomment the line in the source code that does the
- // conversion (if you think about it that's basically what a preprocessor
- // does...)
- customGodRayFunc = customGodRayFunc.replace(/\/\/uncomment\s/g, "");
- this.externalFuncs.push(glslfunctions_1.glslFuncs.depth2occlusion);
- }
- this.externalFuncs.push(customGodRayFunc);
- this.brandExprWithChannel(this.funcIndex, samplerNum);
- }
- /** sets the light color */
- setColor(color) {
- this.setUniform("uCol" + this.id, color);
- this.col = color;
- }
- /** sets the exposure */
- setExposure(exposure) {
- this.setUniform("uExposure" + this.id, exposure);
- this.exposure = expr_1.wrapInValue(exposure);
- }
- /** sets the decay */
- setDecay(decay) {
- this.setUniform("uDecay" + this.id, decay);
- this.decay = expr_1.wrapInValue(decay);
- }
- /** sets the density */
- setDensity(density) {
- this.setUniform("uDensity" + this.id, density);
- this.density = expr_1.wrapInValue(density);
- }
- /** sets the weight */
- setWeight(weight) {
- this.setUniform("uWeight" + this.id, weight);
- this.weight = expr_1.wrapInValue(weight);
- }
- /** sets the light position */
- setLightPos(lightPos) {
- this.setUniform("uLightPos" + this.id, lightPos);
- this.lightPos = lightPos;
- }
- // these only matter when you're using a depth buffer and not an occlusion
- // buffer (although right now, you'll still be able to set them)
- setThreshold(threshold) {
- this.setUniform("uThreshold" + this.id, threshold);
- this.threshold = expr_1.wrapInValue(threshold);
- }
- setNewColor(newColor) {
- this.setUniform("uNewColor" + this.id, newColor);
- this.newColor = newColor;
- }
-}
-exports.GodRaysExpr = GodRaysExpr;
-/**
- * create a godrays expression which requires an occlusion map; all values are
- * mutable by default
- * @param options object that defines godrays properties (has sane defaults)
- */
-function godrays(options = {}) {
- 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
- ? undefined
- : {
- threshold: expr_1.wrapInValue(options.convertDepth.threshold),
- newColor: options.convertDepth.newColor,
- });
-}
-exports.godrays = godrays;
-
-},{"../glslfunctions":61,"./expr":25,"./fragcolorexpr":26,"./vecexprs":59}],32:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.grain = exports.GrainExpr = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-// TODO consider getting rid of this since it's easy to make your own with
-// `random` and `brightness`
-/** grain expression */
-class GrainExpr extends expr_1.ExprVec4 {
- constructor(grain) {
- super(expr_1.tag `vec4((1.0 - ${grain} * random(gl_FragCoord.xy)) * gl_FragColor.rgb, gl_FragColor.a);`, ["uGrain"]);
- this.grain = grain;
- this.externalFuncs = [glslfunctions_1.glslFuncs.random];
- this.needs.centerSample = true;
- }
- /** sets the grain level */
- setGrain(grain) {
- this.setUniform("uGrain" + this.id, grain);
- this.grain = expr_1.wrapInValue(grain);
- }
-}
-exports.GrainExpr = GrainExpr;
-/**
- * creates an expression that adds random grain
- * @param val how much the grain should impact the image (0 to 1 is reasonable)
- */
-function grain(val) {
- return new GrainExpr(expr_1.wrapInValue(val));
-}
-exports.grain = grain;
-
-},{"../glslfunctions":61,"./expr":25}],33:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.hsv2rgb = exports.HSVToRGBExpr = void 0;
-const expr_1 = require("./expr");
-const glslfunctions_1 = require("../glslfunctions");
-/** HSV to RGB expression */
-class HSVToRGBExpr extends expr_1.ExprVec4 {
- constructor(color) {
- super(expr_1.tag `hsv2rgb(${color})`, ["uHSVCol"]);
- this.color = color;
- this.externalFuncs = [glslfunctions_1.glslFuncs.hsv2rgb];
- }
- /** sets the color to convert */
- setColor(color) {
- this.setUniform("uHSVCol", color);
- this.color = color;
- }
-}
-exports.HSVToRGBExpr = HSVToRGBExpr;
-/**
- * converts a color (with an alpha compoment) from hsv to rgb
- * @param col the hsva color to convert to rgba
- */
-function hsv2rgb(col) {
- return new HSVToRGBExpr(col);
-}
-exports.hsv2rgb = hsv2rgb;
-
-},{"../glslfunctions":61,"./expr":25}],34:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.invert = exports.InvertExpr = void 0;
-const expr_1 = require("./expr");
-const glslfunctions_1 = require("../glslfunctions");
-/** invert expression */
-class InvertExpr extends expr_1.ExprVec4 {
- constructor(color) {
- super(expr_1.tag `invert(${color})`, ["uColor"]);
- this.externalFuncs = [glslfunctions_1.glslFuncs.invert];
- this.color = color;
- }
- /** sets the color */
- setColor(color) {
- this.setUniform("uColor", color);
- this.color = color;
- }
-}
-exports.InvertExpr = InvertExpr;
-/**
- * creates an expression that inverts the color, keeping the original alpha
- */
-function invert(col) {
- return new InvertExpr(col);
-}
-exports.invert = invert;
-
-},{"../glslfunctions":61,"./expr":25}],35:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.len = exports.LenExpr = void 0;
-const expr_1 = require("./expr");
-/** length expression */
-class LenExpr extends expr_1.ExprFloat {
- constructor(vec) {
- super(expr_1.tag `length(${vec})`, ["uVec"]);
- this.vec = vec;
- }
- setVec(vec) {
- this.setUniform("uVec" + this.id, vec);
- this.vec = vec;
- }
-}
-exports.LenExpr = LenExpr;
-/** creates an expreession that calculates the length of a vector */
-function len(vec) {
- return new LenExpr(vec);
-}
-exports.len = len;
-
-},{"./expr":25}],36:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.monochrome = exports.MonochromeExpr = void 0;
-const expr_1 = require("./expr");
-const glslfunctions_1 = require("../glslfunctions");
-/** monochrome expression */
-class MonochromeExpr extends expr_1.ExprVec4 {
- constructor(color) {
- super(expr_1.tag `monochrome(${color})`, ["uColor"]);
- this.externalFuncs = [glslfunctions_1.glslFuncs.monochrome];
- this.color = color;
- }
- /** sets the color */
- setColor(color) {
- this.setUniform("uColor", color);
- this.color = color;
- }
-}
-exports.MonochromeExpr = MonochromeExpr;
-/**
- * creates an expression that converts a color into grayscale, keeping the
- * original alpha
- */
-function monochrome(col) {
- return new MonochromeExpr(col);
-}
-exports.monochrome = monochrome;
-
-},{"../glslfunctions":61,"./expr":25}],37:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.motionblur = exports.MotionBlurLoop = void 0;
-const mergepass_1 = require("../mergepass");
-const channelsampleexpr_1 = require("./channelsampleexpr");
-const expr_1 = require("./expr");
-const fragcolorexpr_1 = require("./fragcolorexpr");
-const opexpr_1 = require("./opexpr");
-/** frame averaging motion blur loop */
-class MotionBlurLoop extends mergepass_1.EffectLoop {
- constructor(target = 0, persistence = expr_1.float(expr_1.mut(0.3))) {
- const col1 = opexpr_1.op(channelsampleexpr_1.channel(target), "*", persistence);
- const col2 = opexpr_1.op(fragcolorexpr_1.fcolor(), "*", opexpr_1.op(1, "-", persistence));
- const effects = [
- mergepass_1.loop([opexpr_1.op(col1, "+", col2)]).target(target),
- channelsampleexpr_1.channel(target),
- ];
- super(effects, { num: 1 });
- this.persistence = persistence;
- }
- /** set the persistence (keep between 0 and 1) */
- setPersistence(float) {
- if (!(this.persistence instanceof expr_1.BasicFloat))
- throw new Error("persistence expression not basic float");
- this.persistence.setVal(float);
- }
-}
-exports.MotionBlurLoop = MotionBlurLoop;
-/**
- * creates a frame averaging motion blur effect
- * @param target the channel where your accumulation buffer is (defaults to 0,
- * which you might be using for something like the depth texture, so be sure to
- * change this to suit your needs)
- * @param persistence close to 0 is more ghostly, and close to 1 is nearly no
- * motion blur at all (defaults to 0.3)
- */
-function motionblur(target, persistence) {
- return new MotionBlurLoop(target, expr_1.wrapInValue(persistence));
-}
-exports.motionblur = motionblur;
-
-},{"../mergepass":63,"./channelsampleexpr":19,"./expr":25,"./fragcolorexpr":26,"./opexpr":43}],38:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.mouse = exports.MouseExpr = void 0;
-const expr_1 = require("./expr");
-/** mouse position expression */
-class MouseExpr extends expr_1.ExprVec2 {
- constructor() {
- super(expr_1.tag `uMouse`, []);
- this.needs.mouseUniform = true;
- }
-}
-exports.MouseExpr = MouseExpr;
-/**
- * creates an expression that evaluates to a vector representing the mouse
- * position in pixels
- */
-function mouse() {
- return new MouseExpr();
-}
-exports.mouse = mouse;
-
-},{"./expr":25}],39:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.center = exports.NormCenterFragCoordExpr = void 0;
-const expr_1 = require("./expr");
-/** normalized centered frag coord expression */
-class NormCenterFragCoordExpr extends expr_1.ExprVec2 {
- constructor() {
- super(expr_1.tag `(gl_FragCoord.xy / uResolution - 0.5)`, []);
- }
-}
-exports.NormCenterFragCoordExpr = NormCenterFragCoordExpr;
-/**
- * creates an expression that calculates the normalized centered coord
- * (coordinates range from -0.5 to 0.5)
- */
-function center() {
- return new NormCenterFragCoordExpr();
-}
-exports.center = center;
-
-},{"./expr":25}],40:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.norm = exports.NormExpr = void 0;
-const expr_1 = require("./expr");
-/** normalize expression */
-class NormExpr extends expr_1.Operator {
- constructor(vec) {
- super(vec, expr_1.tag `normalize(${vec})`, ["uVec"]);
- this.vec = vec;
- }
- /** sets the vec to normalize */
- setVec(vec) {
- this.setUniform("uVec" + this.id, vec);
- this.vec = vec;
- }
-}
-exports.NormExpr = NormExpr;
-/** creates an expression that normalizes a vector */
-function norm(vec) {
- return new NormExpr(vec);
-}
-exports.norm = norm;
-
-},{"./expr":25}],41:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.pos = exports.NormFragCoordExpr = void 0;
-const expr_1 = require("./expr");
-/** normalized frag coord expression */
-class NormFragCoordExpr extends expr_1.ExprVec2 {
- constructor() {
- // don't remove these parens! even if you think you are being clever about
- // order of operations
- super(expr_1.tag `(gl_FragCoord.xy / uResolution)`, []);
- }
-}
-exports.NormFragCoordExpr = NormFragCoordExpr;
-/**
- * creates an expression that calculates the normalized frag coord (coordinates
- * range from 0 to 1)
- */
-function pos() {
- return new NormFragCoordExpr();
-}
-exports.pos = pos;
-
-},{"./expr":25}],42:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.nmouse = exports.NormMouseExpr = void 0;
-const expr_1 = require("./expr");
-/** normalized mouse position expression */
-class NormMouseExpr extends expr_1.ExprVec2 {
- constructor() {
- super(expr_1.tag `(uMouse / uResolution.xy)`, []);
- this.needs.mouseUniform = true;
- }
-}
-exports.NormMouseExpr = NormMouseExpr;
-/**
- * creates an expression that calculates the normalized mouse position
- * (coordinates range from 0 to 1)
- */
-function nmouse() {
- return new NormMouseExpr();
-}
-exports.nmouse = nmouse;
-
-},{"./expr":25}],43:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.op = exports.OpExpr = void 0;
-const expr_1 = require("./expr");
-function genOpSourceList(left, op, right) {
- return {
- sections: ["(", ` ${op} `, ")"],
- values: [left, right],
- };
-}
-class OpExpr extends expr_1.Operator {
- constructor(left, op, right) {
- super(left, genOpSourceList(left, op, right), ["uLeft", "uRight"]);
- this.left = left;
- this.right = right;
- }
- setLeft(left) {
- this.setUniform("uLeft" + this.id, left);
- this.left = expr_1.wrapInValue(left);
- }
- setRight(right) {
- this.setUniform("uRight" + this.id, right);
- this.right = expr_1.wrapInValue(right);
- }
-}
-exports.OpExpr = OpExpr;
-// implementation
-/**
- * creates an arithmetic operator expression
- * @param left expression left of operator
- * @param op string representing arithmetic operator
- * @param right expression right of operator
- */
-function op(left, op, right) {
- return new OpExpr(expr_1.wrapInValue(left), op, expr_1.wrapInValue(right));
-}
-exports.op = op;
-
-},{"./expr":25}],44:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.fractalize = exports.perlin = exports.PerlinExpr = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-const opexpr_1 = require("./opexpr");
-/** Perlin noise expression */
-class PerlinExpr extends expr_1.ExprFloat {
- // TODO include a default
- constructor(pos) {
- super(expr_1.tag `gradientnoise(${pos})`, ["uPos"]);
- this.pos = pos;
- this.externalFuncs = [glslfunctions_1.glslFuncs.random2, glslfunctions_1.glslFuncs.gradientnoise];
- }
- /** sets the position to calculate noise value of */
- setPos(pos) {
- this.setUniform("uPos", pos);
- this.pos = pos;
- }
-}
-exports.PerlinExpr = PerlinExpr;
-/**
- * creates a perlin noise expression; values range from -1 to 1 but they tend
- * to be grayer than the [[simplex]] implementation
- * @param pos position
- */
-function perlin(pos) {
- return new PerlinExpr(pos);
-}
-exports.perlin = perlin;
-/**
- * take any function from a position to a float, and repeatedly sum calls to it
- * with doubling frequency and halving amplitude (works well with [[simplex]]
- * and [[perlin]])
- * @param pos position
- * @param octaves how many layers deep to make the fractal
- * @param func the function to fractalize
- */
-function fractalize(pos, octaves, func) {
- if (octaves < 0)
- throw new Error("octaves can't be < 0");
- const recurse = (pos, size, level) => {
- if (level <= 0)
- return expr_1.pfloat(0);
- return opexpr_1.op(func(opexpr_1.op(pos, "/", size * 2)), "+", recurse(pos, size / 2, level - 1));
- };
- return recurse(pos, 0.5, octaves);
-}
-exports.fractalize = fractalize;
-
-},{"../glslfunctions":61,"./expr":25,"./opexpr":43}],45:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.pblur = exports.PowerBlurLoop = void 0;
-const mergepass_1 = require("../mergepass");
-const blurexpr_1 = require("./blurexpr");
-const vecexprs_1 = require("./vecexprs");
-const expr_1 = require("./expr");
-const baseLog = (x, y) => Math.log(y) / Math.log(x);
-// TODO consider getting rid of this, as it pretty much never looks good
-/** power blur loop */
-class PowerBlurLoop extends mergepass_1.EffectLoop {
- constructor(size) {
- const side = blurexpr_1.gauss(expr_1.mut(vecexprs_1.pvec2(size, 0)));
- const up = blurexpr_1.gauss(expr_1.mut(vecexprs_1.pvec2(0, size)));
- const reps = Math.ceil(baseLog(2, size));
- super([side, up], {
- num: reps + 1,
- });
- this.size = size;
- this.loopInfo.func = (i) => {
- const distance = this.size / Math.pow(2, i);
- up.setDirection(vecexprs_1.pvec2(0, distance));
- side.setDirection(vecexprs_1.pvec2(distance, 0));
- };
- }
- /** sets the size of the radius */
- setSize(size) {
- this.size = size;
- this.loopInfo.num = Math.ceil(baseLog(2, size));
- }
-}
-exports.PowerBlurLoop = PowerBlurLoop;
-/**
- * fast approximate blur for large blur radius that might look good in some cases
- * @param size the radius of the blur
- */
-function pblur(size) {
- return new PowerBlurLoop(size);
-}
-exports.pblur = pblur;
-
-},{"../mergepass":63,"./blurexpr":16,"./expr":25,"./vecexprs":59}],46:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.random = exports.RandomExpr = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-const normfragcoordexpr_1 = require("./normfragcoordexpr");
-/** psuedorandom number expression */
-class RandomExpr extends expr_1.ExprFloat {
- constructor(seed = normfragcoordexpr_1.pos()) {
- super(expr_1.tag `random(${seed})`, ["uSeed"]);
- this.seed = seed;
- this.externalFuncs = [glslfunctions_1.glslFuncs.random];
- }
- /** sets the seed (vary this over time to get a moving effect) */
- setSeed(seed) {
- this.setUniform("uSeed", seed);
- this.seed = seed;
- }
-}
-exports.RandomExpr = RandomExpr;
-/**
- * creates expression that evaluates to a pseudorandom number between 0 and 1
- * @param seed vec2 to to seed the random number (defaults to the normalized
- * frag coord)
- */
-function random(seed) {
- return new RandomExpr(seed);
-}
-exports.random = random;
-
-},{"../glslfunctions":61,"./expr":25,"./normfragcoordexpr":41}],47:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.region = void 0;
-const mergepass_1 = require("../mergepass");
-const expr_1 = require("./expr");
-const getcompexpr_1 = require("./getcompexpr");
-const normfragcoordexpr_1 = require("./normfragcoordexpr");
-const opexpr_1 = require("./opexpr");
-const ternaryexpr_1 = require("./ternaryexpr");
-const fragcolorexpr_1 = require("./fragcolorexpr");
-// form: x1, y1, x2, y2
-function createDifferenceFloats(floats) {
- const axes = "xy";
- const differences = [];
- if (floats.length !== 4) {
- throw new Error("incorrect amount of points specified for region");
- }
- for (let i = 0; i < 2; i++) {
- differences.push(opexpr_1.op(getcompexpr_1.getcomp(normfragcoordexpr_1.pos(), axes[i]), "-", floats[i]));
- }
- for (let i = 2; i < floats.length; i++) {
- differences.push(opexpr_1.op(floats[i], "-", getcompexpr_1.getcomp(normfragcoordexpr_1.pos(), axes[i - 2])));
- }
- return differences;
-}
-/**
- * restrict an effect to a region of the screen
- * @param space top left, top right, bottom left, bottom right corners of the
- * region, or just a number if you wish to sample from a channel as the region
- * @param success expression for being inside the region
- * @param failure expression for being outside the region
- * @param not whether to invert the region
- */
-function region(space, success, failure, not = false) {
- const floats = Array.isArray(space)
- ? space.map((f) => expr_1.wrapInValue(f))
- : typeof space === "number"
- ? expr_1.wrapInValue(space)
- : space;
- if (failure instanceof mergepass_1.EffectLoop) {
- if (!(success instanceof mergepass_1.EffectLoop)) {
- [success, failure] = [failure, success]; // swap the order
- not = !not; // invert the region
- }
- }
- if (success instanceof mergepass_1.EffectLoop) {
- if (!(failure instanceof mergepass_1.EffectLoop)) {
- return success.regionWrap(floats, failure, true, not);
- }
- // double loop, so we have to do separately
- return mergepass_1.loop([
- success.regionWrap(floats, fragcolorexpr_1.fcolor(), false, not),
- failure.regionWrap(floats, fragcolorexpr_1.fcolor(), true, !not),
- ]);
- }
- return ternaryexpr_1.ternary(Array.isArray(floats) ? createDifferenceFloats(floats) : floats, success.brandExprWithRegion(floats), failure.brandExprWithRegion(floats), not);
-}
-exports.region = region;
-
-},{"../mergepass":63,"./expr":25,"./fragcolorexpr":26,"./getcompexpr":30,"./normfragcoordexpr":41,"./opexpr":43,"./ternaryexpr":55}],48:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.resolution = exports.ResolutionExpr = void 0;
-const expr_1 = require("./expr");
-/** resolution expression */
-class ResolutionExpr extends expr_1.ExprVec2 {
- constructor() {
- super(expr_1.tag `uResolution`, []);
- }
-}
-exports.ResolutionExpr = ResolutionExpr;
-/** creates an expression that evaluates to a vector representing the resolution */
-function resolution() {
- return new ResolutionExpr();
-}
-exports.resolution = resolution;
-
-},{"./expr":25}],49:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.rgb2hsv = exports.RGBToHSVExpr = void 0;
-const expr_1 = require("./expr");
-const glslfunctions_1 = require("../glslfunctions");
-/** RGB to HSV expression */
-class RGBToHSVExpr extends expr_1.ExprVec4 {
- constructor(color) {
- super(expr_1.tag `rgb2hsv(${color})`, ["uRGBCol"]);
- this.color = color;
- this.externalFuncs = [glslfunctions_1.glslFuncs.rgb2hsv];
- }
- /** sets the color to convert */
- setColor(color) {
- this.setUniform("uRGBCol", color);
- this.color = color;
- }
-}
-exports.RGBToHSVExpr = RGBToHSVExpr;
-/**
- * creates an expression that converts a color (with an alpha component) from
- * rgb to hsv
- * @param col the rgba color to convert to hsva
- */
-function rgb2hsv(col) {
- return new RGBToHSVExpr(col);
-}
-exports.rgb2hsv = rgb2hsv;
-
-},{"../glslfunctions":61,"./expr":25}],50:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.rotate = exports.RotateExpr = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-/** rotate expression */
-class RotateExpr extends expr_1.ExprVec2 {
- constructor(vec, angle) {
- super(expr_1.tag `rotate2d(${vec}, ${angle})`, ["uVec", "uAngle"]);
- this.vec = vec;
- this.angle = angle;
- this.externalFuncs = [glslfunctions_1.glslFuncs.rotate2d];
- }
- /** set the vector to rotate */
- setVec(vec) {
- this.setUniform("uVec" + this.id, vec);
- this.vec = vec;
- }
- /** set the angle to rotate by */
- setAngle(angle) {
- this.setUniform("uAngle" + this.id, angle);
- this.angle = expr_1.wrapInValue(angle);
- }
-}
-exports.RotateExpr = RotateExpr;
-/**
- * creates an expression that rotates a vector by a given angle
- * @param vec the vector to rotate
- * @param angle radians to rotate vector by
- */
-function rotate(vec, angle) {
- return new RotateExpr(vec, expr_1.wrapInValue(angle));
-}
-exports.rotate = rotate;
-
-},{"../glslfunctions":61,"./expr":25}],51:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.input = exports.SceneSampleExpr = void 0;
-const expr_1 = require("./expr");
-const normfragcoordexpr_1 = require("./normfragcoordexpr");
-/** scene sample expression */
-class SceneSampleExpr extends expr_1.ExprVec4 {
- constructor(coord = normfragcoordexpr_1.pos()) {
- super(expr_1.tag `texture2D(uSceneSampler, ${coord})`, ["uCoord"]);
- this.coord = coord;
- this.needs.sceneBuffer = true;
- }
- /** sets coordinate where scene is being sampled from */
- setCoord(coord) {
- this.setUniform("uCoord", coord);
- this.coord = coord;
- }
-}
-exports.SceneSampleExpr = SceneSampleExpr;
-/**
- * creates an expression that samples the original scene
- * @param vec where to sample the original scene texture (defaults to the
- * normalized frag coord, but change this if you want to transform the
- * coordinate space of the original image)
- */
-function input(vec) {
- return new SceneSampleExpr(vec);
-}
-exports.input = input;
-
-},{"./expr":25,"./normfragcoordexpr":41}],52:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.SetColorExpr = void 0;
-const expr_1 = require("./expr");
-/**
- * set fragment color expression (not needed for the user; used internally for
- * wrapping any kind of [[Vec4]] in an [[ExprVec4]])
- */
-class SetColorExpr extends expr_1.ExprVec4 {
- constructor(vec) {
- super(expr_1.tag `(${vec})`, ["uVal"]);
- this.vec = vec;
- }
-}
-exports.SetColorExpr = SetColorExpr;
-
-},{"./expr":25}],53:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.simplex = exports.SimplexNoise = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-/** simplex noise expression */
-class SimplexNoise extends expr_1.ExprFloat {
- constructor(pos) {
- super(expr_1.tag `simplexnoise(${pos})`, ["uPos"]);
- this.pos = pos;
- this.externalFuncs = [glslfunctions_1.glslFuncs.simplexhelpers, glslfunctions_1.glslFuncs.simplexnoise];
- }
- setPos(pos) {
- this.setUniform("uPos", pos);
- this.pos = pos;
- }
-}
-exports.SimplexNoise = SimplexNoise;
-/**
- * creates a simplex noise expression; values range from -1 to 1
- * @param pos position
- */
-function simplex(pos) {
- return new SimplexNoise(pos);
-}
-exports.simplex = simplex;
-
-},{"../glslfunctions":61,"./expr":25}],54:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.sobel = exports.SobelExpr = void 0;
-const glslfunctions_1 = require("../glslfunctions");
-const expr_1 = require("./expr");
-/** Sobel edge detection expression */
-class SobelExpr extends expr_1.ExprVec4 {
- constructor(samplerNum) {
- super(expr_1.tag `sobel()`, []);
- this.externalFuncs = [glslfunctions_1.glslFuncs.sobel];
- this.brandExprWithChannel(0, samplerNum);
- }
-}
-exports.SobelExpr = SobelExpr;
-/**
- * creates a Sobel edge detection expression that outputs the raw result; for
- * more highly processed edge detection expressions, see [[edgecolor]] or
- * [[edge]]
- * @param samplerNum where to sample from
- */
-function sobel(samplerNum) {
- return new SobelExpr(samplerNum);
-}
-exports.sobel = sobel;
-
-},{"../glslfunctions":61,"./expr":25}],55:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.ternary = exports.TernaryExpr = void 0;
-const expr_1 = require("./expr");
-function genTernarySourceList(floats, success, failure, not) {
- const sourceList = {
- sections: [`(${not ? "!" : ""}(`],
- values: [],
- };
- let counter = 0;
- // generate the boolean expression
- if (floats !== null) {
- for (const f of floats) {
- counter++;
- const last = counter === floats.length;
- sourceList.values.push(f);
- sourceList.sections.push(` > 0.${last ? ") ? " : " && "}`);
- }
- }
- else {
- sourceList.sections[0] += "uCount == 0) ? ";
- }
- // generate the success expression and colon
- sourceList.values.push(success);
- sourceList.sections.push(" : ");
- // generate the failure expression
- sourceList.values.push(failure);
- sourceList.sections.push(")");
- return sourceList;
-}
-class TernaryExpr extends expr_1.Operator {
- constructor(floats, success, failure, not) {
- super(success, genTernarySourceList(floats, success, failure, not), [
- ...(floats !== null
- ? Array.from(floats, (val, index) => "uFloat" + index)
- : []),
- "uSuccess",
- "uFailure",
- ]);
- this.success = success;
- this.failure = failure;
- this.needs.passCount = floats === null;
- }
-}
-exports.TernaryExpr = TernaryExpr;
-/**
- * creates a ternary expression; the boolean expression is if all the floats
- * given are greater than 0
- * @param floats if all these floats (or the single float) are above 0, then
- * evaluates to success expression
- * @param success
- * @param failure
- * @param not whether to invert the ternary
- */
-function ternary(floats, success, failure, not = false) {
- // TODO make this type safe (ran into a type error here)
- // wrap single float in array if need be
- if (!Array.isArray(floats) && floats !== null)
- floats = [floats].map((f) => expr_1.wrapInValue(f));
- // TODO get rid of this cast
- return new TernaryExpr(floats, expr_1.wrapInValue(success), expr_1.wrapInValue(failure), not);
-}
-exports.ternary = ternary;
-
-},{"./expr":25}],56:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.time = exports.TimeExpr = void 0;
-const expr_1 = require("./expr");
-/** time expression */
-class TimeExpr extends expr_1.ExprFloat {
- constructor() {
- super(expr_1.tag `uTime`, []);
- this.needs.timeUniform = true;
- }
-}
-exports.TimeExpr = TimeExpr;
-/** creates a time expression that evaluates to the current time */
-function time() {
- return new TimeExpr();
-}
-exports.time = time;
-
-},{"./expr":25}],57:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.translate = exports.TranslateExpr = void 0;
-const expr_1 = require("./expr");
-// really just adding two vecs together, but it might be confusing that there's
-// rotate but no translate, so this is included. also it could make some
-// operations more readable
-/** sets the translate expression */
-class TranslateExpr extends expr_1.ExprVec2 {
- constructor(vec, pos) {
- super(expr_1.tag `(${vec} + ${pos})`, ["uVec", "uPos"]);
- this.vec = vec;
- this.pos = pos;
- }
- /** sets the starting position */
- setVec(vec) {
- this.setUniform("uVec" + this.id, vec);
- this.vec = vec;
- }
- /** sets how far the vector will be translated */
- setPos(pos) {
- this.setUniform("uPos" + this.id, pos);
- this.pos = pos;
- }
-}
-exports.TranslateExpr = TranslateExpr;
-/** translates the position of a vector by another vector */
-function translate(vec, pos) {
- return new TranslateExpr(vec, pos);
-}
-exports.translate = translate;
-
-},{"./expr":25}],58:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.truedepth = exports.TrueDepthExpr = void 0;
-const expr_1 = require("./expr");
-const glslfunctions_1 = require("../glslfunctions");
-/** true depth expression */
-class TrueDepthExpr extends expr_1.ExprFloat {
- constructor(depth) {
- super(expr_1.tag `truedepth(${depth})`, ["uDist"]);
- this.depth = depth;
- this.externalFuncs = [glslfunctions_1.glslFuncs.truedepth];
- }
- /** sets the distance to convert to the true depth */
- setDist(depth) {
- this.setUniform("uDist", depth);
- this.depth = expr_1.wrapInValue(depth);
- }
-}
-exports.TrueDepthExpr = TrueDepthExpr;
-/** calculates the linear depth from inverse depth value `1 / distance` */
-function truedepth(depth) {
- return new TrueDepthExpr(expr_1.wrapInValue(depth));
-}
-exports.truedepth = truedepth;
-
-},{"../glslfunctions":61,"./expr":25}],59:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.pvec4 = exports.pvec3 = exports.pvec2 = exports.vec4 = exports.vec3 = exports.vec2 = void 0;
-const expr_1 = require("./expr");
-/** @ignore */
-function vecSourceList(...components) {
- const sections = ["vec" + components.length + "("];
- for (let i = 0; i < components.length - 1; i++) {
- sections.push(", ");
- }
- const defaultNames = [];
- for (let i = 0; i < components.length; i++) {
- defaultNames.push("uComp" + i);
- }
- sections.push(")");
- return [{ sections: sections, values: components }, defaultNames];
-}
-// expression vector shorthands
-/** creates a basic vec2 expression */
-function vec2(comp1, comp2) {
- return new expr_1.BasicVec2(...vecSourceList(...[comp1, comp2].map((c) => expr_1.wrapInValue(c))));
-}
-exports.vec2 = vec2;
-/** creates a basic vec3 expression */
-function vec3(comp1, comp2, comp3) {
- return new expr_1.BasicVec3(...vecSourceList(...[comp1, comp2, comp3].map((c) => expr_1.wrapInValue(c))));
-}
-exports.vec3 = vec3;
-/** creates a basic vec4 expression */
-function vec4(comp1, comp2, comp3, comp4) {
- return new expr_1.BasicVec4(...vecSourceList(...[comp1, comp2, comp3, comp4].map((c) => expr_1.wrapInValue(c))));
-}
-exports.vec4 = vec4;
-// primitive vector shorthands
-/** creates a primitive vec2 expression */
-function pvec2(comp1, comp2) {
- return new expr_1.PrimitiveVec2([comp1, comp2]);
-}
-exports.pvec2 = pvec2;
-/** creates a primitive vec3 expression */
-function pvec3(comp1, comp2, comp3) {
- return new expr_1.PrimitiveVec3([comp1, comp2, comp3]);
-}
-exports.pvec3 = pvec3;
-/** creates a primitive vec4 expression */
-function pvec4(comp1, comp2, comp3, comp4) {
- return new expr_1.PrimitiveVec4([comp1, comp2, comp3, comp4]);
-}
-exports.pvec4 = pvec4;
-
-},{"./expr":25}],60:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-
-},{}],61:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.glslFuncs = void 0;
-// adapted from The Book of Shaders
-/** glsl source code for external functions */
-exports.glslFuncs = {
- // TODO bad to calculate single pixel width every time; maybe it can be a need
- texture2D_region: `vec4 texture2D_region(
- float r_x_min,
- float r_y_min,
- float r_x_max,
- float r_y_max,
- sampler2D sampler,
- vec2 uv
-) {
- vec2 d = vec2(1., 1.) / uResolution; // pixel width
- 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)));
-}`,
- // TODO replace with a better one
- // adapted from The Book of Shaders
- random: `float random(vec2 st) {
- return fract(sin(dot(st.xy / 99., vec2(12.9898, 78.233))) * 43758.5453123);
-}`,
- // adapted from The Book of Shaders
- random2: `vec2 random2(vec2 st) {
- st = vec2(dot(st,vec2(127.1,311.7)), dot(st,vec2(269.5,183.3)));
- return -1.0 + 2.0*fract(sin(st)*43758.5453123);
-}`,
- rotate2d: `vec2 rotate2d(vec2 v, float angle) {
- return mat2(cos(angle), -sin(angle), sin(angle), cos(angle)) * v;
-}`,
- // adapted from The Book of Shaders
- hsv2rgb: `vec4 hsv2rgb(vec4 co){
- vec3 c = co.xyz;
- vec3 rgb = clamp(abs(mod(
- c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
- rgb = rgb * rgb * (3.0 - 2.0 * rgb);
- vec3 hsv = c.z * mix(vec3(1.0), rgb, c.y);
- return vec4(hsv.x, hsv.y, hsv.z, co.a);
-}`,
- // adapted from The Book of Shaders
- rgb2hsv: `vec4 rgb2hsv(vec4 co){
- vec3 c = co.rgb;
- vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
- vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
- vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
- float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
- return vec4(abs(q.z + (q.w - q.y) / (6.0 * d + e)),
- d / (q.x + e),
- q.x, co.a);
-}`,
- // all gaussian blurs adapted from:
- // https://github.com/Jam3/glsl-fast-gaussian-blur/blob/master/5.glsl
- gauss5: `vec4 gauss5(vec2 dir) {
- vec2 uv = gl_FragCoord.xy / uResolution;
- vec4 col = vec4(0.0);
- vec2 off1 = vec2(1.3333333333333333) * dir;
- col += texture2D(uSampler, uv) * 0.29411764705882354;
- col += texture2D(uSampler, uv + (off1 / uResolution)) * 0.35294117647058826;
- col += texture2D(uSampler, uv - (off1 / uResolution)) * 0.35294117647058826;
- return col;
-}`,
- gauss9: `vec4 gauss9(vec2 dir) {
- vec2 uv = gl_FragCoord.xy / uResolution;
- vec4 col = vec4(0.0);
- vec2 off1 = vec2(1.3846153846) * dir;
- vec2 off2 = vec2(3.2307692308) * dir;
- col += texture2D(uSampler, uv) * 0.2270270270;
- col += texture2D(uSampler, uv + (off1 / uResolution)) * 0.3162162162;
- col += texture2D(uSampler, uv - (off1 / uResolution)) * 0.3162162162;
- col += texture2D(uSampler, uv + (off2 / uResolution)) * 0.0702702703;
- col += texture2D(uSampler, uv - (off2 / uResolution)) * 0.0702702703;
- return col;
-}`,
- gauss13: `vec4 gauss13(vec2 dir) {
- vec2 uv = gl_FragCoord.xy / uResolution;
- vec4 col = vec4(0.0);
- vec2 off1 = vec2(1.411764705882353) * dir;
- vec2 off2 = vec2(3.2941176470588234) * dir;
- vec2 off3 = vec2(5.176470588235294) * dir;
- col += texture2D(uSampler, uv) * 0.1964825501511404;
- col += texture2D(uSampler, uv + (off1 / uResolution)) * 0.2969069646728344;
- col += texture2D(uSampler, uv - (off1 / uResolution)) * 0.2969069646728344;
- col += texture2D(uSampler, uv + (off2 / uResolution)) * 0.09447039785044732;
- col += texture2D(uSampler, uv - (off2 / uResolution)) * 0.09447039785044732;
- col += texture2D(uSampler, uv + (off3 / uResolution)) * 0.010381362401148057;
- col += texture2D(uSampler, uv - (off3 / uResolution)) * 0.010381362401148057;
- return col;
-}`,
- contrast: `vec4 contrast(float val, vec4 col) {
- col.rgb /= col.a;
- col.rgb = ((col.rgb - 0.5) * val) + 0.5;
- col.rgb *= col.a;
- return col;
-}`,
- brightness: `vec4 brightness(float val, vec4 col) {
- col.rgb /= col.a;
- col.rgb += val;
- col.rgb *= col.a;
- return col;
-}`,
- // adapted from https://www.shadertoy.com/view/ls3GWS which was adapted from
- // http://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-opengl-test-radeon-geforce/3/
- // original algorithm created by Timothy Lottes
- fxaa: `vec4 fxaa() {
- float FXAA_SPAN_MAX = 8.0;
- float FXAA_REDUCE_MUL = 1.0 / FXAA_SPAN_MAX;
- float FXAA_REDUCE_MIN = 1.0 / 128.0;
- float FXAA_SUBPIX_SHIFT = 1.0 / 4.0;
-
- vec2 rcpFrame = 1. / uResolution.xy;
- vec2 t_uv = gl_FragCoord.xy / uResolution.xy;
- vec4 uv = vec4(t_uv, t_uv - (rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT)));
-
- vec3 rgbNW = texture2D(uSampler, uv.zw).xyz;
- vec3 rgbNE = texture2D(uSampler, uv.zw + vec2(1,0) * rcpFrame.xy).xyz;
- vec3 rgbSW = texture2D(uSampler, uv.zw + vec2(0,1) * rcpFrame.xy).xyz;
- vec3 rgbSE = texture2D(uSampler, uv.zw + vec2(1,1) * rcpFrame.xy).xyz;
- vec4 rgbMfull = texture2D(uSampler, uv.xy);
- vec3 rgbM = rgbMfull.xyz;
- float alpha = rgbMfull.a;
-
- vec3 luma = vec3(0.299, 0.587, 0.114);
- float lumaNW = dot(rgbNW, luma);
- float lumaNE = dot(rgbNE, luma);
- float lumaSW = dot(rgbSW, luma);
- float lumaSE = dot(rgbSE, luma);
- float lumaM = dot(rgbM, luma);
-
- float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
- float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
-
- vec2 dir;
- dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
- dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
-
- float dirReduce = max(
- (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
- float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
-
- dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
- max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
- dir * rcpDirMin)) * rcpFrame.xy;
-
- vec3 rgbA = (1.0 / 2.0) * (
- texture2D(uSampler, uv.xy + dir * (1.0 / 3.0 - 0.5)).xyz +
- texture2D(uSampler, uv.xy + dir * (2.0 / 3.0 - 0.5)).xyz);
- vec3 rgbB = rgbA * (1.0 / 2.0) + (1.0 / 4.0) * (
- texture2D(uSampler, uv.xy + dir * (0.0 / 3.0 - 0.5)).xyz +
- texture2D(uSampler, uv.xy + dir * (3.0 / 3.0 - 0.5)).xyz);
-
- float lumaB = dot(rgbB, luma);
-
- if (lumaB < lumaMin || lumaB > lumaMax) {
- return vec4(rgbA.r, rgbA.g, rgbA.b, alpha);
- }
-
- return vec4(rgbB.r, rgbB.g, rgbB.b, alpha);
-}`,
- // normal curve is a = 0 and b = 1
- gaussian: `float gaussian(float x, float a, float b) {
- float e = 2.71828;
- return pow(e, -pow(x - a, 2.) / b);
-}`,
- // for calculating the true distance from 0 to 1 depth buffer
- // the small delta is to prevent division by zero, which is undefined behavior
- truedepth: `float truedepth(float i) {
- i = max(i, 0.00000001);
- return (1. - i) / i;
-}`,
- // based off of https://fabiensanglard.net/lightScattering/index.php
- godrays: `vec4 godrays(
- vec4 col,
- float exposure,
- float decay,
- float density,
- float weight,
- vec2 lightPos,
- float threshold,
- vec4 newColor
-) {
- vec2 texCoord = gl_FragCoord.xy / uResolution;
- vec2 deltaTexCoord = texCoord - lightPos;
-
- const int NUM_SAMPLES = 100;
- deltaTexCoord *= 1. / float(NUM_SAMPLES) * density;
- float illuminationDecay = 1.0;
-
- for (int i=0; i < NUM_SAMPLES; i++) {
- texCoord -= deltaTexCoord;
- vec4 sample = texture2D(uSampler, texCoord);
- //uncomment sample = depth2occlusion(sample, newColor, threshold);
- sample *= illuminationDecay * weight;
- col += sample;
- illuminationDecay *= decay;
- }
- return col * exposure;
-}`,
- depth2occlusion: `vec4 depth2occlusion(vec4 depthCol, vec4 newCol, float threshold) {
- float red = 1. - ceil(depthCol.r - threshold);
- return vec4(newCol.rgb * red, 1.0);
-}`,
- // adapted from The Book of Shaders, which was adapted from Inigo Quilez
- // from this example: https://www.shadertoy.com/view/XdXGW8
- gradientnoise: `float gradientnoise(vec2 st) {
- vec2 i = floor(st);
- vec2 f = fract(st);
-
- vec2 u = f * f * (3.0 - 2.0 * f);
-
- return mix(mix(dot(random2(i + vec2(0.0,0.0)), f - vec2(0.0, 0.0)),
- dot(random2(i + vec2(1.0,0.0)), f - vec2(1.0, 0.0)), u.x),
- mix(dot(random2(i + vec2(0.0,1.0)), f - vec2(0.0, 1.0)),
- dot(random2(i + vec2(1.0,1.0)), f - vec2(1.0, 1.0)), u.x), u.y);
-}`,
- // adapted from The Book of Shaders
- // https://thebookofshaders.com/edit.php#11/2d-snoise-clear.frag
- // this was adapted from this fast implementation
- // https://github.com/ashima/webgl-noise
- // simplex noise invented by Ken Perlin
- simplexnoise: `float simplexnoise(vec2 v) {
- // Precompute values for skewed triangular grid
- const vec4 C = vec4(0.211324865405187,
- // (3.0-sqrt(3.0))/6.0
- 0.366025403784439,
- // 0.5*(sqrt(3.0)-1.0)
- -0.577350269189626,
- // -1.0 + 2.0 * C.x
- 0.024390243902439);
- // 1.0 / 41.0
-
- // First corner (x0)
- vec2 i = floor(v + dot(v, C.yy));
- vec2 x0 = v - i + dot(i, C.xx);
-
- // Other two corners (x1, x2)
- vec2 i1 = vec2(0.0);
- i1 = (x0.x > x0.y)? vec2(1.0, 0.0):vec2(0.0, 1.0);
- vec2 x1 = x0.xy + C.xx - i1;
- vec2 x2 = x0.xy + C.zz;
-
- // Do some permutations to avoid
- // truncation effects in permutation
- i = mod289_2(i);
- vec3 p = permute(
- permute( i.y + vec3(0.0, i1.y, 1.0))
- + i.x + vec3(0.0, i1.x, 1.0 ));
-
- vec3 m = max(0.5 - vec3(
- dot(x0,x0),
- dot(x1,x1),
- dot(x2,x2)
- ), 0.0);
-
- m = m*m ;
- m = m*m ;
-
- // Gradients:
- // 41 pts uniformly over a line, mapped onto a diamond
- // The ring size 17*17 = 289 is close to a multiple
- // of 41 (41*7 = 287)
-
- vec3 x = 2.0 * fract(p * C.www) - 1.0;
- vec3 h = abs(x) - 0.5;
- vec3 ox = floor(x + 0.5);
- vec3 a0 = x - ox;
-
- // Normalise gradients implicitly by scaling m
- // Approximation of: m *= inversesqrt(a0*a0 + h*h);
- m *= 1.79284291400159 - 0.85373472095314 * (a0*a0+h*h);
-
- // Compute final noise value at P
- vec3 g = vec3(0.0);
- g.x = a0.x * x0.x + h.x * x0.y;
- g.yz = a0.yz * vec2(x1.x,x2.x) + h.yz * vec2(x1.y,x2.y);
- return 130.0 * dot(m, g);
-}`,
- // only useful for simplex noise
- simplexhelpers: `vec3 mod289_3(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
-vec2 mod289_2(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
-vec3 permute(vec3 x) { return mod289_3(((x*34.0)+1.0)*x); }`,
- // sobel adapted from https://gist.github.com/Hebali/6ebfc66106459aacee6a9fac029d0115
- sobel: `vec4 sobel() {
- vec2 uv = gl_FragCoord.xy / uResolution;
- vec4 k[8];
-
- float w = 1. / uResolution.x;
- float h = 1. / uResolution.y;
-
- k[0] = texture2D(uSampler, uv + vec2(-w, -h));
- k[1] = texture2D(uSampler, uv + vec2(0., -h));
- k[2] = texture2D(uSampler, uv + vec2(w, -h));
- k[3] = texture2D(uSampler, uv + vec2(-w, 0.));
-
- k[4] = texture2D(uSampler, uv + vec2(w, 0.));
- k[5] = texture2D(uSampler, uv + vec2(-w, h));
- k[6] = texture2D(uSampler, uv + vec2(0., h));
- k[7] = texture2D(uSampler, uv + vec2(w, h));
-
- vec4 edge_h = k[2] + (2. * k[4]) + k[7] - (k[0] + (2. * k[3]) + k[5]);
- vec4 edge_v = k[0] + (2. * k[1]) + k[2] - (k[5] + (2. * k[6]) + k[7]);
- vec4 sob = sqrt(edge_h * edge_h + edge_v * edge_v);
-
- return vec4(1. - sob.rgb, 1.);
-}`,
- // inlining a similar function will substitute in the full expression for
- // every component, so it's more efficient to have a function
- monochrome: `vec4 monochrome(vec4 col) {
- return vec4(vec3((col.r + col.g + col.b) / 3.), col.a);
-}`,
- invert: `vec4 invert(vec4 col) {
- return vec4(vec3(1., 1., 1.) - col.rgb, col.a);
-}`,
- channel: `vec4 channel(vec2 uv, sampler2D sampler) {
- return texture2D(sampler, uv);
-}`,
-};
-
-},{}],62:[function(require,module,exports){
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __exportStar = (this && this.__exportStar) || function(m, exports) {
- for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-__exportStar(require("./mergepass"), exports);
-__exportStar(require("./exprtypes"), exports);
-__exportStar(require("./glslfunctions"), exports);
-__exportStar(require("./settings"), exports);
-__exportStar(require("./exprs/blurexpr"), exports);
-__exportStar(require("./exprs/fragcolorexpr"), exports);
-__exportStar(require("./exprs/vecexprs"), exports);
-__exportStar(require("./exprs/opexpr"), exports);
-__exportStar(require("./exprs/powerblur"), exports);
-__exportStar(require("./exprs/blur2dloop"), exports);
-__exportStar(require("./exprs/lenexpr"), exports);
-__exportStar(require("./exprs/normexpr"), exports);
-__exportStar(require("./exprs/fragcoordexpr"), exports);
-__exportStar(require("./exprs/normfragcoordexpr"), exports);
-__exportStar(require("./exprs/normcenterfragcoordexpr"), exports);
-__exportStar(require("./exprs/scenesampleexpr"), exports);
-__exportStar(require("./exprs/brightnessexpr"), exports);
-__exportStar(require("./exprs/contrastexpr"), exports);
-__exportStar(require("./exprs/grainexpr"), exports);
-__exportStar(require("./exprs/getcompexpr"), exports);
-__exportStar(require("./exprs/changecompexpr"), exports);
-__exportStar(require("./exprs/rgbtohsvexpr"), exports);
-__exportStar(require("./exprs/hsvtorgbexpr"), exports);
-__exportStar(require("./exprs/timeexpr"), exports);
-__exportStar(require("./exprs/arity1"), exports);
-__exportStar(require("./exprs/arity2"), exports);
-__exportStar(require("./exprs/fxaaexpr"), exports);
-__exportStar(require("./exprs/channelsampleexpr"), exports);
-__exportStar(require("./exprs/dofloop"), exports);
-__exportStar(require("./exprs/truedepthexpr"), exports);
-__exportStar(require("./exprs/godraysexpr"), exports);
-__exportStar(require("./exprs/depthtoocclusionexpr"), exports);
-__exportStar(require("./exprs/resolutionexpr"), exports);
-__exportStar(require("./exprs/mouseexpr"), exports);
-__exportStar(require("./exprs/rotateexpr"), exports);
-__exportStar(require("./exprs/translateexpr"), exports);
-__exportStar(require("./exprs/normmouseexpr"), exports);
-__exportStar(require("./exprs/perlinexpr"), exports);
-__exportStar(require("./exprs/simplexexpr"), exports);
-__exportStar(require("./exprs/motionblurloop"), exports);
-__exportStar(require("./exprs/randomexpr"), exports);
-__exportStar(require("./exprs/sobelexpr"), exports);
-__exportStar(require("./exprs/bloomloop"), exports);
-__exportStar(require("./exprs/monochromeexpr"), exports);
-__exportStar(require("./exprs/invertexpr"), exports);
-__exportStar(require("./exprs/edgeexpr"), exports);
-__exportStar(require("./exprs/edgecolorexpr"), exports);
-__exportStar(require("./exprs/ternaryexpr"), exports);
-__exportStar(require("./exprs/regiondecorator"), exports);
-__exportStar(require("./exprs/expr"), exports);
-
-},{"./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){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.sendTexture = exports.makeTexture = exports.Merger = exports.loop = exports.EffectLoop = exports.EffectDictionary = void 0;
-const codebuilder_1 = require("./codebuilder");
-const expr_1 = require("./exprs/expr");
-const fragcolorexpr_1 = require("./exprs/fragcolorexpr");
-const regiondecorator_1 = require("./exprs/regiondecorator");
-const scenesampleexpr_1 = require("./exprs/scenesampleexpr");
-const setcolorexpr_1 = require("./exprs/setcolorexpr");
-const ternaryexpr_1 = require("./exprs/ternaryexpr");
-const settings_1 = require("./settings");
-const webglprogramloop_1 = require("./webglprogramloop");
-function wrapInSetColors(effects) {
- return effects.map((e) => e instanceof expr_1.ExprVec4 || e instanceof EffectLoop ? e : new setcolorexpr_1.SetColorExpr(e));
-}
-// should be function of loop?
-function processEffectMap(eMap) {
- const result = {};
- for (const name in eMap) {
- const val = eMap[name];
- result[name] = wrapInSetColors(val);
- }
- return result;
-}
-class EffectDictionary {
- constructor(effectMap) {
- this.effectMap = processEffectMap(effectMap);
- }
- toProgramMap(gl, vShader, uniformLocs, fShaders) {
- const programMap = {};
- let needs = {
- neighborSample: false,
- centerSample: false,
- sceneBuffer: false,
- timeUniform: false,
- mouseUniform: false,
- passCount: false,
- extraBuffers: new Set(),
- };
- for (const name in this.effectMap) {
- const effects = this.effectMap[name];
- // wrap the given list of effects as a loop if need be
- const effectLoop = new EffectLoop(effects, { num: 1 });
- if (effectLoop.effects.length === 0) {
- throw new Error("list of effects was empty");
- }
- const programLoop = effectLoop.genPrograms(gl, vShader, uniformLocs, fShaders);
- // walk the tree to the final program
- let atBottom = false;
- let currProgramLoop = programLoop;
- while (!atBottom) {
- if (currProgramLoop.programElement instanceof webglprogramloop_1.WebGLProgramLeaf) {
- // we traveled right and hit a program, so it must be the last
- currProgramLoop.last = true;
- atBottom = true;
- }
- else {
- // set the current program loop to the last in the list
- currProgramLoop =
- currProgramLoop.programElement[currProgramLoop.programElement.length - 1];
- }
- }
- needs = webglprogramloop_1.updateNeeds(needs, programLoop.getTotalNeeds());
- programMap[name] = programLoop;
- }
- return { programMap, needs };
- }
-}
-exports.EffectDictionary = EffectDictionary;
-/** effect loop, which can loop over other effects or effect loops */
-class EffectLoop {
- constructor(effects, loopInfo) {
- this.effects = wrapInSetColors(effects);
- this.loopInfo = loopInfo;
- }
- /** @ignore */
- getSampleNum(mult = 1, sliceStart = 0, sliceEnd = this.effects.length) {
- mult *= this.loopInfo.num;
- let acc = 0;
- const sliced = this.effects.slice(sliceStart, sliceEnd);
- for (const e of sliced) {
- acc += e.getSampleNum(mult);
- }
- return acc;
- }
- /**
- * @ignore
- * places effects into loops broken up by sampling effects
- */
- regroup() {
- let sampleCount = 0;
- /** number of samples in all previous */
- let prevSampleCount = 0;
- let prevEffects = [];
- const regroupedEffects = [];
- let prevTarget;
- let currTarget;
- let mustBreakCounter = 0;
- const breakOff = () => {
- mustBreakCounter--;
- if (prevEffects.length > 0) {
- // break off all previous effects into their own loop
- if (prevEffects.length === 1) {
- // this is to prevent wrapping in another effect loop
- regroupedEffects.push(prevEffects[0]);
- }
- else {
- regroupedEffects.push(new EffectLoop(prevEffects, { num: 1 }));
- }
- sampleCount -= prevSampleCount;
- prevEffects = [];
- }
- };
- for (const e of this.effects) {
- const sampleNum = e.getSampleNum();
- prevSampleCount = sampleCount;
- sampleCount += sampleNum;
- if (e instanceof EffectLoop) {
- currTarget = e.loopInfo.target;
- if (e.hasTargetSwitch()) {
- mustBreakCounter = 2;
- }
- }
- else {
- // if it's not a loop it's assumed the target is that of outer loop
- currTarget = this.loopInfo.target;
- }
- if (sampleCount > 0 ||
- currTarget !== prevTarget ||
- mustBreakCounter > 0) {
- breakOff();
- }
- prevEffects.push(e);
- prevTarget = currTarget;
- }
- // push on all the straggling effects after the grouping is done
- breakOff();
- return regroupedEffects;
- }
- genPrograms(gl, vShader, uniformLocs, shaders) {
- // validate
- const fullSampleNum = this.getSampleNum() / this.loopInfo.num;
- const firstSampleNum = this.getSampleNum(undefined, 0, 1) / this.loopInfo.num;
- const restSampleNum = this.getSampleNum(undefined, 1) / this.loopInfo.num;
- if (!this.hasTargetSwitch() &&
- (fullSampleNum === 0 || (firstSampleNum === 1 && restSampleNum === 0))) {
- const codeBuilder = new codebuilder_1.CodeBuilder(this);
- const program = codeBuilder.compileProgram(gl, vShader, uniformLocs, shaders);
- return program;
- }
- // otherwise, regroup and try again on regrouped loops
- this.effects = this.regroup();
- return new webglprogramloop_1.WebGLProgramLoop(this.effects.map((e) => e.genPrograms(gl, vShader, uniformLocs, shaders)), this.loopInfo, gl);
- }
- /**
- * changes the render target of an effect loop (-1 targest the scene texture;
- * this is used internally)
- */
- target(num) {
- this.loopInfo.target = num;
- return this;
- }
- /** @ignore */
- hasTargetSwitch() {
- for (const e of this.effects) {
- if (e instanceof EffectLoop) {
- if (e.loopInfo.target !== this.loopInfo.target || e.hasTargetSwitch())
- return true;
- }
- }
- return false;
- }
- /** @ignore */
- regionWrap(space, failure, finalPath = true, not) {
- this.effects = this.effects.map((e, index) =>
- // loops that aren't all the way to the right can't terminate the count ternery
- // don't wrap fcolors in a ternery (it's redundant)
- e instanceof EffectLoop
- ? e.regionWrap(space, failure, index === this.effects.length - 1, not)
- : new setcolorexpr_1.SetColorExpr(regiondecorator_1.region(space, e.brandExprWithRegion(space), index === this.effects.length - 1 && finalPath
- ? !(failure instanceof fragcolorexpr_1.FragColorExpr)
- ? ternaryexpr_1.ternary(null, failure, fragcolorexpr_1.fcolor())
- : failure
- : fragcolorexpr_1.fcolor(), not)));
- return this;
- }
-}
-exports.EffectLoop = EffectLoop;
-/** creates an effect loop */
-function loop(effects, rep = 1) {
- return new EffectLoop(effects, { num: rep });
-}
-exports.loop = loop;
-/** @ignore */
-const V_SOURCE = `attribute vec2 aPosition;
-void main() {
- gl_Position = vec4(aPosition, 0.0, 1.0);
-}\n`;
-/** class that can merge effects */
-class Merger {
- /**
- * constructs the object that runs the effects
- * @param effects list of effects that define the final effect
- * @param source the source image or texture
- * @param gl the target rendering context
- * @param options additional options for the texture
- */
- constructor(effects, source, gl, options) {
- this.uniformLocs = {};
- /** additional channels */
- this.channels = [];
- this.fShaders = [];
- this.textureMode = source instanceof WebGLTexture;
- // set channels if provided with channels
- if ((options === null || options === void 0 ? void 0 : options.channels) !== undefined)
- this.channels = options === null || options === void 0 ? void 0 : options.channels;
- if (!(effects instanceof EffectDictionary)) {
- effects = new EffectDictionary({ default: effects });
- }
- // add the copy to scene texture if in texture mode
- if (this.textureMode) {
- if (settings_1.settings.verbosity > 1) {
- console.log("we are in texture mode!");
- }
- for (const name in effects.effectMap) {
- const list = effects.effectMap[name];
- list.unshift(loop([scenesampleexpr_1.input()]).target(-1));
- }
- }
- this.source = source;
- this.gl = gl;
- this.options = options;
- // set the viewport
- this.gl.viewport(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight);
- // set up the vertex buffer
- const vertexBuffer = this.gl.createBuffer();
- if (vertexBuffer === null) {
- throw new Error("problem creating vertex buffer");
- }
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
- const vertexArray = [-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1];
- const triangles = new Float32Array(vertexArray);
- this.gl.bufferData(this.gl.ARRAY_BUFFER, triangles, this.gl.STATIC_DRAW);
- // save the vertex buffer reference just so we can delete it later
- this.vertexBuffer = vertexBuffer;
- // compile the simple vertex shader (2 big triangles)
- const vShader = this.gl.createShader(this.gl.VERTEX_SHADER);
- if (vShader === null) {
- throw new Error("problem creating the vertex shader");
- }
- // save the vertex shader reference just so we can delete it later
- this.vShader = vShader;
- this.gl.shaderSource(vShader, V_SOURCE);
- this.gl.compileShader(vShader);
- // make textures
- this.tex = {
- // make the front texture the source if we're given a texture instead of
- // an image
- back: {
- name: "orig_back",
- tex: source instanceof WebGLTexture
- ? source
- : makeTexture(this.gl, this.options),
- },
- front: { name: "orig_front", tex: makeTexture(this.gl, this.options) },
- scene: undefined,
- bufTextures: [],
- };
- // create the framebuffer
- const framebuffer = gl.createFramebuffer();
- if (framebuffer === null) {
- throw new Error("problem creating the framebuffer");
- }
- this.framebuffer = framebuffer;
- const { programMap, needs } = effects.toProgramMap(this.gl, this.vShader, this.uniformLocs, this.fShaders);
- this.programMap = programMap;
- if (needs.sceneBuffer || this.textureMode) {
- // we always create a scene texture if we're in texture mode
- this.tex.scene = {
- name: "scene",
- tex: makeTexture(this.gl, this.options),
- };
- }
- if (programMap["default"] === undefined) {
- throw new Error("no default program");
- }
- this.programLoop = programMap["default"];
- // create x amount of empty textures based on buffers needed
- const channelsNeeded = Math.max(...needs.extraBuffers) + 1;
- const channelsSupplied = this.channels.length;
- if (channelsNeeded > channelsSupplied) {
- throw new Error("not enough channels supplied for this effect");
- }
- for (let i = 0; i < this.channels.length; i++) {
- const texOrImage = this.channels[i];
- if (!(texOrImage instanceof WebGLTexture)) {
- // create a new texture; we will update this with the image source every draw
- const texture = makeTexture(this.gl, this.options);
- this.tex.bufTextures.push({ name: "tex_channel_" + i, tex: texture });
- }
- else {
- // this is already a texture; the user will handle updating this
- this.tex.bufTextures.push({
- name: "img_channel_" + i,
- tex: texOrImage,
- });
- }
- }
- if (settings_1.settings.verbosity > 0) {
- console.log(effects);
- console.log(this.programMap);
- }
- }
- /**
- * use the source and channels to draw effect to target context; mouse
- * position (as with all positions) are stored from the bottom left corner as
- * this is how texture data is stored
- * @param timeVal number to set the time uniform to (supply this if you plan to
- * use [[time]])
- * @param mouseX the x position of the mouse (supply this if you plan to use
- * [[mouse]] or [[nmouse]])
- * @param mouseY the y position of the mouse (supply this if you plan to use
- * [[mouse]] or [[nmouse]])
- */
- draw(timeVal = 0, mouseX = 0, mouseY = 0) {
- this.gl.activeTexture(this.gl.TEXTURE0 + settings_1.settings.offset);
- this.gl.bindTexture(this.gl.TEXTURE_2D, this.tex.back.tex);
- sendTexture(this.gl, this.source);
- // TODO only do unbinding and rebinding in texture mode
- // TODO see if we need to unbind
- this.gl.bindTexture(this.gl.TEXTURE_2D, null);
- // bind the scene buffer
- if (this.programLoop.getTotalNeeds().sceneBuffer &&
- this.tex.scene !== undefined) {
- this.gl.activeTexture(this.gl.TEXTURE1 + settings_1.settings.offset);
- this.gl.bindTexture(this.gl.TEXTURE_2D, this.tex.scene.tex);
- sendTexture(this.gl, this.source);
- // TODO see if we need to unbind
- this.gl.bindTexture(this.gl.TEXTURE_2D, null);
- }
- // bind the additional buffers
- let counter = 0;
- for (const b of this.channels) {
- // TODO check for texture limit
- this.gl.activeTexture(this.gl.TEXTURE2 + counter + settings_1.settings.offset);
- this.gl.bindTexture(this.gl.TEXTURE_2D, this.tex.bufTextures[counter].tex);
- sendTexture(this.gl, b);
- // TODO see if we need to unbind (this gets rid of the error)
- this.gl.bindTexture(this.gl.TEXTURE_2D, null);
- counter++;
- }
- this.programLoop.run(this.gl, this.tex, this.framebuffer, this.uniformLocs, this.programLoop.last, { timeVal: timeVal, mouseX: mouseX, mouseY: mouseY });
- }
- /**
- * delete all resources created by construction of this [[Merger]]; use right before
- * intentionally losing a reference to this merger object. this is useful if you want
- * to construct another [[Merger]] to use new effects
- */
- delete() {
- // TODO do we have to do something with VertexAttribArray?
- // call bind with null on all textures
- for (let i = 0; i < 2 + this.tex.bufTextures.length; i++) {
- // this gets rid of final texture, scene texture and channels
- this.gl.activeTexture(this.gl.TEXTURE0 + i + settings_1.settings.offset);
- this.gl.bindTexture(this.gl.TEXTURE_2D, null);
- }
- // call bind with null on all vertex buffers (just 1)
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
- // call bind with null on all frame buffers (just 1)
- // (this might be redundant because this happens at end of draw call)
- this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
- // delete all programs
- this.programLoop.delete(this.gl);
- // delete all textures
- this.gl.deleteTexture(this.tex.front.tex);
- this.gl.deleteTexture(this.tex.back.tex);
- for (const c of this.tex.bufTextures) {
- this.gl.deleteTexture(c.tex);
- }
- // delete all vertex buffers (just 1)
- this.gl.deleteBuffer(this.vertexBuffer);
- // delete all frame buffers (just 1)
- this.gl.deleteFramebuffer(this.framebuffer);
- // delete all vertex shaders (just 1)
- this.gl.deleteShader(this.vShader);
- // delete all fragment shaders
- for (const f of this.fShaders) {
- this.gl.deleteShader(f);
- }
- }
- /**
- * changes the current program loop
- * @param str key in the program map
- */
- changeProgram(str) {
- if (this.programMap[str] === undefined) {
- throw new Error(`program "${str}" doesn't exist on this merger`);
- }
- this.programLoop = this.programMap[str];
- }
-}
-exports.Merger = Merger;
-/** creates a texture given a context and options */
-function makeTexture(gl, options) {
- const texture = gl.createTexture();
- if (texture === null) {
- throw new Error("problem creating texture");
- }
- // flip the order of the pixels, or else it displays upside down
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
- // bind the texture after creating it
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- const filterMode = (f) => f === undefined || f === "linear" ? gl.LINEAR : gl.NEAREST;
- // how to map texture element
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode(options === null || options === void 0 ? void 0 : options.minFilterMode));
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode(options === null || options === void 0 ? void 0 : options.maxFilterMode));
- if ((options === null || options === void 0 ? void 0 : options.edgeMode) !== "wrap") {
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- }
- return texture;
-}
-exports.makeTexture = makeTexture;
-/** copies onto texture */
-function sendTexture(gl, src) {
- // if you are using textures instead of images, the user is responsible for
- // updating that texture, so just return
- if (src instanceof WebGLTexture || src === null)
- return;
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);
-}
-exports.sendTexture = sendTexture;
-
-},{"./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){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.settings = void 0;
-exports.settings = {
- /**
- * set to 1 if you want reasonable logging for debugging, such as the
- * generated GLSL code and program tree. set to 100 if you want texture debug
- * info (you probably don't want to do this, as it logs many lines every
- * frame!)
- */
- verbosity: 0,
- /** texture offset */
- offset: 0,
-};
-
-},{}],65:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.brandWithRegion = exports.brandWithChannel = exports.captureAndAppend = void 0;
-const glslfunctions_1 = require("./glslfunctions");
-/** @ignore */
-function captureAndAppend(str, reg, suffix) {
- const matches = str.match(reg);
- if (matches === null)
- throw new Error("no match in the given string");
- return str.replace(reg, matches[0] + suffix);
-}
-exports.captureAndAppend = captureAndAppend;
-/** @ignore */
-function nameExtractor(sourceLists, extra) {
- const origFuncName = sourceLists.sections[0];
- const ending = origFuncName[origFuncName.length - 1] === ")" ? ")" : "";
- const newFuncName = origFuncName.substr(0, origFuncName.length - 1 - ~~(ending === ")")) +
- extra +
- "(" +
- ending;
- return { origFuncName, newFuncName, ending };
-}
-/** @ignore */
-function brandWithChannel(sourceLists, funcs, needs, funcIndex, samplerNum) {
- samplerNum === undefined || samplerNum === -1
- ? (needs.neighborSample = true)
- : (needs.extraBuffers = new Set([samplerNum]));
- if (samplerNum === undefined || samplerNum === -1)
- return;
- const { origFuncName, newFuncName, ending } = nameExtractor(sourceLists, samplerNum !== undefined ? "_" + samplerNum : "");
- sourceLists.sections[0] = sourceLists.sections[0]
- .split(origFuncName)
- .join(newFuncName);
- funcs[funcIndex] = funcs[funcIndex]
- .split(origFuncName)
- .join(newFuncName)
- .split("uSampler")
- .join("uBufferSampler" + samplerNum);
-}
-exports.brandWithChannel = brandWithChannel;
-/** @ignore */
-function brandWithRegion(expr, funcIndex, space) {
- // if it's not a rectangle region we can't do anything so just return
- if (!Array.isArray(space))
- return;
- const sourceLists = expr.sourceLists;
- const funcs = expr.externalFuncs;
- const needs = expr.needs;
- if (expr.regionBranded ||
- (!needs.neighborSample && needs.extraBuffers.size === 0))
- return;
- const { origFuncName, newFuncName, ending } = nameExtractor(sourceLists, "_region");
- const openFuncName = newFuncName.substr(0, newFuncName.length - ~~(ending === ")"));
- const newFuncDeclaration = openFuncName +
- "float r_x_min, float r_y_min, float r_x_max, float r_y_max" +
- (ending === ")" ? ")" : ", ");
- const origTextureName = "texture2D(";
- const newTextureName = "texture2D_region(r_x_min, r_y_min, r_x_max, r_y_max, ";
- // replace name in the external function and `texture2D` and sampler
- // (assumes the sampling function is the first external function)
- funcs[funcIndex] = funcs[funcIndex]
- .split(origFuncName)
- .join(newFuncDeclaration)
- .split(origTextureName)
- .join(newTextureName);
- // shift the original name off the list
- sourceLists.sections.shift();
- // add the close paren if we're opening up a function with 0 args
- if (ending === ")")
- sourceLists.sections.unshift(")");
- // add commas (one less if it is a 0 arg function call)
- for (let i = 0; i < 4 - ~~(ending === ")"); i++) {
- sourceLists.sections.unshift(", ");
- }
- // add the new name to the beginning of the list
- sourceLists.sections.unshift(newFuncName.substr(0, newFuncName.length - ~~(ending === ")")));
- // add values from region data
- sourceLists.values.unshift(...space);
- // put the texture access wrapper at the beginning
- funcs.unshift(glslfunctions_1.glslFuncs.texture2D_region);
- expr.regionBranded = true;
-}
-exports.brandWithRegion = brandWithRegion;
-
-},{"./glslfunctions":61}],66:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.WebGLProgramLoop = exports.WebGLProgramLeaf = exports.updateNeeds = void 0;
-const settings_1 = require("./settings");
-// update me on change to needs
-function updateNeeds(acc, curr) {
- return {
- neighborSample: acc.neighborSample || curr.neighborSample,
- centerSample: acc.centerSample || curr.centerSample,
- sceneBuffer: acc.sceneBuffer || curr.sceneBuffer,
- timeUniform: acc.timeUniform || curr.timeUniform,
- mouseUniform: acc.mouseUniform || curr.mouseUniform,
- passCount: acc.passCount || curr.passCount,
- extraBuffers: new Set([...acc.extraBuffers, ...curr.extraBuffers]),
- };
-}
-exports.updateNeeds = updateNeeds;
-class WebGLProgramLeaf {
- constructor(program, totalNeeds, effects) {
- this.program = program;
- this.totalNeeds = totalNeeds;
- this.effects = effects;
- }
-}
-exports.WebGLProgramLeaf = WebGLProgramLeaf;
-/** @ignore */
-function getLoc(programElement, gl, name) {
- gl.useProgram(programElement.program);
- const loc = gl.getUniformLocation(programElement.program, name);
- if (loc === null) {
- throw new Error("could not get the " + name + " uniform location");
- }
- return loc;
-}
-/** recursive data structure of compiled programs */
-class WebGLProgramLoop {
- constructor(programElement, loopInfo, gl) {
- //effects: Expr[];
- this.last = false;
- this.counter = 0;
- this.programElement = programElement;
- this.loopInfo = loopInfo;
- if (this.programElement instanceof WebGLProgramLeaf) {
- if (gl === undefined) {
- throw new Error("program element is a program but context is undefined");
- }
- if (this.programElement.totalNeeds.timeUniform) {
- this.timeLoc = getLoc(this.programElement, gl, "uTime");
- }
- if (this.programElement.totalNeeds.mouseUniform) {
- this.mouseLoc = getLoc(this.programElement, gl, "uMouse");
- }
- if (this.programElement.totalNeeds.passCount) {
- this.countLoc = getLoc(this.programElement, gl, "uCount");
- }
- }
- }
- /** get all needs from all programs */
- getTotalNeeds() {
- // go through needs of program loop
- if (!(this.programElement instanceof WebGLProgramLeaf)) {
- const allNeeds = [];
- for (const p of this.programElement) {
- allNeeds.push(p.getTotalNeeds());
- }
- return allNeeds.reduce(updateNeeds);
- }
- return this.programElement.totalNeeds;
- }
- /**
- * recursively uses all programs in the loop, binding the appropriate
- * textures and setting the appropriate uniforms; the user should only have
- * to call [[draw]] on [[Merger]] and never this function directly
- */
- run(gl, tex, framebuffer, uniformLocs, last, defaultUniforms, outerLoop) {
- let savedTexture;
- if (this.loopInfo.target !== undefined &&
- // if there is a target switch:
- (outerLoop === null || outerLoop === void 0 ? void 0 : outerLoop.loopInfo.target) !== this.loopInfo.target) {
- // swap out the back texture for the channel texture if this loop has
- // an alternate render target
- savedTexture = tex.back;
- if (this.loopInfo.target !== -1) {
- tex.back = tex.bufTextures[this.loopInfo.target];
- }
- else {
- if (tex.scene === undefined) {
- throw new Error("tried to target -1 but scene texture was undefined");
- }
- tex.back = tex.scene;
- }
- tex.bufTextures[this.loopInfo.target] = savedTexture;
- if (settings_1.settings.verbosity > 99)
- console.log("saved texture: " + savedTexture.name);
- }
- // setup for program leaf
- if (this.programElement instanceof WebGLProgramLeaf) {
- // bind the scene texture if needed
- if (this.programElement.totalNeeds.sceneBuffer) {
- if (tex.scene === undefined) {
- throw new Error("needs scene buffer, but scene texture is somehow undefined");
- }
- gl.activeTexture(gl.TEXTURE1 + settings_1.settings.offset);
- if (this.loopInfo.target === -1) {
- gl.bindTexture(gl.TEXTURE_2D, savedTexture.tex);
- }
- else {
- gl.bindTexture(gl.TEXTURE_2D, tex.scene.tex);
- }
- }
- // bind all extra channel textures if needed
- for (const n of this.programElement.totalNeeds.extraBuffers) {
- gl.activeTexture(gl.TEXTURE2 + n + settings_1.settings.offset);
- gl.bindTexture(gl.TEXTURE_2D, tex.bufTextures[n].tex);
- }
- // use the current program
- gl.useProgram(this.programElement.program);
- // apply all uniforms
- for (const effect of this.programElement.effects) {
- effect.applyUniforms(gl, uniformLocs);
- }
- // set time uniform if needed
- if (this.programElement.totalNeeds.timeUniform) {
- if (this.timeLoc === undefined ||
- defaultUniforms.timeVal === undefined) {
- throw new Error("time or location is undefined");
- }
- gl.uniform1f(this.timeLoc, defaultUniforms.timeVal);
- }
- // set mouse uniforms if needed
- if (this.programElement.totalNeeds.mouseUniform) {
- if (this.mouseLoc === undefined ||
- defaultUniforms.mouseX === undefined ||
- defaultUniforms.mouseY === undefined) {
- throw new Error("mouse uniform or location is undefined");
- }
- gl.uniform2f(this.mouseLoc, defaultUniforms.mouseX, defaultUniforms.mouseY);
- }
- // set count uniform if needed
- if (this.programElement.totalNeeds.passCount && outerLoop !== undefined) {
- if (this.countLoc === undefined) {
- throw new Error("count location is undefined");
- }
- if (outerLoop !== undefined) {
- gl.uniform1i(this.countLoc, outerLoop.counter);
- }
- this.counter++;
- const mod = outerLoop === undefined ? 1 : outerLoop.loopInfo.num;
- this.counter %= mod;
- }
- }
- for (let i = 0; i < this.loopInfo.num; i++) {
- const newLast = i === this.loopInfo.num - 1;
- if (this.programElement instanceof WebGLProgramLeaf) {
- if (newLast && last && this.last) {
- // we are on the final pass of the final loop, so draw screen by
- // setting to the default framebuffer
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- }
- else {
- // we have to bounce between two textures
- gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
- // use the framebuffer to write to front texture
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex.front.tex, 0);
- }
- // allows us to read from `texBack`
- // default sampler is 0, so `uSampler` uniform will always sample from texture 0
- gl.activeTexture(gl.TEXTURE0 + settings_1.settings.offset);
- gl.bindTexture(gl.TEXTURE_2D, tex.back.tex);
- // use our last program as the draw program
- gl.drawArrays(gl.TRIANGLES, 0, 6);
- if (settings_1.settings.verbosity > 99) {
- console.log("intermediate back", tex.back.name);
- console.log("intermediate front", tex.front.name);
- }
- // swap back and front
- [tex.back, tex.front] = [tex.front, tex.back];
- // deactivate and unbind all the channel textures needed
- for (const n of this.programElement.totalNeeds.extraBuffers) {
- gl.activeTexture(gl.TEXTURE2 + n + settings_1.settings.offset);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- gl.activeTexture(gl.TEXTURE1 + settings_1.settings.offset);
- gl.bindTexture(gl.TEXTURE_2D, null);
- }
- else {
- if (this.loopInfo.func !== undefined) {
- this.loopInfo.func(i);
- }
- for (const p of this.programElement) {
- p.run(gl, tex, framebuffer, uniformLocs, newLast, defaultUniforms, this // this is now the outer loop
- );
- }
- }
- }
- // swap the textures back if we were temporarily using a channel texture
- if (savedTexture !== undefined) {
- const target = this.loopInfo.target;
- if (settings_1.settings.verbosity > 99) {
- console.log("pre final back", tex.back.name);
- console.log("pre final front", tex.front.name);
- }
- // back texture is really the front texture because it was just swapped
- if (this.loopInfo.target !== -1) {
- tex.bufTextures[target] = tex.back;
- }
- else {
- if (tex.scene === undefined) {
- throw new Error("tried to replace -1 but scene texture was undefined");
- }
- tex.scene = tex.back;
- }
- tex.back = savedTexture;
- if (settings_1.settings.verbosity > 99) {
- console.log("post final back", tex.back.name);
- console.log("post final front", tex.front.name);
- console.log("channel texture", tex.bufTextures[target].name);
- }
- }
- }
- delete(gl) {
- if (this.programElement instanceof WebGLProgramLeaf) {
- gl.deleteProgram(this.programElement.program);
- }
- else {
- for (const p of this.programElement) {
- p.delete(gl);
- }
- }
- }
-}
-exports.WebGLProgramLoop = WebGLProgramLoop;
-
-},{"./settings":64}]},{},[9]);
-// @ts-nocheck
-{
- const addToProto = (pr, name, add) => {
- if (p5.prototype.hasOwnProperty(name)) {
- throw new Error("p5 already has this: " + name);
- }
- pr[name] = add;
- };
-
- const pr = p5.prototype;
- // this avoids collisions with names in p5 and changes to camelCase
- addToProto(pr, "foggyRays", MP.foggyrays);
- addToProto(pr, "vignette", MP.vignette);
- addToProto(pr, "blurAndTrace", MP.blurandtrace);
- addToProto(pr, "lightBands", MP.lightbands);
- addToProto(pr, "noiseDisplacement", MP.noisedisplacement);
- addToProto(pr, "oldFilm", MP.oldfilm);
- addToProto(pr, "kaleidoscope", MP.kaleidoscope);
- addToProto(pr, "effectLoop", MP.loop);
- addToProto(pr, "gauss", MP.gauss);
- addToProto(pr, "fColor", MP.fcolor);
- addToProto(pr, "vec2", MP.vec2);
- addToProto(pr, "vec3", MP.vec3);
- addToProto(pr, "vec4", MP.vec4);
- addToProto(pr, "pVec2", MP.pvec2);
- addToProto(pr, "pVec3", MP.pvec3);
- addToProto(pr, "pVec4", MP.pvec4);
- addToProto(pr, "op", MP.op);
- addToProto(pr, "blur2d", MP.blur2d);
- addToProto(pr, "len", MP.len);
- addToProto(pr, "normalize", MP.norm);
- addToProto(pr, "pixel", MP.pixel);
- addToProto(pr, "pos", MP.pos);
- addToProto(pr, "center", MP.center);
- addToProto(pr, "input", MP.input);
- addToProto(pr, "bright", MP.brightness);
- addToProto(pr, "contrast", MP.contrast);
- addToProto(pr, "grain", MP.grain);
- addToProto(pr, "getComp", MP.getcomp);
- addToProto(pr, "get2Comp", MP.get2comp);
- addToProto(pr, "get3Comp", MP.get3comp);
- addToProto(pr, "get4Comp", MP.get4comp);
- addToProto(pr, "changeComp", MP.changecomp);
- addToProto(pr, "rgbToHsv", MP.rgb2hsv);
- addToProto(pr, "hsvToRgb", MP.hsv2rgb);
- addToProto(pr, "time", MP.time);
- addToProto(pr, "a1", MP.a1);
- addToProto(pr, "a2", MP.a2);
- addToProto(pr, "fxaa", MP.fxaa);
- addToProto(pr, "channel", MP.channel);
- addToProto(pr, "depthOfField", MP.dof);
- addToProto(pr, "trueDepth", MP.truedepth);
- addToProto(pr, "godrays", MP.godrays);
- addToProto(pr, "depthToOcclusion", MP.depth2occlusion);
- addToProto(pr, "resolution", MP.resolution);
- addToProto(pr, "mouse", MP.mouse);
- addToProto(pr, "rotate2d", MP.rotate);
- addToProto(pr, "translate2d", MP.translate);
- addToProto(pr, "nMouse", MP.nmouse);
- addToProto(pr, "perlin", MP.perlin);
- addToProto(pr, "simplex", MP.simplex);
- addToProto(pr, "motionBlur", MP.motionblur);
- addToProto(pr, "randomFloat", MP.random);
- addToProto(pr, "sobel", MP.sobel);
- addToProto(pr, "bloom", MP.bloom);
- addToProto(pr, "monochrome", MP.monochrome);
- addToProto(pr, "invert", MP.invert);
- addToProto(pr, "edge", MP.edge);
- addToProto(pr, "edgeColor", MP.edgecolor);
- addToProto(pr, "ternary", MP.ternary);
- addToProto(pr, "region", MP.region);
- addToProto(pr, "cFloat", MP.cfloat);
- addToProto(pr, "cVec2", MP.cvec2);
- addToProto(pr, "cVec3", MP.cvec3);
- addToProto(pr, "cVec4", MP.cvec4);
- addToProto(pr, "mut", MP.mut);
- addToProto(pr, "basicFloat", MP.float);
- addToProto(pr, "pFloat", MP.pfloat);
- addToProto(pr, "tag", MP.tag);
-
- addToProto(pr, "__info", {
- replaced: false,
- orig: null,
- canvas: null,
- gl: null,
- verbosity: 0,
- startTime: 0,
- mousePos: { x: 0, y: 0 },
- effects: [],
- channels: [],
- });
-
- console.log(pr.__info);
-
- addToProto(pr, "addEffects", function () {
- pr.__info.effects.push(...arguments);
- });
-
- addToProto(pr, "addChannels", function () {
- pr.__info.channels.push(...arguments);
- });
-
- const info = p5.prototype.__info;
-
- function mpInit() {
- if (info.verbosity > 0) console.log("mp init");
- }
-
- function mpPre() {
- if (info.replaced || !info.effects) return;
- if (info.verbosity > 0) console.log("mp pre x1");
-
- info.startTime = new Date().getTime();
-
- info.orig = document.getElementById("defaultCanvas0");
-
- if (!info.orig) throw new Error("mergepass couldn't get the p5 canvas");
- const parent = info.orig.parentElement;
- parent.style.position = "relative";
-
- info.canvas = document.createElement("canvas");
-
- info.canvas.width = info.orig.width;
- info.canvas.height = info.orig.height;
- info.canvas.style.width = info.orig.style.width;
- info.canvas.style.height = info.orig.style.height;
-
- info.gl = info.canvas.getContext("webgl2");
- if (!info.gl) throw new Error("mergepass couldn't get the webgl2 context");
-
- parent.appendChild(info.canvas);
-
- info.merger = new MP.Merger(pr.__info.effects, info.orig, info.gl, {
- channels: pr.__info.channels,
- });
-
- const align = (c, z) => {
- c.style.position = "absolute";
- c.style.left = 0;
- c.style.top = 0;
- c.style.zIndex = z;
- };
-
- align(info.canvas, 0);
- align(info.orig, 1);
-
- info.orig.style.visibility = "hidden";
-
- info.canvas.addEventListener("mousemove", (e) => {
- const rect = info.orig.getBoundingClientRect();
- info.mousePos.x =
- (info.canvas.width * (e.clientX - rect.left)) / rect.width;
- info.mousePos.y =
- (info.canvas.height * (rect.height - (e.clientY - rect.top))) /
- rect.height;
- });
-
- info.replaced = true;
- }
-
- function mpPost() {
- if (info.verbosity > 1) console.log("mp post");
- if (!info.effects) return;
- const time = info.startTime - new Date().getTime();
- info.merger.draw(time / 1000, info.mousePos.x, info.mousePos.y);
- }
-
- p5.prototype.registerMethod("pre", mpPre);
- p5.prototype.registerMethod("init", mpInit);
- p5.prototype.registerMethod("post", mpPost);
-}