class EdgeFinderFilter extends PIXI.Filter {
constructor() {
let uniformValues = {
inputDimensions: [1, 1],
};
super(es300VertexShader, EdgeFinderFilter.fragmentShader, uniformValues);
}
get inputDimensions() { return this.uniforms.inputDimensions; }
set inputDimensions(value) { this.uniforms.inputDimensions = value; }
apply() {
return super.apply(...arguments);
}
static {
EdgeFinderFilter.neighborAlphas = {
aN: 16,
aE: 32,
aS: 64,
aW: 128
}
{
let options = [];
let allDirs = ["n", "e", "s", "w"];
let empty = allDirs.reduce((obj, dir) => { obj[dir] = false; return obj }, { value: 0 });
for (let [key, value] of Object.entries(EdgeFinderFilter.neighborAlphas)) {
let f = Object.assign({}, empty);
let dir = key[1].toLowerCase();
let t = Object.assign({}, empty, Object.fromEntries([["value", value], [dir, true]]));
options.push([f, t]);
}
let combos = [];
for (let rawCombo of d3.cross(...options)) {
let combo = Object.assign({}, empty);
for (let v of rawCombo) {
combo.value += v.value;
allDirs.forEach(d => combo[d] ||= v[d]);
}
combos[combo.value] = combo;
delete combo.value;
}
EdgeFinderFilter.neighborAlphasDecoded = combos;
}
let defines = Object.entries(EdgeFinderFilter.neighborAlphas)
.map(([key, value]) => ` float ${key} = ${value / 255};`)
.join("\n");
EdgeFinderFilter.fragmentShader = `#version 300 es
precision highp float;
${defines.trim()}
in vec2 vTextureCoord;
in vec2 vFragCoord;
in vec2 vFilterCoord;
uniform sampler2D uSampler;
uniform vec2 inputDimensions;
uniform vec4 inputSize;
out vec4 fragColor;
vec2 uvToXy(vec2 uv, vec2 dimensions) {
return vec2(uv.x * dimensions.x, uv.y * dimensions.y);
}
vec2 xyToUv(vec2 xy, vec2 dimensions) {
return vec2(xy.x / dimensions.x, xy.y / dimensions.y);
}
void main () {
vec2 xyC = vFragCoord;
vec2 xyN = vFragCoord + vec2( 0.0, -1.0);
vec2 xyE = vFragCoord + vec2( 1.0, 0.0);
vec2 xyS = vFragCoord + vec2( 0.0, 1.0);
vec2 xyW = vFragCoord + vec2(-1.0, 0.0);
bool eN = xyC.y < 1.0;
bool eE = xyC.x > inputDimensions.x - 1.0;
bool eS = xyC.y > inputDimensions.y - 1.0;
bool eW = xyC.x < 1.0;
vec2 uvC = xyToUv(xyC, inputSize.xy);
vec2 uvN = xyToUv(xyN, inputSize.xy);
vec2 uvE = xyToUv(xyE, inputSize.xy);
vec2 uvS = xyToUv(xyS, inputSize.xy);
vec2 uvW = xyToUv(xyW, inputSize.xy);
vec4 cC = texture(uSampler, uvC);
if (cC.a == 0.0) return;
vec4 cN = texture(uSampler, uvN);
vec4 cE = texture(uSampler, uvE);
vec4 cS = texture(uSampler, uvS);
vec4 cW = texture(uSampler, uvW);
vec4 outputColor = vec4(0.0, 0.0, 0.0, 0.0);
float encodedNeighbors = 0.0;
if (eN || cC != cN) {
outputColor.rgb = cC.rgb;
encodedNeighbors += aN;
}
if (eE || cC != cE) {
outputColor.rgb = cC.rgb;
encodedNeighbors += aE;
}
if (eS || cC != cS) {
outputColor.rgb = cC.rgb;
encodedNeighbors += aS;
}
if (eW || cC != cW) {
outputColor.rgb = cC.rgb;
encodedNeighbors += aW;
}
if (encodedNeighbors == 0.0) {
fragColor = vec4(0.0, 0.0, 0.0, 0.0);
}
else {
fragColor = vec4(encodedNeighbors, 0.0, 0.0, 1.0);
}
}`;
}
}