mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-14 12:29:30 -07:00
Detect and advise against running through SwiftShader
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
2
TODO.txt
2
TODO.txt
@@ -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
|
||||||
|
|||||||
74
index.html
74
index.html
@@ -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>
|
||||||
|
|||||||
27
js/main.js
27
js/main.js
@@ -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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user