Fixing some y-flip related stuff in the rain pass fragment shader. Consolidating and changing the type of a bunch of info in the config uniform. Improving the code comments.

This commit is contained in:
Rezmason
2021-10-30 20:05:07 -07:00
parent d8701c9408
commit 4ea6cadd2f
3 changed files with 43 additions and 41 deletions

View File

@@ -2,7 +2,7 @@ TODO:
WebGPU
First decent rainRender
Is there a way to whittle out quadSize?
What's wrong with the other font textures?
Port compute pass 100%
Compute entry point can live in the same wgsl file, I think
use textureLoad for texel access in render pipeline

View File

@@ -37,13 +37,11 @@ export default async (canvas, config) => {
// to reach the desired density, and then overlaps them
const volumetric = config.volumetric;
const density = volumetric && config.effect !== "none" ? config.density : 1;
const [numRows, numColumns] = [config.numColumns, config.numColumns * density];
const gridSize = [config.numColumns * density, config.numColumns];
// The volumetric mode requires us to create a grid of quads,
// rather than a single quad for our geometry
const [numQuadRows, numQuadColumns] = volumetric ? [numRows, numColumns] : [1, 1];
const numQuads = numQuadRows * numQuadColumns;
const quadSize = [1 / numQuadColumns, 1 / numQuadRows];
const numQuads = volumetric ? gridSize[0] * gridSize[1] : 1;
// Various effect-related values
const rippleType = config.rippleTypeName in rippleTypes ? rippleTypes[config.rippleTypeName] : -1;
@@ -57,8 +55,7 @@ export default async (canvas, config) => {
{ name: "animationSpeed", type: "f32", value: config.animationSpeed },
{ name: "glyphHeightToWidth", type: "f32", value: config.glyphHeightToWidth },
{ name: "resurrectingCodeRatio", type: "f32", value: config.resurrectingCodeRatio },
{ name: "numColumns", type: "i32", value: numColumns },
{ name: "numRows", type: "i32", value: numRows },
{ name: "gridSize", type: "vec2<f32>", value: gridSize },
{ name: "showComputationTexture", type: "i32", value: showComputationTexture },
// compute
@@ -84,9 +81,6 @@ export default async (canvas, config) => {
{ name: "glyphEdgeCrop", type: "f32", value: config.glyphEdgeCrop },
{ name: "isPolar", type: "i32", value: config.isPolar },
{ name: "density", type: "f32", value: density },
{ name: "numQuadColumns", type: "i32", value: numQuadColumns },
{ name: "numQuadRows", type: "i32", value: numQuadRows },
{ name: "quadSize", type: "vec2<f32>", value: quadSize },
{ name: "slantScale", type: "f32", value: slantScale },
{ name: "slantVec", type: "vec2<f32>", value: slantVec },
{ name: "volumetric", type: "i32", value: volumetric },

View File

@@ -11,8 +11,7 @@ let SQRT_5:f32 = 2.23606797749979;
animationSpeed : f32;
glyphHeightToWidth : f32;
resurrectingCodeRatio : f32;
numColumns : i32;
numRows : i32;
gridSize : vec2<f32>;
showComputationTexture : i32;
// compute
@@ -38,9 +37,6 @@ let SQRT_5:f32 = 2.23606797749979;
glyphEdgeCrop : f32;
isPolar : i32;
density : f32;
numQuadColumns : i32;
numQuadRows : i32;
quadSize : vec2<f32>;
slantScale : f32;
slantVec : vec2<f32>;
volumetric : i32;
@@ -110,6 +106,12 @@ fn wobble(x:f32) -> f32 {
var volumetric = bool(config.volumetric);
var quadGridSize = vec2<f32>(1.0);
if (volumetric) {
quadGridSize = config.gridSize;
}
// Convert the vertex index into its quad's position and its corner in its quad
var i = i32(input.index);
var quadIndex = i / NUM_VERTICES_PER_QUAD;
@@ -119,46 +121,52 @@ fn wobble(x:f32) -> f32 {
);
var quadPosition = vec2<f32>(
f32(quadIndex % config.numQuadColumns),
f32(quadIndex / config.numQuadColumns)
f32(quadIndex % i32(quadGridSize.x)),
f32(quadIndex / i32(quadGridSize.x))
);
var vUV = (quadPosition + quadCorner) * config.quadSize;
var vGlyph = vec4<f32>(1.0, 0.15, randomFloat(vec2<f32>(quadPosition.x, 1.0)), 0.0); // TODO: texture2D(state, quadPosition * config.quadSize);
// Calculate the vertex's uv
var uv = (quadPosition + quadCorner) / quadGridSize;
// Calculate the world space position
// Retrieve the quad's glyph data
var vGlyph = vec4<f32>(1.0, 0.72, randomFloat(vec2<f32>(quadPosition.x, 1.0)), 0.0); // TODO: texture2D(state, quadPosition / quadGridSize);
// Calculate the quad's depth
var quadDepth = 0.0;
if (volumetric && !bool(config.showComputationTexture)) {
quadDepth = fract(vGlyph.b + time.seconds * config.animationSpeed * config.forwardSpeed);
vGlyph.b = quadDepth;
}
var position = (quadPosition * vec2<f32>(1.0, config.glyphVerticalSpacing) + quadCorner * vec2<f32>(config.density, 1.0)) * config.quadSize;
var pos = vec4<f32>((position - 0.5) * 2.0, quadDepth, 1.0);
pos.y = -pos.y;
// Calculate the vertex's world space position
var worldPosition = quadPosition * vec2<f32>(1.0, config.glyphVerticalSpacing);
worldPosition = worldPosition + quadCorner * vec2<f32>(config.density, 1.0);
worldPosition = worldPosition / quadGridSize;
worldPosition = (worldPosition - 0.5) * 2.0;
worldPosition.y = -worldPosition.y;
// "Resurrected" columns are in the green channel,
// and are vertically flipped (along with their glyphs)
var vChannel = vec3<f32>(1.0, 0.0, 0.0);
if (volumetric && randomFloat(vec2<f32>(quadPosition.x, 0.0)) < config.resurrectingCodeRatio) {
pos.y = -pos.y;
worldPosition.y = -worldPosition.y;
vChannel = vec3<f32>(0.0, 1.0, 0.0);
}
vChannel = vec3<f32>(1.0); // TODO: remove
// Convert the world space position to screen space
// Convert the vertex's world space position to screen space
var screenPosition = vec4<f32>(worldPosition, quadDepth, 1.0);
if (volumetric) {
pos.x = pos.x / config.glyphHeightToWidth;
pos = scene.camera * scene.transform * pos;
screenPosition.x = screenPosition.x / config.glyphHeightToWidth;
screenPosition = scene.camera * scene.transform * screenPosition;
} else {
pos.x = pos.x * scene.screenSize.x;
pos.y = pos.y * scene.screenSize.y;
screenPosition = vec4<f32>(screenPosition.xy * scene.screenSize, screenPosition.zw);
}
return VertOutput(
pos,
vUV,
screenPosition,
uv,
vChannel,
vGlyph
);
@@ -182,26 +190,26 @@ fn getSymbolUV(glyphCycle:f32) -> vec2<f32> {
var volumetric = bool(config.volumetric);
var uv = input.uv;
// In normal mode, derives the current glyph and UV from vUV
// For normal mode, derive the fragment's glyph and msdf UV from its screen space position
if (!volumetric) {
if (bool(config.isPolar)) {
// Curved space that makes letters appear to radiate from up above
// Curve space to make the letters appear to radiate from up above
uv = (uv - 0.5) * 0.5;
uv.y = uv.y - 0.5;
uv.y = uv.y + 0.5;
var radius = length(uv);
var angle = atan2(uv.y, uv.x) / (2.0 * PI) + 0.5; // atan?
uv = vec2<f32>(fract(angle * 4.0 - 0.5), 1.5 * (1.0 - sqrt(radius)));
var angle = atan2(uv.y, uv.x) / (2.0 * PI) + 0.5;
uv = -vec2<f32>(fract(angle * 4.0 - 0.5), 1.5 * (1.0 - sqrt(radius)));
} else {
// Applies the slant and scales space so the viewport is fully covered
// Apply the slant and a scale to space so the viewport is still fully covered by the geometry
uv = vec2<f32>(
(uv.x - 0.5) * config.slantVec.x + (uv.y - 0.5) * config.slantVec.y,
(uv.y - 0.5) * config.slantVec.x - (uv.x - 0.5) * config.slantVec.y
(uv.x - 0.5) * config.slantVec.x + (uv.y - 0.5) * -config.slantVec.y,
(uv.y - 0.5) * config.slantVec.x - (uv.x - 0.5) * -config.slantVec.y
) * config.slantScale + 0.5;
}
uv.y = uv.y / config.glyphHeightToWidth;
}
// Unpack the values from the data texture
// Retrieve values from the data texture
var glyph:vec4<f32>;
if (volumetric) {
glyph = input.glyph;
@@ -221,7 +229,7 @@ fn getSymbolUV(glyphCycle:f32) -> vec2<f32> {
}
// resolve UV to cropped position of glyph in MSDF texture
var glyphUV = fract(uv * vec2<f32>(f32(config.numColumns), f32(config.numRows)));
var glyphUV = fract(uv * config.gridSize);
glyphUV = glyphUV - 0.5;
glyphUV = glyphUV * clamp(1.0 - config.glyphEdgeCrop, 0.0, 1.0);
glyphUV = glyphUV + 0.5;