Detect and advise against running through SwiftShader

This commit is contained in:
Rezmason
2022-10-02 13:20:50 -07:00
parent 87bd6c1681
commit 95b67d1dad
5 changed files with 106 additions and 8 deletions

View File

@@ -45,6 +45,7 @@
- [Goals](#goals) - [Goals](#goals)
- [Sidenote: other people's Matrix effects](#sidenote-other-peoples-matrix-effects) - [Sidenote: other people's Matrix effects](#sidenote-other-peoples-matrix-effects)
- [Customization](#customization) - [Customization](#customization)
- [Troubleshooting](#troubleshooting)
- [Future directions](#future-directions) - [Future directions](#future-directions)
- [Friends of the project](#friends-of-the-project) - [Friends of the project](#friends-of-the-project)
- [Colophon](#colophon) - [Colophon](#colophon)
@@ -136,6 +137,12 @@ Now you know link fu. Here's a list of customization options:
- `loops` - (WIP) if set to "true", this causes the effect to loop, so that it can be converted into a looping video. - `loops` - (WIP) if set to "true", this causes the effect to loop, so that it can be converted into a looping video.
## Troubleshooting
There haven't been many reported issues yet that weren't quick fixes, but one has stood out: many visitors have previously *disabled hardware acceleration* in their Chrome browsers, at the advice of well-meaning Internet websites.
What this does is cause Chrome to fall back to **SwiftShader**, a software renderer that runs projects like this one at a much slower rate. Because of this, if you are seeing serious performance issues on Chrome, it's recommended that you ensure hardware acceleration is enabled in your browser settings.
## Future directions ## Future directions
This project is still in active development, but some upcoming features are worth mentioning. This project is still in active development, but some upcoming features are worth mentioning.

View File

@@ -1,5 +1,7 @@
TODO: TODO:
Replace fwidth with a uniform or something
Bloom comparison: WebGPU vs REGL Bloom comparison: WebGPU vs REGL
Why are they different? Why are they different?
Create a project that tests them side-by-side Create a project that tests them side-by-side

View File

@@ -3,26 +3,90 @@
<head> <head>
<title>Matrix digital rain</title> <title>Matrix digital rain</title>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="apple-mobile-web-app-capable" content="yes"></meta> <meta name="apple-mobile-web-app-capable" content="yes" /></meta>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"></meta> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /></meta>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover" /> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover" />
<style> <style>
@supports (padding-top: env(safe-area-inset-top)) { @supports (padding-top: env(safe-area-inset-top)) {
body { body {
padding: 0; padding: 0;
height: calc(100% + env(safe-area-inset-top)); height: calc(100% + env(safe-area-inset-top));
} }
} }
body { body {
background: black; background: black;
overflow: hidden; overflow: hidden;
margin: 0; margin: 0;
font-family: monospace;
font-size: 2em;
text-align: center;
} }
canvas { canvas {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
} }
p {
color: hsl(108, 90%, 70%);
text-shadow: hsl(108, 90%, 40%) 1px 0 10px;
}
.notice {
margin-top: 10em;
animation: fadeInAnimation ease 3s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
@keyframes fadeInAnimation {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.pill {
display: inline-block;
background: gray;
border: 0.3em solid lightgray;
font-size: 1rem;
font-family: monospace;
color: white;
padding: 0.5em 1em;
border-radius: 2em;
min-width: 6rem;
margin: 3em;
text-decoration: none;
cursor: pointer;
text-transform: uppercase;
font-weight: bold;
}
.blue {
background: linear-gradient(skyblue, blue, black, black, darkblue);
border-color: darkblue;
color: lightblue;
}
.blue:hover {
border-color: blue;
color: white;
}
.red {
background: linear-gradient(lightpink, crimson, black, black, darkred);
border-color: darkred;
color: lightpink;
}
.red:hover {
border-color: crimson;
color: white;
}
</style> </style>
</head> </head>
<body> <body>

View File

@@ -10,10 +10,35 @@ const supportsWebGPU = async () => {
return window.GPUQueue != null && navigator.gpu != null && navigator.gpu.getPreferredCanvasFormat != null; return window.GPUQueue != null && navigator.gpu != null && navigator.gpu.getPreferredCanvasFormat != null;
}; };
const isRunningSwiftShader = () => {
const gl = document.createElement("canvas").getContext("webgl");
const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
return renderer.toLowerCase().includes("swiftshader");
};
document.body.onload = async () => { document.body.onload = async () => {
const urlParams = Object.fromEntries(new URLSearchParams(window.location.search).entries()); const urlParams = Object.fromEntries(new URLSearchParams(window.location.search).entries());
const config = makeConfig(urlParams); const config = makeConfig(urlParams);
const useWebGPU = (await supportsWebGPU()) && ["webgpu"].includes(config.renderer?.toLowerCase()); const useWebGPU = (await supportsWebGPU()) && ["webgpu"].includes(config.renderer?.toLowerCase());
const solution = import(`./${useWebGPU ? "webgpu" : "regl"}/main.js`); const solution = import(`./${useWebGPU ? "webgpu" : "regl"}/main.js`);
(await solution).default(canvas, config);
if (isRunningSwiftShader()) {
const notice = document.createElement("notice");
notice.innerHTML = `<div class="notice">
<p>Wake up, Neo... you've got hardware acceleration disabled.</p>
<p>This project will still run, incredibly, but at a noticeably low framerate.</p>
<button class="blue pill">Plug me in</button>
<a class="red pill" target="_blank" href="https://www.google.com/search?q=chrome+enable+hardware+acceleration">Free me</a>
`;
canvas.style.display = "none";
document.body.appendChild(notice);
document.querySelector(".blue.pill").addEventListener("click", async () => {
(await solution).default(canvas, config);
canvas.style.display = "unset";
document.body.removeChild(notice);
});
} else {
(await solution).default(canvas, config);
}
}; };

View File

@@ -70,12 +70,12 @@ export default async (canvas, config) => {
extensions.push("OES_standard_derivatives"); extensions.push("OES_standard_derivatives");
break; break;
case "fwidth_10_1_2022_B": case "fwidth_10_1_2022_B":
optionalExtensions.forEach(ext => extensions.push(ext)); optionalExtensions.forEach((ext) => extensions.push(ext));
extensions.length = 0; extensions.length = 0;
break; break;
} }
const regl = createREGL({ canvas, extensions, optionalExtensions, }); const regl = createREGL({ canvas, extensions, optionalExtensions });
const cameraTex = regl.texture(cameraCanvas); const cameraTex = regl.texture(cameraCanvas);
const lkg = await getLKG(config.useHoloplay, true); const lkg = await getLKG(config.useHoloplay, true);