Optimize viewer shaders and camera controls; sample GPU profiles asynchronously

Amp-Thread-ID: https://ampcode.com/threads/T-01a0b382-1e79-712b-abd1-d29201c9bb5e
Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
Amp
2026-09-18 11:52:09 +00:00
co-authored by heaust
parent bc957cf40d
commit eb8aa0e9dc
21 changed files with 762 additions and 174 deletions
+62 -2
View File
@@ -292,7 +292,31 @@ test("Node, ArcRotateCamera, and light handles update their shared rows", async
assert.equal(scene.array("pointLights").row(light.id)[6], 3);
});
test("ArcRotateCamera pans one projected world pixel per pointer pixel", async () => {
test("ArcRotateCamera damps pan, orbit and zoom with reversed vertical orbit", async (t) => {
let now = 0;
let next = 1;
const frames = new Map<number, FrameRequestCallback>();
const originalRequest = globalThis.requestAnimationFrame;
const originalCancel = globalThis.cancelAnimationFrame;
t.mock.method(performance, "now", () => now);
globalThis.requestAnimationFrame = (callback) => {
const id = next++;
frames.set(id, callback);
return id;
};
globalThis.cancelAnimationFrame = (id) => {
frames.delete(id);
};
t.after(() => {
globalThis.requestAnimationFrame = originalRequest;
globalThis.cancelAnimationFrame = originalCancel;
});
const advance = (ms: number) => {
now += ms;
const callbacks = [...frames.values()];
frames.clear();
for (const callback of callbacks) callback(now);
};
const listeners = new Map<string, Set<(event: any) => void>>();
const element = {
clientWidth: 400,
@@ -329,7 +353,43 @@ test("ArcRotateCamera pans one projected world pixel per pointer pixel", async (
pointerId: 1,
});
dispatch("pointermove", { clientX: 120, clientY: 110 });
dispatch("pointerup", {});
advance(80);
close(camera.position, [-2 * (1 - Math.exp(-1)), 1 - Math.exp(-1), 10]);
advance(1600);
close(camera.position, [-2, 1, 10]);
advance(16);
assert.equal(frames.size, 0);
const orbit = () => {
dispatch("pointerdown", {
button: 0,
clientX: 100,
clientY: 100,
pointerId: 1,
});
dispatch("pointermove", { clientX: 140, clientY: 120 });
dispatch("pointerup", {});
};
orbit();
advance(40);
const released = camera.alpha;
advance(40);
assert.ok(camera.alpha < released);
const pose = [camera.alpha, camera.beta];
close(pose, [
-0.2 * (1 - Math.exp(-1)),
Math.PI / 2 - 0.1 * (1 - Math.exp(-1)),
]);
camera.detachControls();
camera.alpha = 0;
camera.beta = Math.PI / 2;
camera.attachControls({ element });
orbit();
advance(80);
close([camera.alpha, camera.beta], pose);
dispatch("wheel", { deltaY: 100 });
advance(80);
close([camera.radius], [10 * Math.exp(0.1 * (1 - Math.exp(-1)))]);
camera.detachControls();
assert.equal(frames.size, 0);
});