Static site
Browse files- index.html +2 -2
- static/city.js +2 -2
- static/main.js +3 -2
- static/world.js +1 -1
index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
| 8 |
<meta name="theme-color" content="#10131b">
|
| 9 |
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
<link href="https://fonts.googleapis.com/css2?family=Unbounded:wght@500;800;900&family=Inter:wght@400;500;600;700&family=Noto+Kufi+Arabic:wght@700&display=swap" rel="stylesheet">
|
| 11 |
-
<link rel="stylesheet" href="/static/style.css?v=
|
| 12 |
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 64 64%27%3E%3Crect width=%2764%27 height=%2764%27 rx=%2714%27 fill=%27%23050506%27/%3E%3Ccircle cx=%2732%27 cy=%2732%27 r=%2716%27 fill=%27none%27 stroke=%27%23fff%27 stroke-width=%275%27/%3E%3C/svg%3E">
|
| 13 |
<script type="importmap">
|
| 14 |
{ "imports": {
|
|
@@ -202,6 +202,6 @@
|
|
| 202 |
<div id="toast" role="status"></div>
|
| 203 |
<noscript><p style="position:fixed;inset:auto 0 0;padding:16px;background:#111;color:#fff;text-align:center">VOID needs JavaScript for the 3D car.</p></noscript>
|
| 204 |
<script src="/static/hub.js" data-app="void" defer></script>
|
| 205 |
-
<script type="module" src="/static/main.js?v=
|
| 206 |
</body>
|
| 207 |
</html>
|
|
|
|
| 8 |
<meta name="theme-color" content="#10131b">
|
| 9 |
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
<link href="https://fonts.googleapis.com/css2?family=Unbounded:wght@500;800;900&family=Inter:wght@400;500;600;700&family=Noto+Kufi+Arabic:wght@700&display=swap" rel="stylesheet">
|
| 11 |
+
<link rel="stylesheet" href="/static/style.css?v=1792911712">
|
| 12 |
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 64 64%27%3E%3Crect width=%2764%27 height=%2764%27 rx=%2714%27 fill=%27%23050506%27/%3E%3Ccircle cx=%2732%27 cy=%2732%27 r=%2716%27 fill=%27none%27 stroke=%27%23fff%27 stroke-width=%275%27/%3E%3C/svg%3E">
|
| 13 |
<script type="importmap">
|
| 14 |
{ "imports": {
|
|
|
|
| 202 |
<div id="toast" role="status"></div>
|
| 203 |
<noscript><p style="position:fixed;inset:auto 0 0;padding:16px;background:#111;color:#fff;text-align:center">VOID needs JavaScript for the 3D car.</p></noscript>
|
| 204 |
<script src="/static/hub.js" data-app="void" defer></script>
|
| 205 |
+
<script type="module" src="/static/main.js?v=1792911712"></script>
|
| 206 |
</body>
|
| 207 |
</html>
|
static/city.js
CHANGED
|
@@ -186,9 +186,9 @@ export async function buildCity(scene, canvasTex, COARSE) {
|
|
| 186 |
}
|
| 187 |
// the bridge over the East River carries the boulevard on; roads past the edges lead to it and to the piers
|
| 188 |
roads.push({ p: [[XB, 0], [1700, 0]], w: 26 });
|
| 189 |
-
for (const [k, list] of Object.entries(markG)) if (list.length) { const t = markTex(k); t.wrapT = THREE.RepeatWrapping; scene.add(new THREE.Mesh(mergeGeometries(list), new THREE.MeshBasicMaterial({ map: t, transparent: true, depthWrite: false, color: 0xdddddd, side: THREE.DoubleSide }))); }
|
| 190 |
zebra.wrapT = THREE.RepeatWrapping;
|
| 191 |
-
scene.add(new THREE.Mesh(mergeGeometries(zebraG), new THREE.MeshBasicMaterial({ map: zebra, transparent: true, depthWrite: false, color: 0xcccccc, side: THREE.DoubleSide })));
|
| 192 |
|
| 193 |
// ---- the blocks ----
|
| 194 |
const SIGN_N = SHOPS.length;
|
|
|
|
| 186 |
}
|
| 187 |
// the bridge over the East River carries the boulevard on; roads past the edges lead to it and to the piers
|
| 188 |
roads.push({ p: [[XB, 0], [1700, 0]], w: 26 });
|
| 189 |
+
for (const [k, list] of Object.entries(markG)) if (list.length) { const t = markTex(k); t.wrapT = THREE.RepeatWrapping; scene.add(new THREE.Mesh(mergeGeometries(list), new THREE.MeshBasicMaterial({ map: t, transparent: true, depthWrite: false, color: 0xdddddd, side: THREE.DoubleSide, polygonOffset: true, polygonOffsetFactor: -2, polygonOffsetUnits: -2 }))); }
|
| 190 |
zebra.wrapT = THREE.RepeatWrapping;
|
| 191 |
+
scene.add(new THREE.Mesh(mergeGeometries(zebraG), new THREE.MeshBasicMaterial({ map: zebra, transparent: true, depthWrite: false, color: 0xcccccc, side: THREE.DoubleSide, polygonOffset: true, polygonOffsetFactor: -2, polygonOffsetUnits: -2 })));
|
| 192 |
|
| 193 |
// ---- the blocks ----
|
| 194 |
const SIGN_N = SHOPS.length;
|
static/main.js
CHANGED
|
@@ -338,7 +338,8 @@ function frameLoop(fixed) {
|
|
| 338 |
perf.t += raw; perf.n++;
|
| 339 |
if (perf.t > 1.5) {
|
| 340 |
const avg = perf.t / perf.n, was = perf.pr; fpsNow = Math.round(1 / avg); const fe = document.getElementById("gFps"); if (fe) fe.textContent = fpsNow + " fps";
|
| 341 |
-
if (avg > 1 /
|
|
|
|
| 342 |
else if (avg > 1 / 40 && mode === "play" && ++perf.down >= 3 && SET.q !== "low") { // still slow at the lowest resolution: drop a quality level
|
| 343 |
perf.down = 0; SET.q = { ultra: "high", high: "medium", medium: "low" }[SET.q]; perf.pr = W.QUALITY[SET.q].pr; applySettings(false); toast(`Graphics set to ${SET.q} to keep it smooth`);
|
| 344 |
}
|
|
@@ -476,7 +477,7 @@ function frameLoop(fixed) {
|
|
| 476 |
const c = S.cam, shake = REDUCED ? 0 : (Math.max(0, S.g - 2) * .004 + S.thrust.power * .01 + (S.shake || 0) * .25 + (S.nitro || 0) * .02) * (S.inside ? .25 : 1);
|
| 477 |
camera.position.copy(c.pos).add(new THREE.Vector3(Math.sin(time * 53) * shake, Math.sin(time * 61 + 1) * shake, Math.sin(time * 47 + 2) * shake));
|
| 478 |
camera.up.copy(c.up || new THREE.Vector3(0, 1, 0)); camera.lookAt(c.look);
|
| 479 |
-
camera.fov = fovFor(c.fov); camera.near = S.inside || S.screenOn ? .
|
| 480 |
camLight.position.copy(camera.position).add(new THREE.Vector3(0, 3, 0)); camLight.target.position.copy(S.pos);
|
| 481 |
scene.fog.far = lerp(950, 2600, smooth(20, 160, S.alt)) * W.weatherFog; scene.fog.near = lerp(120, 400, smooth(20, 160, S.alt)) * W.weatherFog;
|
| 482 |
const DET = { low: .55, medium: .8, high: 1, ultra: 1.2 }[W.quality] || 1; life.detail = DET; W.city.detail = DET;
|
|
|
|
| 338 |
perf.t += raw; perf.n++;
|
| 339 |
if (perf.t > 1.5) {
|
| 340 |
const avg = perf.t / perf.n, was = perf.pr; fpsNow = Math.round(1 / avg); const fe = document.getElementById("gFps"); if (fe) fe.textContent = fpsNow + " fps";
|
| 341 |
+
if (avg > 1 / 25 && mode === "play" && SET.q !== "low") perf.down = 3; // very slow: skip straight to a lower level
|
| 342 |
+
if (avg > 1 / 45 && perf.pr > .6 && perf.down < 3) perf.pr = Math.max(.6, perf.pr - .12);
|
| 343 |
else if (avg > 1 / 40 && mode === "play" && ++perf.down >= 3 && SET.q !== "low") { // still slow at the lowest resolution: drop a quality level
|
| 344 |
perf.down = 0; SET.q = { ultra: "high", high: "medium", medium: "low" }[SET.q]; perf.pr = W.QUALITY[SET.q].pr; applySettings(false); toast(`Graphics set to ${SET.q} to keep it smooth`);
|
| 345 |
}
|
|
|
|
| 477 |
const c = S.cam, shake = REDUCED ? 0 : (Math.max(0, S.g - 2) * .004 + S.thrust.power * .01 + (S.shake || 0) * .25 + (S.nitro || 0) * .02) * (S.inside ? .25 : 1);
|
| 478 |
camera.position.copy(c.pos).add(new THREE.Vector3(Math.sin(time * 53) * shake, Math.sin(time * 61 + 1) * shake, Math.sin(time * 47 + 2) * shake));
|
| 479 |
camera.up.copy(c.up || new THREE.Vector3(0, 1, 0)); camera.lookAt(c.look);
|
| 480 |
+
camera.fov = fovFor(c.fov); camera.near = S.inside || S.screenOn ? .06 : .35; camera.updateProjectionMatrix();
|
| 481 |
camLight.position.copy(camera.position).add(new THREE.Vector3(0, 3, 0)); camLight.target.position.copy(S.pos);
|
| 482 |
scene.fog.far = lerp(950, 2600, smooth(20, 160, S.alt)) * W.weatherFog; scene.fog.near = lerp(120, 400, smooth(20, 160, S.alt)) * W.weatherFog;
|
| 483 |
const DET = { low: .55, medium: .8, high: 1, ultra: 1.2 }[W.quality] || 1; life.detail = DET; W.city.detail = DET;
|
static/world.js
CHANGED
|
@@ -25,7 +25,7 @@ export const ZONES = [];
|
|
| 25 |
export const PAD_R = 28;
|
| 26 |
|
| 27 |
export async function createWorld(canvas, COARSE) {
|
| 28 |
-
const renderer = new THREE.WebGLRenderer({ canvas, antialias:
|
| 29 |
renderer.shadowMap.enabled = !COARSE; renderer.shadowMap.type = THREE.PCFShadowMap;
|
| 30 |
renderer.localClippingEnabled = true;
|
| 31 |
renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 1.2;
|
|
|
|
| 25 |
export const PAD_R = 28;
|
| 26 |
|
| 27 |
export async function createWorld(canvas, COARSE) {
|
| 28 |
+
const renderer = new THREE.WebGLRenderer({ canvas, antialias: false, powerPreference: "high-performance", stencil: false });
|
| 29 |
renderer.shadowMap.enabled = !COARSE; renderer.shadowMap.type = THREE.PCFShadowMap;
|
| 30 |
renderer.localClippingEnabled = true;
|
| 31 |
renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 1.2;
|