Exploring ways to preserve the vanilla JS browser demo without compromising on the bundle. Experimenting with embedding images in the bundle as data URIs

This commit is contained in:
Rezmason
2025-05-06 12:59:02 -07:00
parent 6663c92f99
commit eea341f50c
27 changed files with 372 additions and 137 deletions

View File

@@ -6,8 +6,6 @@ import {
makeBindGroup,
makePass,
} from "./utils.js";
import bloomBlurShader from "../../shaders/wgsl/bloomBlur.wgsl";
import bloomCombineShader from "../../shaders/wgsl/bloomCombine.wgsl";
// const makePyramid = makeComputeTarget;
@@ -56,8 +54,8 @@ export default ({ config, device }) => {
}
const assets = [
loadShader(device, bloomBlurShader),
loadShader(device, bloomCombineShader),
loadShader(device, "shaders/wgsl/bloomBlur.wgsl"),
loadShader(device, "shaders/wgsl/bloomCombine.wgsl"),
];
const linearSampler = device.createSampler({

View File

@@ -1,7 +1,5 @@
import { loadShader, makeBindGroup, makePass } from "./utils.js";
import endPassShader from "../../shaders/wgsl/endPass.wgsl";
// Eventually, WebGPU will allow the output of the final pass in the pipeline to be copied to the canvas texture.
// Until then, this render pass does the job.
@@ -23,7 +21,7 @@ export default ({ device, canvasFormat, canvasContext }) => {
let renderPipeline;
let renderBindGroup;
const assets = [loadShader(device, endPassShader)];
const assets = [loadShader(device, "shaders/wgsl/endPass.wgsl")];
const loaded = (async () => {
const [imageShader] = await Promise.all(assets);

View File

@@ -7,7 +7,6 @@ import {
makeBindGroup,
makePass,
} from "./utils.js";
import imagePassShader from "../../shaders/wgsl/imagePass.wgsl";
// Multiplies the rendered rain and bloom by a loaded in image
@@ -16,7 +15,10 @@ const defaultBGURL =
export default ({ config, cache, device }) => {
const bgURL = "bgURL" in config ? config.bgURL : defaultBGURL;
const assets = [loadTexture(device, cache, bgURL), loadShader(device, imagePassShader)];
const assets = [
loadTexture(device, cache, bgURL),
loadShader(device, "shaders/wgsl/imagePass.wgsl"),
];
const linearSampler = device.createSampler({
magFilter: "linear",

View File

@@ -1,5 +1,6 @@
import { structs } from "../../lib/gpu-buffer.js";
import { makeUniformBuffer, makePipeline } from "./utils.js";
import fetchLibraries from "../fetchLibraries.js";
import makeRain from "./rainPass.js";
import makeBloomPass from "./bloomPass.js";
@@ -23,7 +24,12 @@ const effects = {
mirror: makeMirrorPass,
};
let glMatrix;
export const init = async (canvas) => {
const libraries = await fetchLibraries();
glMatrix = libraries.glMatrix;
const resize = () => {
const devicePixelRatio = window.devicePixelRatio ?? 1;
canvas.width = Math.ceil(canvas.clientWidth * devicePixelRatio * rain.resolution);
@@ -50,7 +56,16 @@ export const init = async (canvas) => {
const device = await adapter.requestDevice();
const cache = new Map();
const rain = { canvas, resize, doubleClick, cache, canvasContext, adapter, device, resolution: 1 };
const rain = {
canvas,
resize,
doubleClick,
cache,
canvasContext,
adapter,
device,
resolution: 1,
};
window.addEventListener("dblclick", doubleClick);
window.addEventListener("resize", resize);
@@ -103,6 +118,7 @@ export const formulate = async (rain, config) => {
cameraTex,
cameraAspectRatio,
cameraSize,
glMatrix,
};
const effectName = config.effect in effects ? config.effect : "palette";

View File

@@ -6,7 +6,6 @@ import {
makeBindGroup,
makePass,
} from "./utils.js";
import mirrorPassShader from "../../shaders/wgsl/mirrorPass.wgsl";
let start;
const numTouches = 5;
@@ -26,7 +25,7 @@ window.onclick = (e) => {
};
export default ({ config, device, cameraTex, cameraAspectRatio, timeBuffer }) => {
const assets = [loadShader(device, mirrorPassShader)];
const assets = [loadShader(device, "shaders/wgsl/mirrorPass.wgsl")];
const linearSampler = device.createSampler({
magFilter: "linear",

View File

@@ -7,7 +7,6 @@ import {
makeComputeTarget,
makePass,
} from "./utils.js";
import palettePassShader from "../../shaders/wgsl/palettePass.wgsl";
// Maps the brightness of the rendered rain and bloom to colors
// in a linear gradient buffer generated from the passed-in color sequence
@@ -87,7 +86,7 @@ export default ({ config, device, timeBuffer }) => {
let output;
let screenSize;
const assets = [loadShader(device, palettePassShader)];
const assets = [loadShader(device, "shaders/wgsl/palettePass.wgsl")];
const loaded = (async () => {
const [paletteShader] = await Promise.all(assets);

View File

@@ -7,8 +7,6 @@ import {
makeBindGroup,
makePass,
} from "./utils.js";
import { mat2, mat4, vec2, vec3 } from "gl-matrix";
import rainPassShader from "../../shaders/wgsl/rainPass.wgsl";
const rippleTypes = {
box: 0,
@@ -35,13 +33,14 @@ const makeConfigBuffer = (device, configUniforms, config, density, gridSize, gly
return makeUniformBuffer(device, configUniforms, configData);
};
export default ({ config, cache, device, timeBuffer }) => {
export default ({ config, glMatrix, cache, device, timeBuffer }) => {
const { mat2, mat4, vec2, vec3 } = glMatrix;
const assets = [
loadTexture(device, cache, config.glyphMSDFURL),
loadTexture(device, cache, config.glintMSDFURL),
loadTexture(device, cache, config.baseTextureURL, false, true),
loadTexture(device, cache, config.glintTextureURL, false, true),
loadShader(device, rainPassShader),
loadShader(device, "shaders/wgsl/rainPass.wgsl"),
];
// The volumetric mode multiplies the number of columns

View File

@@ -8,7 +8,6 @@ import {
makeComputeTarget,
makePass,
} from "./utils.js";
import stripePassShader from "../../shaders/wgsl/stripePass.wgsl";
// Multiplies the rendered rain and bloom by a 1D gradient texture
// generated from the passed-in color sequence
@@ -69,7 +68,7 @@ export default ({ config, device, timeBuffer }) => {
let output;
let screenSize;
const assets = [loadShader(device, stripePassShader)];
const assets = [loadShader(device, "shaders/wgsl/stripePass.wgsl")];
const loaded = (async () => {
const [stripeShader] = await Promise.all(assets);

View File

@@ -1,5 +1,4 @@
const loadTexture = async (device, cache, url) => {
const key = url;
if (cache.has(key)) {
return cache.get(key);
@@ -63,9 +62,9 @@ const makeComputeTarget = (device, size, mipLevelCount = 1) =>
GPUTextureUsage.STORAGE_BINDING,
});
const loadShader = async (device, code /*text*/) => {
// const response = await fetch(url);
// const code = await response.text();
const loadShader = async (device, url) => {
const response = await fetch(url);
const code = await response.text();
return {
code,
module: device.createShaderModule({ code }),