More cleanup

This commit is contained in:
Rezmason
2020-01-22 13:02:08 -08:00
parent cadd769b63
commit 05933a5dda
6 changed files with 113 additions and 130 deletions

View File

@@ -1,4 +1,4 @@
import { makePassFBO, makePyramid, resizePyramid } from "./utils.js";
import { makePassFBO, makePyramid, resizePyramid, makePass } from "./utils.js";
// The bloom pass is basically an added high-pass blur.
@@ -11,32 +11,30 @@ const levelStrengths = Array(pyramidHeight)
.reverse();
export default (regl, config, input) => {
if (config.effect === "none") {
return {
output: input,
resize: () => {},
render: () => {}
};
if (!config.performBloom) {
return makePass(input, null, null);
}
const highPassPyramid = makePyramid(regl, pyramidHeight);
const horizontalBlurPyramid = makePyramid(regl, pyramidHeight);
const verticalBlurPyramid = makePyramid(regl, pyramidHeight);
const hBlurPyramid = makePyramid(regl, pyramidHeight);
const vBlurPyramid = makePyramid(regl, pyramidHeight);
const output = makePassFBO(regl);
// The high pass restricts the blur to bright things in our input texture.
const highPass = regl({
frag: `
#define lumaMag vec3(0.2126, 0.7152, 0.0722)
precision mediump float;
varying vec2 vUV;
uniform sampler2D tex;
uniform float highPassThreshold;
void main() {
float value = texture2D(tex, vUV).r;
if (value < highPassThreshold) {
value = 0.;
vec3 lumaColor = texture2D(tex, vUV).rgb * lumaMag;
float luma = lumaColor.r + lumaColor.g + lumaColor.b;
if (luma < highPassThreshold) {
luma = 0.;
}
gl_FragColor = vec4(vec3(value), 1.0);
gl_FragColor = vec4(vec3(luma), 1.0);
}
`,
uniforms: {
@@ -79,70 +77,51 @@ export default (regl, config, input) => {
frag: `
precision mediump float;
varying vec2 vUV;
${verticalBlurPyramid
.map((_, index) => `uniform sampler2D tex_${index};`)
${vBlurPyramid
.map((_, index) => `uniform sampler2D pyr_${index};`)
.join("\n")}
uniform sampler2D tex;
uniform float bloomStrength;
void main() {
vec4 total = vec4(0.);
${verticalBlurPyramid
${vBlurPyramid
.map(
(_, index) =>
`total += texture2D(tex_${index}, vUV) * ${levelStrengths[index]};`
`total += texture2D(pyr_${index}, vUV) * ${levelStrengths[index]};`
)
.join("\n")}
gl_FragColor = total * bloomStrength + texture2D(tex, vUV);
}
`,
uniforms: Object.assign(
{
tex: input
},
Object.fromEntries(
verticalBlurPyramid.map((fbo, index) => [`tex_${index}`, fbo])
uniforms: {
tex: input,
...Object.fromEntries(
vBlurPyramid.map((fbo, index) => [`pyr_${index}`, fbo])
)
),
},
framebuffer: output
});
return {
const scale = config.bloomSize;
return makePass(
output,
resize: (viewportWidth, viewportHeight) => {
// The blur pyramids can be lower resolution than the screen.
resizePyramid(
highPassPyramid,
viewportWidth,
viewportHeight,
config.bloomSize
);
resizePyramid(
horizontalBlurPyramid,
viewportWidth,
viewportHeight,
config.bloomSize
);
resizePyramid(
verticalBlurPyramid,
viewportWidth,
viewportHeight,
config.bloomSize
);
output.resize(viewportWidth, viewportHeight);
},
render: () => {
() => {
highPassPyramid.forEach(fbo => highPass({ fbo, tex: input }));
horizontalBlurPyramid.forEach((fbo, index) =>
hBlurPyramid.forEach((fbo, index) =>
blur({ fbo, tex: highPassPyramid[index], direction: [1, 0] })
);
verticalBlurPyramid.forEach((fbo, index) =>
blur({
fbo,
tex: horizontalBlurPyramid[index],
direction: [0, 1]
})
vBlurPyramid.forEach((fbo, index) =>
blur({ fbo, tex: hBlurPyramid[index], direction: [0, 1] })
);
combineBloom();
},
(w, h) => {
// The blur pyramids can be lower resolution than the screen.
resizePyramid(highPassPyramid, w, h, scale);
resizePyramid(hBlurPyramid, w, h, scale);
resizePyramid(vBlurPyramid, w, h, scale);
output.resize(w, h);
}
};
);
};

View File

@@ -1,19 +1,18 @@
import { makePassFBO } from "./utils.js";
import { makePassFBO, makePass } from "./utils.js";
// rendered texture's values are mapped to colors in a palette texture.
// A little noise is introduced, to hide the banding that appears
// in subtle gradients. The noise is also time-driven, so its grain
// won't persist across subsequent frames. This is a safe trick
// in screen space.
const colorizeByPalette = regl =>
const colorizeByPalette = (regl, uniforms, framebuffer) =>
// The rendered texture's values are mapped to colors in a palette texture.
// A little noise is introduced, to hide the banding that appears
// in subtle gradients. The noise is also time-driven, so its grain
// won't persist across subsequent frames. This is a safe trick
// in screen space.
regl({
frag: `
precision mediump float;
#define PI 3.14159265359
uniform sampler2D tex;
uniform sampler2D paletteColorData;
uniform sampler2D palette;
uniform float ditherMagnitude;
uniform float time;
varying vec2 vUV;
@@ -25,23 +24,26 @@ const colorizeByPalette = regl =>
}
void main() {
gl_FragColor = texture2D( paletteColorData, vec2( texture2D( tex, vUV ).r - rand( gl_FragCoord.xy, time ) * ditherMagnitude, 0.0 ) );
float at = texture2D( tex, vUV ).r - rand( gl_FragCoord.xy, time ) * ditherMagnitude;
gl_FragColor = texture2D( palette, vec2(at, 0.0));
}
`,
uniforms: {
...uniforms,
ditherMagnitude: 0.05
}
},
framebuffer
});
const colorizeByStripes = regl =>
const colorizeByStripes = (regl, uniforms, framebuffer) =>
regl({
frag: `
precision mediump float;
#define PI 3.14159265359
uniform sampler2D tex;
uniform sampler2D stripeColorData;
uniform sampler2D stripes;
uniform float ditherMagnitude;
varying vec2 vUV;
@@ -52,18 +54,20 @@ const colorizeByStripes = regl =>
}
void main() {
float value = texture2D(tex, vUV).r;
vec3 value2 = texture2D(stripeColorData, vUV).rgb - rand( gl_FragCoord.xy ) * ditherMagnitude;
gl_FragColor = vec4(value2 * value, 1.0);
vec3 color = texture2D(stripes, vUV).rgb - rand( gl_FragCoord.xy ) * ditherMagnitude;
float brightness = texture2D(tex, vUV).r;
gl_FragColor = vec4(color * brightness, 1.0);
}
`,
uniforms: {
...uniforms,
ditherMagnitude: 0.1
}
},
framebuffer
});
const colorizeByImage = (regl, bgTex) =>
const colorizeByImage = (regl, uniforms, framebuffer) =>
regl({
frag: `
precision mediump float;
@@ -72,12 +76,13 @@ const colorizeByImage = (regl, bgTex) =>
varying vec2 vUV;
void main() {
gl_FragColor = vec4(texture2D(bgTex, vUV).rgb * (pow(texture2D(tex, vUV).r, 1.5) * 0.995 + 0.005), 1.0);
vec3 bgColor = texture2D(bgTex, vUV).rgb;
float brightness = pow(texture2D(tex, vUV).r, 1.5);
gl_FragColor = vec4(bgColor * brightness, 1.0);
}
`,
uniforms: {
bgTex
}
uniforms,
framebuffer
});
const colorizersByEffect = {
@@ -89,36 +94,19 @@ const colorizersByEffect = {
export default (regl, config, { bgTex }, input) => {
if (config.effect === "none") {
return {
output: input,
resize: () => {},
render: () => {}
};
return makePass(input, null, null);
}
if (bgTex == null) {
bgTex = 0;
}
const output = makePassFBO(regl);
const colorize = regl({
uniforms: {
tex: regl.prop("tex")
},
framebuffer: output
});
const colorizer = (config.effect in colorizersByEffect
? colorizersByEffect[config.effect]
: colorizeByPalette)(regl, bgTex);
return {
return makePass(
output,
resize: output.resize,
render: resources => {
colorize(
{
tex: input
},
() => colorizer(resources)
);
}
};
(config.effect in colorizersByEffect
? colorizersByEffect[config.effect]
: colorizeByPalette)(regl, { bgTex, tex: input }, output)
);
};

View File

@@ -38,7 +38,7 @@ const versions = {
rippleScale: 30,
rippleSpeed: 0.1,
numColumns: 30,
palette: [
paletteEntries: [
{ rgb: [0.0, 0.0, 0.0], at: 0.0 },
{ rgb: [0.52, 0.17, 0.05], at: 0.4 },
{ rgb: [0.82, 0.37, 0.12], at: 0.7 },
@@ -69,7 +69,7 @@ const versions = {
rippleScale: 30,
rippleSpeed: 0.2,
numColumns: 60,
palette: [
paletteEntries: [
{ rgb: [0.0, 0.0, 0.0], at: 0.0 },
{ rgb: [0.32, 0.06, 0.0], at: 0.2 },
{ rgb: [0.82, 0.06, 0.05], at: 0.4 },
@@ -100,7 +100,7 @@ const versions = {
rippleScale: 30,
rippleSpeed: 0.2,
numColumns: 80,
palette: [
paletteEntries: [
{ rgb: [0 / 255, 0 / 255, 0 / 255], at: 0 / 16 },
{ rgb: [6 / 255, 16 / 255, 8 / 255], at: 1 / 16 },
{ rgb: [11 / 255, 28 / 255, 15 / 255], at: 2 / 16 },
@@ -143,7 +143,7 @@ const versions = {
rippleScale: 30,
rippleSpeed: 0.2,
numColumns: 108,
palette: [
paletteEntries: [
{ rgb: [0.0, 0.0, 0.0], at: 0.0 },
{ rgb: [0.18, 0.9, 0.35], at: 0.6 },
{ rgb: [0.9, 1.0, 0.9], at: 1.0 }
@@ -155,7 +155,7 @@ const versions = {
versions.throwback = versions.operator;
versions["1999"] = versions.classic;
export default (searchString, makePaletteTexture) => {
export default (searchString, make1DTexture) => {
const urlParams = new URLSearchParams(searchString);
const getParam = (keyOrKeys, defaultValue) => {
if (Array.isArray(keyOrKeys)) {
@@ -215,6 +215,11 @@ export default (searchString, makePaletteTexture) => {
.split(",")
.map(parseFloat);
config.showComputationTexture = config.effect === "none";
config.performBloom =
config.effect !== "none" &&
config.bloomSize > 0 &&
config.bloomStrength > 0;
console.log(config.effect, config.bloomSize, config.bloomStrength);
switch (config.cycleStyleName) {
case "cycleFasterWhenDimmed":
@@ -239,7 +244,7 @@ export default (searchString, makePaletteTexture) => {
const PALETTE_SIZE = 2048;
const paletteColors = Array(PALETTE_SIZE);
const sortedEntries = version.palette
const sortedEntries = version.paletteEntries
.slice()
.sort((e1, e2) => e1.at - e2.at)
.map(entry => ({
@@ -269,9 +274,7 @@ export default (searchString, makePaletteTexture) => {
}
});
config.paletteColorData = makePaletteTexture(
paletteColors.flat().map(i => i * 0xff)
);
config.palette = make1DTexture(paletteColors.flat().map(i => i * 0xff));
let stripeColors = [0, 0, 0];
@@ -292,9 +295,7 @@ export default (searchString, makePaletteTexture) => {
stripeColors = config.customStripes.slice(0, numFlagColors * 3);
}
config.stripeColorData = makePaletteTexture(
stripeColors.map(f => Math.floor(f * 0xff))
);
config.stripes = make1DTexture(stripeColors.map(f => Math.floor(f * 0xff)));
const uniforms = Object.fromEntries(
Object.entries(config).filter(([key, value]) => {

View File

@@ -1,4 +1,4 @@
import { makePassFBO, makeDoubleBuffer } from "./utils.js";
import { makePassFBO, makeDoubleBuffer, makePass } from "./utils.js";
export default (regl, config, { msdfTex }) => {
// These two framebuffers are used to compute the raining code.
@@ -292,12 +292,8 @@ export default (regl, config, { msdfTex }) => {
framebuffer: output
});
return {
resize: output.resize,
output,
render: resources => {
update();
render(resources);
}
};
return makePass(output, resources => {
update();
render(resources);
});
};

View File

@@ -99,7 +99,7 @@ const makeFullScreenQuad = (regl, uniforms = {}, context = {}) =>
count: 3
});
const makePalette = (regl, data) =>
const make1DTexture = (regl, data) =>
regl.texture({
data,
width: data.length / 3,
@@ -109,6 +109,24 @@ const makePalette = (regl, data) =>
min: "linear"
});
const makePass = (output, render, resize) => {
if (render == null) {
render = () => {};
}
if (resize === undefined) {
// "default" resize function is on the FBO
resize = (w, h) => output.resize(w, h);
}
if (resize == null) {
resize = () => {};
}
return {
output,
render,
resize
};
};
export {
makePassTexture,
makePassFBO,
@@ -118,5 +136,6 @@ export {
loadImage,
loadImages,
makeFullScreenQuad,
makePalette
make1DTexture,
makePass
};