mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-18 14:19:30 -07:00
Rebuilt on top of REGL.
This commit is contained in:
140
js/bloomPass.js
Normal file
140
js/bloomPass.js
Normal file
@@ -0,0 +1,140 @@
|
||||
import { makePassFBO, makePyramid, resizePyramid } from "./utils.js";
|
||||
|
||||
const pyramidHeight = 5;
|
||||
const levelStrengths = Array(pyramidHeight)
|
||||
.fill()
|
||||
.map((_, index) =>
|
||||
Math.pow(index / (pyramidHeight * 2) + 0.5, 1 / 3).toPrecision(5)
|
||||
)
|
||||
.reverse();
|
||||
|
||||
export default (regl, config, input) => {
|
||||
if (config.effect === "none") {
|
||||
return {
|
||||
fbo: input,
|
||||
resize: () => {},
|
||||
render: () => {}
|
||||
};
|
||||
}
|
||||
|
||||
const highPassPyramid = makePyramid(regl, pyramidHeight);
|
||||
const horizontalBlurPyramid = makePyramid(regl, pyramidHeight);
|
||||
const verticalBlurPyramid = makePyramid(regl, pyramidHeight);
|
||||
const fbo = makePassFBO(regl);
|
||||
|
||||
const highPass = regl({
|
||||
frag: `
|
||||
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.;
|
||||
}
|
||||
gl_FragColor = vec4(vec3(value), 1.0);
|
||||
}
|
||||
`,
|
||||
uniforms: {
|
||||
tex: regl.prop("tex")
|
||||
},
|
||||
framebuffer: regl.prop("fbo")
|
||||
});
|
||||
|
||||
const blur = regl({
|
||||
frag: `
|
||||
precision mediump float;
|
||||
varying vec2 vUV;
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 direction;
|
||||
uniform float width, height;
|
||||
void main() {
|
||||
vec2 size = width > height ? vec2(width / height, 1.) : vec2(1., height / width);
|
||||
gl_FragColor =
|
||||
texture2D(tex, vUV) * 0.442 +
|
||||
(
|
||||
texture2D(tex, vUV + direction / max(width, height) * size) +
|
||||
texture2D(tex, vUV - direction / max(width, height) * size)
|
||||
) * 0.279;
|
||||
}
|
||||
`,
|
||||
uniforms: {
|
||||
tex: regl.prop("tex"),
|
||||
direction: regl.prop("direction"),
|
||||
height: regl.context("viewportWidth"),
|
||||
width: regl.context("viewportHeight")
|
||||
},
|
||||
framebuffer: regl.prop("fbo")
|
||||
});
|
||||
|
||||
const combineBloom = regl({
|
||||
frag: `
|
||||
precision mediump float;
|
||||
varying vec2 vUV;
|
||||
${verticalBlurPyramid
|
||||
.map((_, index) => `uniform sampler2D tex_${index};`)
|
||||
.join("\n")}
|
||||
uniform sampler2D tex;
|
||||
uniform float bloomStrength;
|
||||
void main() {
|
||||
vec4 total = vec4(0.);
|
||||
${verticalBlurPyramid
|
||||
.map(
|
||||
(_, index) =>
|
||||
`total += texture2D(tex_${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])
|
||||
)
|
||||
),
|
||||
framebuffer: fbo
|
||||
});
|
||||
|
||||
return {
|
||||
fbo,
|
||||
resize: (viewportWidth, viewportHeight) => {
|
||||
resizePyramid(
|
||||
highPassPyramid,
|
||||
viewportWidth,
|
||||
viewportHeight,
|
||||
config.bloomSize
|
||||
);
|
||||
resizePyramid(
|
||||
horizontalBlurPyramid,
|
||||
viewportWidth,
|
||||
viewportHeight,
|
||||
config.bloomSize
|
||||
);
|
||||
resizePyramid(
|
||||
verticalBlurPyramid,
|
||||
viewportWidth,
|
||||
viewportHeight,
|
||||
config.bloomSize
|
||||
);
|
||||
fbo.resize(viewportWidth, viewportHeight);
|
||||
},
|
||||
render: () => {
|
||||
highPassPyramid.forEach(fbo => highPass({ fbo, tex: input }));
|
||||
horizontalBlurPyramid.forEach((fbo, index) =>
|
||||
blur({ fbo, tex: highPassPyramid[index], direction: [1, 0] })
|
||||
);
|
||||
verticalBlurPyramid.forEach((fbo, index) =>
|
||||
blur({
|
||||
fbo,
|
||||
tex: horizontalBlurPyramid[index],
|
||||
direction: [0, 1]
|
||||
})
|
||||
);
|
||||
combineBloom();
|
||||
}
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user