mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-18 14:19:30 -07:00
The renderer now accepts a density parameter, that multiplies the columns.
Glyph depth now impacts brightness. Raindrops now move forward at a steady speed.
This commit is contained in:
@@ -18,6 +18,7 @@ const fonts = {
|
|||||||
|
|
||||||
const defaults = {
|
const defaults = {
|
||||||
animationSpeed: 1,
|
animationSpeed: 1,
|
||||||
|
forwardSpeed: 0.25,
|
||||||
bloomStrength: 1,
|
bloomStrength: 1,
|
||||||
bloomSize: 1,
|
bloomSize: 1,
|
||||||
highPassThreshold: 0.3,
|
highPassThreshold: 0.3,
|
||||||
@@ -39,6 +40,7 @@ const defaults = {
|
|||||||
rippleScale: 30,
|
rippleScale: 30,
|
||||||
rippleSpeed: 0.2,
|
rippleSpeed: 0.2,
|
||||||
numColumns: 80,
|
numColumns: 80,
|
||||||
|
density: 1,
|
||||||
paletteEntries: [
|
paletteEntries: [
|
||||||
{ rgb: [0.0, 0.0, 0.0], at: 0.0 },
|
{ rgb: [0.0, 0.0, 0.0], at: 0.0 },
|
||||||
{ rgb: [0.09, 0.33, 0.04], at: 0.25 },
|
{ rgb: [0.09, 0.33, 0.04], at: 0.25 },
|
||||||
@@ -131,11 +133,17 @@ const paramMapping = {
|
|||||||
version: { key: "version", parser: s => s },
|
version: { key: "version", parser: s => s },
|
||||||
effect: { key: "effect", parser: s => s },
|
effect: { key: "effect", parser: s => s },
|
||||||
width: { key: "numColumns", parser: s => nullNaN(parseInt(s)) },
|
width: { key: "numColumns", parser: s => nullNaN(parseInt(s)) },
|
||||||
|
numColumns: { key: "numColumns", parser: s => nullNaN(parseInt(s)) },
|
||||||
|
density: { key: "density", parser: s => nullNaN(range(parseFloat(s), 0)) },
|
||||||
resolution: { key: "resolution", parser: s => nullNaN(parseFloat(s)) },
|
resolution: { key: "resolution", parser: s => nullNaN(parseFloat(s)) },
|
||||||
animationSpeed: {
|
animationSpeed: {
|
||||||
key: "animationSpeed",
|
key: "animationSpeed",
|
||||||
parser: s => nullNaN(parseFloat(s))
|
parser: s => nullNaN(parseFloat(s))
|
||||||
},
|
},
|
||||||
|
forwardSpeed: {
|
||||||
|
key: "forwardSpeed",
|
||||||
|
parser: s => nullNaN(parseFloat(s))
|
||||||
|
},
|
||||||
cycleSpeed: { key: "cycleSpeed", parser: s => nullNaN(parseFloat(s)) },
|
cycleSpeed: { key: "cycleSpeed", parser: s => nullNaN(parseFloat(s)) },
|
||||||
fallSpeed: { key: "fallSpeed", parser: s => nullNaN(parseFloat(s)) },
|
fallSpeed: { key: "fallSpeed", parser: s => nullNaN(parseFloat(s)) },
|
||||||
raindropLength: {
|
raindropLength: {
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ const cycleStyles = {
|
|||||||
|
|
||||||
const numVerticesPerGlyph = 2 * 3;
|
const numVerticesPerGlyph = 2 * 3;
|
||||||
|
|
||||||
const camera = glMatrix.mat4.create();
|
|
||||||
const transform = glMatrix.mat4.create();
|
|
||||||
|
|
||||||
export default (regl, config) => {
|
export default (regl, config) => {
|
||||||
|
|
||||||
|
const density = config.density;
|
||||||
|
const [numRows, numColumns] = [config.numColumns, config.numColumns * density];
|
||||||
|
|
||||||
// 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.
|
||||||
// The half float data type is crucial! It lets us store almost any real number,
|
// The half float data type is crucial! It lets us store almost any real number,
|
||||||
@@ -30,12 +31,12 @@ export default (regl, config) => {
|
|||||||
// This double buffer is smaller than the screen, because its pixels correspond
|
// This double buffer is smaller than the screen, because its pixels correspond
|
||||||
// with glyphs in the final image, and the glyphs are much larger than a pixel.
|
// with glyphs in the final image, and the glyphs are much larger than a pixel.
|
||||||
const doubleBuffer = makeDoubleBuffer(regl, {
|
const doubleBuffer = makeDoubleBuffer(regl, {
|
||||||
radius: config.numColumns,
|
width: numColumns,
|
||||||
|
height: numRows,
|
||||||
wrapT: "clamp",
|
wrapT: "clamp",
|
||||||
type: "half float"
|
type: "half float"
|
||||||
});
|
});
|
||||||
|
|
||||||
const numColumns = config.numColumns;
|
|
||||||
|
|
||||||
const output = makePassFBO(regl, config.useHalfFloat);
|
const output = makePassFBO(regl, config.useHalfFloat);
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ export default (regl, config) => {
|
|||||||
// rain general
|
// rain general
|
||||||
"glyphHeightToWidth",
|
"glyphHeightToWidth",
|
||||||
"glyphTextureColumns",
|
"glyphTextureColumns",
|
||||||
"numColumns",
|
"density",
|
||||||
// rain update
|
// rain update
|
||||||
"animationSpeed",
|
"animationSpeed",
|
||||||
"brightnessMinimum",
|
"brightnessMinimum",
|
||||||
@@ -60,11 +61,16 @@ export default (regl, config) => {
|
|||||||
"rippleScale",
|
"rippleScale",
|
||||||
"rippleSpeed",
|
"rippleSpeed",
|
||||||
"rippleThickness",
|
"rippleThickness",
|
||||||
|
// rain vertex
|
||||||
|
"forwardSpeed",
|
||||||
// rain render
|
// rain render
|
||||||
"glyphEdgeCrop",
|
"glyphEdgeCrop",
|
||||||
"isPolar"
|
"isPolar",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
uniforms.numRows = numRows;
|
||||||
|
uniforms.numColumns = numColumns;
|
||||||
|
|
||||||
uniforms.rippleType =
|
uniforms.rippleType =
|
||||||
config.rippleTypeName in rippleTypes
|
config.rippleTypeName in rippleTypes
|
||||||
? rippleTypes[config.rippleTypeName]
|
? rippleTypes[config.rippleTypeName]
|
||||||
@@ -95,7 +101,7 @@ export default (regl, config) => {
|
|||||||
#define SQRT_5 2.23606797749979
|
#define SQRT_5 2.23606797749979
|
||||||
|
|
||||||
uniform float time;
|
uniform float time;
|
||||||
uniform float numColumns;
|
uniform float numColumns, numRows;
|
||||||
uniform sampler2D lastState;
|
uniform sampler2D lastState;
|
||||||
uniform bool hasSun;
|
uniform bool hasSun;
|
||||||
uniform bool hasThunder;
|
uniform bool hasThunder;
|
||||||
@@ -197,7 +203,7 @@ export default (regl, config) => {
|
|||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
vec2 glyphPos = gl_FragCoord.xy;
|
vec2 glyphPos = gl_FragCoord.xy;
|
||||||
vec2 screenPos = glyphPos / numColumns;
|
vec2 screenPos = glyphPos / vec2(numColumns, numRows);
|
||||||
float simTime = time * animationSpeed;
|
float simTime = time * animationSpeed;
|
||||||
|
|
||||||
// Read the current values of the glyph
|
// Read the current values of the glyph
|
||||||
@@ -258,9 +264,9 @@ export default (regl, config) => {
|
|||||||
framebuffer: doubleBuffer.front
|
framebuffer: doubleBuffer.front
|
||||||
});
|
});
|
||||||
|
|
||||||
const numGlyphs = numColumns * numColumns;
|
const numGlyphs = numRows * numColumns;
|
||||||
|
|
||||||
const glyphPositions = Array(numColumns).fill().map((_, y) =>
|
const glyphPositions = Array(numRows).fill().map((_, y) =>
|
||||||
Array(numColumns).fill().map((_, x) =>
|
Array(numColumns).fill().map((_, x) =>
|
||||||
Array(numVerticesPerGlyph).fill([x, y])
|
Array(numVerticesPerGlyph).fill([x, y])
|
||||||
)
|
)
|
||||||
@@ -291,8 +297,9 @@ 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;
|
uniform float numColumns, numRows, density;
|
||||||
uniform sampler2D lastState;
|
uniform sampler2D lastState;
|
||||||
|
uniform float forwardSpeed;
|
||||||
varying vec2 vUV;
|
varying vec2 vUV;
|
||||||
varying vec4 vGlyph;
|
varying vec4 vGlyph;
|
||||||
uniform mat4 camera;
|
uniform mat4 camera;
|
||||||
@@ -300,11 +307,13 @@ export default (regl, config) => {
|
|||||||
uniform float time;
|
uniform float time;
|
||||||
uniform bool showComputationTexture;
|
uniform bool showComputationTexture;
|
||||||
void main() {
|
void main() {
|
||||||
vUV = (aPosition + aCorner) / numColumns;
|
vUV = (aPosition + aCorner) / vec2(numColumns, numRows);
|
||||||
vec2 position = (vUV - 0.5) * 2.0;
|
vec2 position = (aPosition + aCorner * vec2(density, 1.)) / vec2(numColumns, numRows);
|
||||||
vGlyph = texture2D(lastState, vUV + (0.5 - aCorner) / numColumns);
|
position = (position - 0.5) * 2.0;
|
||||||
|
vGlyph = texture2D(lastState, vUV + (0.5 - aCorner) / vec2(numColumns, numRows));
|
||||||
|
|
||||||
float glyphDepth = showComputationTexture ? 0. : vGlyph.b;
|
float glyphDepth = showComputationTexture ? 0. : fract(vGlyph.b + time * forwardSpeed);
|
||||||
|
vGlyph.b = glyphDepth;
|
||||||
vec4 pos = camera * transform * vec4(position, glyphDepth, 1.0);
|
vec4 pos = camera * transform * vec4(position, glyphDepth, 1.0);
|
||||||
|
|
||||||
// Scale the geometry to cover the longest dimension of the viewport
|
// Scale the geometry to cover the longest dimension of the viewport
|
||||||
@@ -322,7 +331,7 @@ export default (regl, config) => {
|
|||||||
#endif
|
#endif
|
||||||
precision lowp float;
|
precision lowp float;
|
||||||
|
|
||||||
uniform float numColumns;
|
uniform float numColumns, numRows;
|
||||||
uniform sampler2D glyphTex;
|
uniform sampler2D glyphTex;
|
||||||
uniform float glyphHeightToWidth, glyphSequenceLength, glyphTextureColumns, glyphEdgeCrop;
|
uniform float glyphHeightToWidth, glyphSequenceLength, glyphTextureColumns, glyphEdgeCrop;
|
||||||
uniform vec2 slantVec;
|
uniform vec2 slantVec;
|
||||||
@@ -377,10 +386,12 @@ export default (regl, config) => {
|
|||||||
float effect = vGlyph.a;
|
float effect = vGlyph.a;
|
||||||
brightness = max(effect, brightness);
|
brightness = max(effect, brightness);
|
||||||
float symbolIndex = getSymbolIndex(vGlyph.g);
|
float symbolIndex = getSymbolIndex(vGlyph.g);
|
||||||
|
float glyphDepth = vGlyph.b;
|
||||||
|
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));
|
||||||
vec2 glyphUV = fract(uv * numColumns);
|
vec2 glyphUV = fract(uv * vec2(numColumns, numRows));
|
||||||
glyphUV -= 0.5;
|
glyphUV -= 0.5;
|
||||||
glyphUV *= clamp(1.0 - glyphEdgeCrop, 0.0, 1.0);
|
glyphUV *= clamp(1.0 - glyphEdgeCrop, 0.0, 1.0);
|
||||||
glyphUV += 0.5;
|
glyphUV += 0.5;
|
||||||
@@ -391,7 +402,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), 1.0);
|
gl_FragColor = vec4(vec3(brightness * alpha * depthFade), 1.0);
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
|
||||||
@@ -410,8 +421,13 @@ export default (regl, config) => {
|
|||||||
framebuffer: output
|
framebuffer: output
|
||||||
});
|
});
|
||||||
|
|
||||||
const translation = glMatrix.vec3.set(glMatrix.vec3.create(), 0, 0, -1);
|
const {mat4, vec3} = glMatrix;
|
||||||
const scale = glMatrix.vec3.set(glMatrix.vec3.create(), 3, 3, 1);
|
const camera = mat4.create();
|
||||||
|
const translation = vec3.set(vec3.create(), 0, 0.5 / numRows, -1);
|
||||||
|
const scale = vec3.set(vec3.create(), 1, 1, 1);
|
||||||
|
const transform = mat4.create();
|
||||||
|
mat4.translate(transform, transform, translation);
|
||||||
|
mat4.scale(transform, transform, scale);
|
||||||
|
|
||||||
return makePass(
|
return makePass(
|
||||||
{
|
{
|
||||||
@@ -421,11 +437,6 @@ export default (regl, config) => {
|
|||||||
|
|
||||||
const time = Date.now();
|
const time = Date.now();
|
||||||
|
|
||||||
glMatrix.mat4.identity(transform);
|
|
||||||
glMatrix.mat4.translate(transform, transform, translation);
|
|
||||||
glMatrix.mat4.scale(transform, transform, scale);
|
|
||||||
glMatrix.mat4.rotateY(transform, transform, Math.PI * 2 * Math.sin(time * 0.001) * 0.05);
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
regl.clear({
|
regl.clear({
|
||||||
depth: 1,
|
depth: 1,
|
||||||
@@ -437,7 +448,7 @@ export default (regl, config) => {
|
|||||||
(w, h) => {
|
(w, h) => {
|
||||||
output.resize(w, h);
|
output.resize(w, h);
|
||||||
const aspectRatio = w / h;
|
const aspectRatio = w / h;
|
||||||
glMatrix.mat4.perspective(camera, (Math.PI / 180) * 150, aspectRatio, 0.0001, 1000);
|
glMatrix.mat4.perspective(camera, (Math.PI / 180) * 90, aspectRatio, 0.0001, 1000);
|
||||||
},
|
},
|
||||||
msdfLoader.ready
|
msdfLoader.ready
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user