Added cache check to WebGPU renderer's loadShader method. Un-commented entries into config.js. Inclusions are now explicit dynamic import lambdas, so the cache functions can detect and call them; however, webpack and rollup seem to use them differently.

This commit is contained in:
Rezmason
2025-05-20 07:57:27 -07:00
parent 24e939008e
commit f61a4e29c9
20 changed files with 268 additions and 160 deletions

View File

@@ -39,7 +39,7 @@ const makePyramidViews = (pyramid) => pyramid.map((tex) => tex.createView());
// The bloom pass is basically an added blur of the rain pass's high-pass output.
// The blur approximation is the sum of a pyramid of downscaled, blurred textures.
export default ({ config, device }) => {
export default ({ config, device, cache }) => {
const pyramidHeight = 4;
const bloomSize = config.bloomSize;
const bloomStrength = config.bloomStrength;
@@ -54,8 +54,8 @@ export default ({ config, device }) => {
}
const assets = [
loadShader(device, "shaders/wgsl/bloomBlur.wgsl"),
loadShader(device, "shaders/wgsl/bloomCombine.wgsl"),
loadShader(device, cache, "shaders/wgsl/bloomBlur.wgsl"),
loadShader(device, cache, "shaders/wgsl/bloomCombine.wgsl"),
];
const linearSampler = device.createSampler({

View File

@@ -5,7 +5,7 @@ import { loadShader, makeBindGroup, makePass } from "./utils.js";
const numVerticesPerQuad = 2 * 3;
export default ({ device, canvasFormat, canvasContext }) => {
export default ({ device, cache, canvasFormat, canvasContext }) => {
const nearestSampler = device.createSampler();
const renderPassConfig = {
@@ -21,7 +21,7 @@ export default ({ device, canvasFormat, canvasContext }) => {
let renderPipeline;
let renderBindGroup;
const assets = [loadShader(device, "shaders/wgsl/endPass.wgsl")];
const assets = [loadShader(device, cache, "shaders/wgsl/endPass.wgsl")];
const loaded = (async () => {
const [imageShader] = await Promise.all(assets);

View File

@@ -17,7 +17,7 @@ export default ({ config, cache, device }) => {
const bgURL = "bgURL" in config ? config.bgURL : defaultBGURL;
const assets = [
loadTexture(device, cache, bgURL),
loadShader(device, "shaders/wgsl/imagePass.wgsl"),
loadShader(device, cache, "shaders/wgsl/imagePass.wgsl"),
];
const linearSampler = device.createSampler({

View File

@@ -24,11 +24,12 @@ const effects = {
mirror: makeMirrorPass,
};
let glMatrix;
let glMatrix, inclusions;
export const init = async (canvas) => {
const libraries = await fetchLibraries();
glMatrix = libraries.glMatrix;
inclusions = libraries.inclusions;
const resize = () => {
const devicePixelRatio = window.devicePixelRatio ?? 1;

View File

@@ -24,8 +24,8 @@ window.onclick = (e) => {
touchesChanged = true;
};
export default ({ config, device, cameraTex, cameraAspectRatio, timeBuffer }) => {
const assets = [loadShader(device, "shaders/wgsl/mirrorPass.wgsl")];
export default ({ config, device, cache, cameraTex, cameraAspectRatio, timeBuffer }) => {
const assets = [loadShader(device, cache, "shaders/wgsl/mirrorPass.wgsl")];
const linearSampler = device.createSampler({
magFilter: "linear",

View File

@@ -73,7 +73,7 @@ const makePalette = (device, paletteUniforms, entries) => {
// won't persist across subsequent frames. This is a safe trick
// in screen space.
export default ({ config, device, timeBuffer }) => {
export default ({ config, device, cache, timeBuffer }) => {
const linearSampler = device.createSampler({
magFilter: "linear",
minFilter: "linear",
@@ -86,7 +86,7 @@ export default ({ config, device, timeBuffer }) => {
let output;
let screenSize;
const assets = [loadShader(device, "shaders/wgsl/palettePass.wgsl")];
const assets = [loadShader(device, cache, "shaders/wgsl/palettePass.wgsl")];
const loaded = (async () => {
const [paletteShader] = await Promise.all(assets);

View File

@@ -39,7 +39,7 @@ export default ({ config, glMatrix, cache, device, timeBuffer }) => {
loadTexture(device, cache, config.glintMSDFURL),
loadTexture(device, cache, config.baseTextureURL, false, true),
loadTexture(device, cache, config.glintTextureURL, false, true),
loadShader(device, "shaders/wgsl/rainPass.wgsl"),
loadShader(device, cache, "shaders/wgsl/rainPass.wgsl"),
];
// The volumetric mode multiplies the number of columns

View File

@@ -43,7 +43,7 @@ const numVerticesPerQuad = 2 * 3;
// won't persist across subsequent frames. This is a safe trick
// in screen space.
export default ({ config, device, timeBuffer }) => {
export default ({ config, device, cache, timeBuffer }) => {
// Expand and convert stripe colors into 1D texture data
const stripeColors =
"stripeColors" in config
@@ -68,7 +68,7 @@ export default ({ config, device, timeBuffer }) => {
let output;
let screenSize;
const assets = [loadShader(device, "shaders/wgsl/stripePass.wgsl")];
const assets = [loadShader(device, cache, "shaders/wgsl/stripePass.wgsl")];
const loaded = (async () => {
const [stripeShader] = await Promise.all(assets);

View File

@@ -62,7 +62,11 @@ const makeComputeTarget = (device, size, mipLevelCount = 1) =>
GPUTextureUsage.STORAGE_BINDING,
});
const loadShader = async (device, url) => {
const loadShader = async (device, cache, url) => {
const key = url;
if (cache.has(key)) {
return cache.get(key);
}
const response = await fetch(url);
const code = await response.text();
return {