- 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:
Rezmason
2019-02-17 18:42:08 -08:00
parent 7d34f00dde
commit d03cd685e1
3 changed files with 79 additions and 68 deletions

View File

@@ -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 );