Old and new matrix rendering now coexist.

This commit is contained in:
Rezmason
2021-09-06 16:35:44 -07:00
parent 4add0c3324
commit 99591e1186
2 changed files with 111 additions and 85 deletions

View File

@@ -17,11 +17,12 @@ const fonts = {
}; };
const defaults = { const defaults = {
threedee: false,
animationSpeed: 1, animationSpeed: 1,
forwardSpeed: 0.25, forwardSpeed: 0.25,
bloomStrength: 1, bloomStrength: 1,
bloomSize: 1, bloomSize: 0.6,
highPassThreshold: 0.3, highPassThreshold: 0.1,
cycleSpeed: 1, cycleSpeed: 1,
cycleStyleName: "cycleFasterWhenDimmed", cycleStyleName: "cycleFasterWhenDimmed",
cursorEffectThreshold: 1, cursorEffectThreshold: 1,
@@ -159,7 +160,8 @@ const paramMapping = {
parser: s => nullNaN(range(parseFloat(s), 0, 1)) parser: s => nullNaN(range(parseFloat(s), 0, 1))
}, },
url: { key: "bgURL", parser: s => s }, url: { key: "bgURL", parser: s => s },
colors: { key: "stripeColors", parser: s => s } colors: { key: "stripeColors", parser: s => s },
threedee: { key: "threedee", parser: s => s.toLowerCase().includes("true") }
}; };
paramMapping.dropLength = paramMapping.raindropLength; paramMapping.dropLength = paramMapping.raindropLength;
paramMapping.angle = paramMapping.slant; paramMapping.angle = paramMapping.slant;

View File

@@ -16,12 +16,17 @@ const cycleStyles = {
cycleRandomly: 1 cycleRandomly: 1
}; };
const numVerticesPerGlyph = 2 * 3; const numVerticesPerQuad = 2 * 3;
export default (regl, config) => { export default (regl, config) => {
const density = config.density; const threedee = config.threedee;
const density = threedee && config.effect !== "none" ? config.density : 1;
const [numRows, numColumns] = [config.numColumns, config.numColumns * density]; const [numRows, numColumns] = [config.numColumns, config.numColumns * density];
const [numQuadRows, numQuadColumns] = threedee ? [numRows, numColumns] : [1, 1];
const numQuads = numQuadRows * numQuadColumns;
const quadSize = [1 / numQuadColumns, 1 / numQuadRows];
// These two framebuffers are used to compute the raining code. // These two framebuffers are used to compute the raining code.
// they take turns being the source and destination of the "compute" shader. // they take turns being the source and destination of the "compute" shader.
@@ -40,36 +45,41 @@ export default (regl, config) => {
const output = makePassFBO(regl, config.useHalfFloat); const output = makePassFBO(regl, config.useHalfFloat);
const uniforms = extractEntries(config, [ const uniforms = {
// rain general ...extractEntries(config, [
"glyphHeightToWidth", // rain general
"glyphTextureColumns", "glyphHeightToWidth",
"density", "glyphTextureColumns",
// rain update // rain update
"animationSpeed", "animationSpeed",
"brightnessMinimum", "brightnessMinimum",
"brightnessMix", "brightnessMix",
"brightnessMultiplier", "brightnessMultiplier",
"brightnessOffset", "brightnessOffset",
"cursorEffectThreshold", "cursorEffectThreshold",
"cycleSpeed", "cycleSpeed",
"fallSpeed", "fallSpeed",
"glyphSequenceLength", "glyphSequenceLength",
"hasSun", "hasSun",
"hasThunder", "hasThunder",
"raindropLength", "raindropLength",
"rippleScale", "rippleScale",
"rippleSpeed", "rippleSpeed",
"rippleThickness", "rippleThickness",
// rain vertex // rain vertex
"forwardSpeed", "forwardSpeed",
// rain render // rain render
"glyphEdgeCrop", "glyphEdgeCrop",
"isPolar", "isPolar",
]); ]),
density,
uniforms.numRows = numRows; numRows,
uniforms.numColumns = numColumns; numColumns,
numQuadRows,
numQuadColumns,
quadSize,
threedee
};
uniforms.rippleType = uniforms.rippleType =
config.rippleTypeName in rippleTypes config.rippleTypeName in rippleTypes
@@ -264,23 +274,13 @@ export default (regl, config) => {
framebuffer: doubleBuffer.front framebuffer: doubleBuffer.front
}); });
const numGlyphs = numRows * numColumns; const quadPositions = Array(numQuadRows).fill().map((_, y) =>
Array(numQuadColumns).fill().map((_, x) =>
const glyphPositions = Array(numRows).fill().map((_, y) => Array(numVerticesPerQuad).fill([x, y])
Array(numColumns).fill().map((_, x) =>
Array(numVerticesPerGlyph).fill([x, y])
) )
); );
const glyphCorners = Array(numGlyphs).fill([[0, 0], [0, 1], [1, 1], [0, 0], [1, 1], [1, 0]]);
const depthMesh = {}; const quadCorners = Array(numQuads).fill([[0, 0], [0, 1], [1, 1], [0, 0], [1, 1], [1, 0]]);
Object.assign(depthMesh, {
attributes: {
aPosition: glyphPositions,
aCorner: glyphCorners
},
count: numGlyphs * numVerticesPerGlyph,
});
// We render the code into an FBO using MSDFs: https://github.com/Chlumsky/msdfgen // We render the code into an FBO using MSDFs: https://github.com/Chlumsky/msdfgen
const render = regl({ const render = regl({
@@ -297,28 +297,40 @@ export default (regl, config) => {
precision lowp float; precision lowp float;
attribute vec2 aPosition, aCorner; attribute vec2 aPosition, aCorner;
uniform float width, height; uniform float width, height;
uniform float numColumns, numRows, density; uniform float density;
uniform vec2 quadSize;
uniform sampler2D lastState; uniform sampler2D lastState;
uniform float forwardSpeed; uniform float forwardSpeed;
varying vec2 vUV; uniform float glyphHeightToWidth;
varying vec4 vGlyph;
uniform mat4 camera; uniform mat4 camera;
uniform mat4 transform; uniform mat4 transform;
uniform float time; uniform float time;
uniform bool threedee;
uniform bool showComputationTexture; uniform bool showComputationTexture;
varying vec2 vUV;
varying vec4 vGlyph;
void main() { void main() {
vUV = (aPosition + aCorner) / vec2(numColumns, numRows);
vec2 position = (aPosition + aCorner * vec2(density, 1.)) / vec2(numColumns, numRows); vUV = (aPosition + aCorner) * quadSize;
vec2 position = (aPosition + aCorner * vec2(density, 1.)) * quadSize;
position = (position - 0.5) * 2.0; position = (position - 0.5) * 2.0;
vGlyph = texture2D(lastState, vUV + (0.5 - aCorner) / vec2(numColumns, numRows)); vGlyph = texture2D(lastState, vUV + (0.5 - aCorner) * quadSize);
float glyphDepth = showComputationTexture ? 0. : fract(vGlyph.b + time * forwardSpeed); float quadDepth = 0.0;
vGlyph.b = glyphDepth; if (threedee && !showComputationTexture) {
vec4 pos = camera * transform * vec4(position, glyphDepth, 1.0); quadDepth = fract(vGlyph.b + time * forwardSpeed);
vGlyph.b = quadDepth;
}
vec4 pos = vec4(position, quadDepth, 1.0);
// Scale the geometry to cover the longest dimension of the viewport if (threedee) {
// vec2 size = width > height ? vec2(width / height, 1.) : vec2(1., height / width); pos.x /= glyphHeightToWidth;
// pos.xy *= size; pos = camera * transform * pos;
} else {
// Scale the geometry to cover the longest dimension of the viewport
vec2 size = width > height ? vec2(width / height, 1.) : vec2(1., height / width);
pos.xy *= size;
}
gl_Position = pos; gl_Position = pos;
} }
@@ -331,6 +343,7 @@ export default (regl, config) => {
#endif #endif
precision lowp float; precision lowp float;
uniform sampler2D lastState;
uniform float numColumns, numRows; uniform float numColumns, numRows;
uniform sampler2D glyphTex; uniform sampler2D glyphTex;
uniform float glyphHeightToWidth, glyphSequenceLength, glyphTextureColumns, glyphEdgeCrop; uniform float glyphHeightToWidth, glyphSequenceLength, glyphTextureColumns, glyphEdgeCrop;
@@ -338,6 +351,7 @@ export default (regl, config) => {
uniform float slantScale; uniform float slantScale;
uniform bool isPolar; uniform bool isPolar;
uniform bool showComputationTexture; uniform bool showComputationTexture;
uniform bool threedee;
varying vec2 vUV; varying vec2 vUV;
varying vec4 vGlyph; varying vec4 vGlyph;
@@ -357,37 +371,43 @@ export default (regl, config) => {
vec2 uv = vUV; vec2 uv = vUV;
if (isPolar) { if (!threedee) {
// Curves the UV space to make letters appear to radiate from up above if (isPolar) {
uv -= 0.5; // Curves the UV space to make letters appear to radiate from up above
uv *= 0.5; uv -= 0.5;
uv.y -= 0.5; uv *= 0.5;
float radius = length(uv); uv.y -= 0.5;
float angle = atan(uv.y, uv.x) / (2. * PI) + 0.5; float radius = length(uv);
uv = vec2(angle * 4. - 0.5, 1.5 - pow(radius, 0.5) * 1.5); float angle = atan(uv.y, uv.x) / (2. * PI) + 0.5;
} else { uv = vec2(angle * 4. - 0.5, 1.5 - pow(radius, 0.5) * 1.5);
// Applies the slant, scaling the UV space } else {
// to guarantee the viewport is still covered // Applies the slant, scaling the UV space
uv = vec2( // to guarantee the viewport is still covered
(uv.x - 0.5) * slantVec.x + (uv.y - 0.5) * slantVec.y, uv = vec2(
(uv.y - 0.5) * slantVec.x - (uv.x - 0.5) * slantVec.y (uv.x - 0.5) * slantVec.x + (uv.y - 0.5) * slantVec.y,
) * slantScale + 0.5; (uv.y - 0.5) * slantVec.x - (uv.x - 0.5) * slantVec.y
) * slantScale + 0.5;
}
uv.y /= glyphHeightToWidth;
} }
uv.y /= glyphHeightToWidth; vec4 glyph = threedee ? vGlyph : texture2D(lastState, uv);
if (showComputationTexture) { if (showComputationTexture) {
gl_FragColor = vGlyph; gl_FragColor = glyph;
return; return;
} }
// Unpack the values from the font texture // Unpack the values from the font texture
float brightness = vGlyph.r; float brightness = glyph.r;
float effect = vGlyph.a; float symbolIndex = getSymbolIndex(glyph.g);
float quadDepth = glyph.b;
float effect = glyph.a;
brightness = max(effect, brightness); brightness = max(effect, brightness);
float symbolIndex = getSymbolIndex(vGlyph.g); if (threedee) {
float glyphDepth = vGlyph.b; brightness = min(1.0, brightness * quadDepth * 1.25);
float depthFade = min(1.0, glyphDepth * 1.25); }
// resolve UV to MSDF texture coord // resolve UV to MSDF texture coord
vec2 symbolUV = vec2(mod(symbolIndex, glyphTextureColumns), floor(symbolIndex / glyphTextureColumns)); vec2 symbolUV = vec2(mod(symbolIndex, glyphTextureColumns), floor(symbolIndex / glyphTextureColumns));
@@ -402,7 +422,7 @@ export default (regl, config) => {
float sigDist = median3(dist) - 0.5; float sigDist = median3(dist) - 0.5;
float alpha = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0); float alpha = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0);
gl_FragColor = vec4(vec3(brightness * alpha * depthFade), 1.0); gl_FragColor = vec4(vec3(brightness * alpha), 1.0);
} }
`, `,
@@ -416,7 +436,11 @@ export default (regl, config) => {
lastState: doubleBuffer.front lastState: doubleBuffer.front
}, },
...depthMesh, attributes: {
aPosition: quadPositions,
aCorner: quadCorners
},
count: numQuads * numVerticesPerQuad,
framebuffer: output framebuffer: output
}); });