mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-16 21:39:29 -07:00
- Added "slant" param to readme
- getParam now supports synonyms - Renamed "dropLength" URL param to "raindropLength", keeping around support for dropLength URL param - Renamed "texture" to "fontTexture" - Changed "isSlanted" boolean to "slant" angle, adding slant/angle URL param, converted from degrees to radians - Renamed "numGlyphColumns" to "numFontColumns" - Renamed "showRTT" to "showComputationTexture" - Random glyphs are now based on a simple sine scramble - Renaming "now" and "delta" to "time" and "deltaTime" - glyphCycleSpeed is no longer premultiplied; it is now a number between 0 and 1, much easier to visualize
This commit is contained in:
@@ -3,13 +3,13 @@ const makeMatrixRenderer = (renderer, texture, {
|
||||
numColumns,
|
||||
animationSpeed, fallSpeed, cycleSpeed,
|
||||
glyphSequenceLength,
|
||||
numGlyphColumns,
|
||||
numFontColumns,
|
||||
hasThunder,
|
||||
hasSun,
|
||||
isPolar,
|
||||
isSlanted,
|
||||
showRTT,
|
||||
dropLength
|
||||
slant,
|
||||
showComputationTexture,
|
||||
raindropLength
|
||||
}) => {
|
||||
const matrixRenderer = {};
|
||||
const camera = new THREE.OrthographicCamera( -0.5, 0.5, 0.5, -0.5, 0.0001, 10000 );
|
||||
@@ -17,9 +17,12 @@ const makeMatrixRenderer = (renderer, texture, {
|
||||
const gpuCompute = new GPUComputationRenderer( numColumns, numColumns, renderer );
|
||||
const glyphValue = gpuCompute.createTexture();
|
||||
const pixels = glyphValue.image.data;
|
||||
|
||||
const scramble = i => Math.sin(i) * 0.5 + 0.5;
|
||||
|
||||
for (let i = 0; i < numColumns * numColumns; i++) {
|
||||
pixels[i * 4 + 0] = 0;
|
||||
pixels[i * 4 + 1] = Math.random();
|
||||
pixels[i * 4 + 1] = showComputationTexture ? 0 : scramble(i);
|
||||
pixels[i * 4 + 2] = 0;
|
||||
pixels[i * 4 + 3] = 0;
|
||||
}
|
||||
@@ -31,15 +34,15 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
#define PI 3.14159265359
|
||||
#define SQRT_2 1.4142135623730951
|
||||
#define SQRT_5 2.23606797749979
|
||||
uniform float now;
|
||||
uniform float delta;
|
||||
uniform float time;
|
||||
uniform float deltaTime;
|
||||
uniform float animationSpeed;
|
||||
uniform float fallSpeed;
|
||||
uniform float cycleSpeed;
|
||||
uniform float brightnessChangeBias;
|
||||
uniform float glyphSequenceLength;
|
||||
uniform float numGlyphColumns;
|
||||
uniform float dropLength;
|
||||
uniform float numFontColumns;
|
||||
uniform float raindropLength;
|
||||
|
||||
highp float rand( const in vec2 uv ) {
|
||||
const highp float a = 12.9898, b = 78.233, c = 43758.5453;
|
||||
@@ -62,11 +65,11 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
vec4 data = texture2D( glyph, uv );
|
||||
|
||||
float brightness = data.r;
|
||||
float cycle = data.g;
|
||||
float glyphCycle = data.g;
|
||||
|
||||
float simTime = now * 0.0005 * animationSpeed;
|
||||
float simTime = time * 0.0005 * animationSpeed;
|
||||
float columnTime = (columnTimeOffset * 1000.0 + simTime * fallSpeed) * (0.5 + columnSpeedOffset * 0.5) + (sin(simTime * fallSpeed * 2.0 * columnSpeedOffset) * 0.2);
|
||||
float glyphTime = (gl_FragCoord.y * 0.01 + columnTime) / dropLength;
|
||||
float glyphTime = (gl_FragCoord.y * 0.01 + columnTime) / raindropLength;
|
||||
|
||||
float value = 1.0 - fract((glyphTime + 0.3 * sin(SQRT_2 * glyphTime) + 0.2 * sin(SQRT_5 * glyphTime)));
|
||||
|
||||
@@ -92,23 +95,23 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
brightness = mix(brightness, newBrightness, brightnessChangeBias);
|
||||
#endif
|
||||
|
||||
float glyphCycleSpeed = (brightness < 0.0) ? 0.0 : delta * cycleSpeed * 0.2 * pow(1.0 - brightness, 4.0);
|
||||
cycle = fract(cycle + glyphCycleSpeed);
|
||||
float symbol = floor(glyphSequenceLength * cycle);
|
||||
float symbolX = mod(symbol, numGlyphColumns);
|
||||
float symbolY = ((numGlyphColumns - 1.0) - (symbol - symbolX) / numGlyphColumns);
|
||||
float glyphCycleSpeed = (brightness <= 0.0) ? 0.0 : pow(1.0 - brightness, 4.0);
|
||||
glyphCycle = fract(glyphCycle + deltaTime * cycleSpeed * 0.2 * glyphCycleSpeed);
|
||||
float symbol = floor(glyphSequenceLength * glyphCycle);
|
||||
float symbolX = mod(symbol, numFontColumns);
|
||||
float symbolY = ((numFontColumns - 1.0) - (symbol - symbolX) / numFontColumns);
|
||||
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
gl_FragColor.r = brightness;
|
||||
gl_FragColor.g = cycle;
|
||||
gl_FragColor.g = glyphCycle;
|
||||
|
||||
#ifdef showRTT
|
||||
#ifdef showComputationTexture
|
||||
// Better use of the blue channel, for show and tell
|
||||
gl_FragColor.b = min(1.0, glyphCycleSpeed * 500.0);
|
||||
gl_FragColor.b = min(1.0, glyphCycleSpeed);
|
||||
gl_FragColor.a = 1.0;
|
||||
#else
|
||||
gl_FragColor.b = symbolX / numGlyphColumns;
|
||||
gl_FragColor.a = symbolY / numGlyphColumns;
|
||||
gl_FragColor.b = symbolX / numFontColumns;
|
||||
gl_FragColor.a = symbolY / numFontColumns;
|
||||
#endif
|
||||
}
|
||||
`
|
||||
@@ -119,14 +122,14 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
|
||||
const brightnessChangeBias = (animationSpeed * fallSpeed) == 0 ? 1 : Math.min(1, Math.abs(animationSpeed * fallSpeed));
|
||||
Object.assign(glyphVariable.material.uniforms, {
|
||||
now: { type: "f", value: 0 },
|
||||
delta: { type: "f", value: 0.01 },
|
||||
time: { type: "f", value: 0 },
|
||||
deltaTime: { type: "f", value: 0.01 },
|
||||
animationSpeed: { type: "f", value: animationSpeed },
|
||||
fallSpeed: { type: "f", value: fallSpeed },
|
||||
cycleSpeed: {type: "f", value: cycleSpeed },
|
||||
glyphSequenceLength: { type: "f", value: glyphSequenceLength },
|
||||
numGlyphColumns: {type: "f", value: numGlyphColumns },
|
||||
dropLength: {type: "f", value: dropLength },
|
||||
numFontColumns: {type: "f", value: numFontColumns },
|
||||
raindropLength: {type: "f", value: raindropLength },
|
||||
brightnessChangeBias: { type: "f", value: brightnessChangeBias },
|
||||
});
|
||||
if (hasThunder) {
|
||||
@@ -135,8 +138,8 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
if (hasSun) {
|
||||
glyphVariable.material.defines.hasSun = 1.0;
|
||||
}
|
||||
if (showRTT) {
|
||||
glyphVariable.material.defines.showRTT = 1.0;
|
||||
if (showComputationTexture) {
|
||||
glyphVariable.material.defines.showComputationTexture = 1.0;
|
||||
}
|
||||
|
||||
const error = gpuCompute.init();
|
||||
@@ -154,8 +157,9 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
msdf: { type: "t", value: texture },
|
||||
numColumns: {type: "f", value: numColumns},
|
||||
sharpness: { type: "f", value: sharpness },
|
||||
numGlyphColumns: {type: "f", value: numGlyphColumns},
|
||||
numFontColumns: {type: "f", value: numFontColumns},
|
||||
resolution: {type: "v2", value: new THREE.Vector2() },
|
||||
slant: {type: "v2", value: new THREE.Vector2(Math.cos(slant), Math.sin(slant)) }
|
||||
},
|
||||
vertexShader: `
|
||||
attribute vec2 uv;
|
||||
@@ -179,7 +183,8 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
uniform sampler2D msdf;
|
||||
uniform sampler2D glyphs;
|
||||
uniform float numColumns;
|
||||
uniform float numGlyphColumns;
|
||||
uniform float numFontColumns;
|
||||
uniform vec2 slant;
|
||||
varying vec2 vUV;
|
||||
|
||||
float median(float r, float g, float b) {
|
||||
@@ -189,23 +194,22 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
void main() {
|
||||
|
||||
vec2 uv = vUV;
|
||||
|
||||
uv = vec2(
|
||||
(uv.x - 0.5) * slant.x + (uv.y - 0.5) * slant.y,
|
||||
(uv.y - 0.5) * slant.x - (uv.x - 0.5) * slant.y
|
||||
) * 0.75 + 0.5;
|
||||
|
||||
#ifdef isPolar
|
||||
vec2 diff = vUV - vec2(0.5, 1.25);
|
||||
vec2 diff = uv - vec2(0.5, 1.25);
|
||||
float radius = length(diff);
|
||||
float angle = atan(diff.y, diff.x) + PI;
|
||||
uv = vec2(angle / PI, 1.0 - pow(radius * 0.75, 0.6));
|
||||
#endif
|
||||
#ifdef isSlanted
|
||||
float angle = PI * 0.125;
|
||||
vec2 rotation = vec2(cos(angle), sin(angle));
|
||||
uv = vec2(
|
||||
(vUV.x - 0.5) * rotation.x + (vUV.y - 0.5) * rotation.y,
|
||||
(vUV.y - 0.5) * rotation.x - (vUV.x - 0.5) * rotation.y) * 0.75 + 0.5;
|
||||
#endif
|
||||
|
||||
vec4 glyph = texture2D(glyphs, uv);
|
||||
|
||||
#ifdef showRTT
|
||||
#ifdef showComputationTexture
|
||||
gl_FragColor = glyph;
|
||||
return;
|
||||
#endif
|
||||
@@ -213,7 +217,7 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
// Unpack the values from the glyph texture
|
||||
float brightness = glyph.r;
|
||||
vec2 symbolUV = glyph.ba;
|
||||
vec4 sample = texture2D(msdf, fract(uv * numColumns) / numGlyphColumns + symbolUV);
|
||||
vec4 sample = texture2D(msdf, fract(uv * numColumns) / numFontColumns + symbolUV);
|
||||
|
||||
// The rest is straight up MSDF
|
||||
float sigDist = median(sample.r, sample.g, sample.b) - 0.5;
|
||||
@@ -239,12 +243,8 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
mesh.material.defines.isPolar = 1.0;
|
||||
}
|
||||
|
||||
if (isSlanted) {
|
||||
mesh.material.defines.isSlanted = 1.0;
|
||||
}
|
||||
|
||||
if (showRTT) {
|
||||
mesh.material.defines.showRTT = 1.0;
|
||||
if (showComputationTexture) {
|
||||
mesh.material.defines.showComputationTexture = 1.0;
|
||||
}
|
||||
|
||||
scene.add( mesh );
|
||||
@@ -266,11 +266,11 @@ const glyphVariable = gpuCompute.addVariable(
|
||||
return;
|
||||
}
|
||||
|
||||
const delta = ((now - last > 1000) ? 0 : now - last) / 1000 * animationSpeed;
|
||||
const deltaTime = ((now - last > 1000) ? 0 : now - last) / 1000 * animationSpeed;
|
||||
last = now;
|
||||
|
||||
glyphVariable.material.uniforms.now.value = now;
|
||||
glyphVariable.material.uniforms.delta.value = delta;
|
||||
glyphVariable.material.uniforms.time.value = now;
|
||||
glyphVariable.material.uniforms.deltaTime.value = deltaTime;
|
||||
|
||||
gpuCompute.compute();
|
||||
renderer.render( scene, camera );
|
||||
|
||||
Reference in New Issue
Block a user