Skip to content

Commit f65f635

Browse files
docs: Cleanup examples (#2265)
1 parent fee2131 commit f65f635

29 files changed

Lines changed: 116 additions & 314 deletions

File tree

apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,9 @@ function resetDrawing() {
208208
}
209209
}
210210

211-
let disposed = false;
211+
let animationFrameId: number;
212212

213213
function run() {
214-
if (disposed) {
215-
return;
216-
}
217-
218214
const scale = canvas.width / SIZE;
219215

220216
context.clearRect(0, 0, canvas.width, canvas.height);
@@ -244,7 +240,7 @@ function run() {
244240
context.fillStyle = '#000';
245241
context.fillText('draw here 🖌️', canvas.width / 2, canvas.height / 2);
246242
}
247-
requestAnimationFrame(run);
243+
animationFrameId = requestAnimationFrame(run);
248244
}
249245

250246
document.querySelector('.loading')?.classList.add('loaded');
@@ -397,7 +393,7 @@ export const controls = defineControls({
397393
});
398394

399395
export function onCleanup() {
400-
disposed = true;
396+
cancelAnimationFrame(animationFrameId);
401397
window.removeEventListener('mouseup', mouseUpEventListener);
402398
window.removeEventListener('touchend', touchEndEventListener);
403399
root.destroy();

apps/typegpu-docs/src/examples/rendering/3d-fish/index.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ function enqueuePresetChanges() {
7878
fishBehaviorBuffer.write(presets.init);
7979

8080
setTimeout(() => {
81-
if (disposed) return;
8281
fishBehaviorBuffer.write(presets.default);
8382
spinnerBackground.style.display = 'none';
8483
speedMultiplier = 1;
@@ -222,12 +221,9 @@ const computeBindGroups = [0, 1].map((idx) =>
222221

223222
let odd = false;
224223
let lastTimestamp: DOMHighResTimeStamp = 0;
225-
let disposed = false;
224+
let animationFrameId: number;
226225

227226
function frame(timestamp: DOMHighResTimeStamp) {
228-
if (disposed) {
229-
return;
230-
}
231227
odd = !odd;
232228

233229
currentTimeBuffer.write(timestamp);
@@ -270,10 +266,10 @@ function frame(timestamp: DOMHighResTimeStamp) {
270266
.with(renderFishBindGroups[odd ? 1 : 0])
271267
.draw(fishModel.polygonCount, p.fishAmount);
272268

273-
requestAnimationFrame(frame);
269+
animationFrameId = requestAnimationFrame(frame);
274270
}
275271
enqueuePresetChanges();
276-
requestAnimationFrame(frame);
272+
animationFrameId = requestAnimationFrame(frame);
277273

278274
// #region Example controls and cleanup
279275

@@ -442,7 +438,7 @@ const resizeObserver = new ResizeObserver(() => {
442438
resizeObserver.observe(canvas);
443439

444440
export function onCleanup() {
445-
disposed = true;
441+
cancelAnimationFrame(animationFrameId);
446442
window.removeEventListener('mouseup', mouseUpEventListener);
447443
window.removeEventListener('mousemove', mouseMoveEventListener);
448444
window.removeEventListener('touchmove', touchMoveEventListener);

apps/typegpu-docs/src/examples/rendering/box-raytracing/index.ts

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -248,24 +248,13 @@ const pipeline = root.createRenderPipeline({
248248

249249
// UI
250250

251-
let disposed = false;
251+
let animationFrameId: number;
252+
let lastTime: number | null = null;
252253

253-
const onFrame = (loop: (deltaTime: number) => unknown) => {
254-
let lastTime = Date.now();
255-
const runner = () => {
256-
if (disposed) {
257-
return;
258-
}
259-
const now = Date.now();
260-
const dt = now - lastTime;
261-
lastTime = now;
262-
loop(dt);
263-
requestAnimationFrame(runner);
264-
};
265-
requestAnimationFrame(runner);
266-
};
254+
const runner = (timestamp: number) => {
255+
const deltaTime = lastTime !== null ? timestamp - lastTime : 0;
256+
lastTime = timestamp;
267257

268-
onFrame((deltaTime) => {
269258
const width = canvas.width;
270259
const height = canvas.height;
271260

@@ -283,7 +272,9 @@ onFrame((deltaTime) => {
283272
frame += (rotationSpeed * deltaTime) / 1000;
284273

285274
pipeline.withColorAttachment({ view: context }).draw(3);
286-
});
275+
animationFrameId = requestAnimationFrame(runner);
276+
};
277+
animationFrameId = requestAnimationFrame(runner);
287278

288279
// #region Example controls and cleanup
289280

@@ -330,7 +321,7 @@ export const controls = defineControls({
330321
});
331322

332323
export function onCleanup() {
333-
disposed = true;
324+
cancelAnimationFrame(animationFrameId);
334325
root.destroy();
335326
}
336327

apps/typegpu-docs/src/examples/rendering/clouds/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ resizeObserver.observe(canvas);
9393

9494
let frameId: number;
9595

96-
function render() {
97-
paramsUniform.writePartial({ time: (performance.now() / 1000) % 500 });
96+
function render(timestamp: number) {
97+
paramsUniform.writePartial({ time: (timestamp / 1000) % 500 });
9898

9999
pipeline
100100
.with(bindGroup)

apps/typegpu-docs/src/examples/rendering/disco/index.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@ const pipelines = fragmentShaders.map((fragment) =>
3939

4040
let currentPipeline = pipelines[0];
4141

42-
let startTime = performance.now();
42+
let startTime: null | number = null;
4343
let frameId: number;
4444

45-
function render() {
46-
const timestamp = (performance.now() - startTime) / 1000;
47-
if (timestamp > 500.0) startTime = performance.now();
48-
time.write(timestamp);
45+
function render(timestamp: number) {
46+
if (startTime === null) {
47+
startTime = timestamp;
48+
}
49+
time.write((timestamp - startTime) / 1000);
4950
resolutionUniform.write(d.vec2f(canvas.width, canvas.height));
5051

5152
currentPipeline

apps/typegpu-docs/src/examples/rendering/function-visualizer/index.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ const properties = Properties({
4545

4646
// Buffers
4747

48-
const propertiesUniform = root.createUniform(Properties, properties);
48+
const propertiesUniform = root.createUniform(Properties);
49+
queuePropertiesBufferUpdate();
4950

5051
// these buffers are recreated with a different size on interpolationPoints change
5152
function createLineVerticesBuffers() {
@@ -101,7 +102,7 @@ const backgroundVertex = tgpu.vertexFn({
101102
const properties = propertiesUniform.$;
102103
const leftBot = properties.transformation.mul(d.vec4f(-1, -1, 0, 1));
103104
const rightTop = properties.transformation.mul(d.vec4f(1, 1, 0, 1));
104-
const canvasRatio = (rightTop.x - leftBot.x) / (rightTop.y - leftBot.y);
105+
const aspectRatio = (rightTop.x - leftBot.x) / (rightTop.y - leftBot.y);
105106

106107
const transformedPoints = [
107108
d.vec2f(leftBot.x, 0),
@@ -111,12 +112,12 @@ const backgroundVertex = tgpu.vertexFn({
111112
];
112113

113114
const currentPoint = properties.inverseTransformation.mul(
114-
d.vec4f(transformedPoints[2 * iid + vid / 2].xy, 0, 1),
115+
d.vec4f(transformedPoints[2 * iid + d.u32(vid / 2)].xy, 0, 1),
115116
);
116117

117118
return {
118119
pos: d.vec4f(
119-
currentPoint.x + (d.f32(iid) * std.select(d.f32(-1), 1, vid % 2 === 0) * 0.005) / canvasRatio,
120+
currentPoint.x + (d.f32(iid) * std.select(d.f32(-1), 1, vid % 2 === 0) * 0.005) / aspectRatio,
120121
currentPoint.y + d.f32(1 - iid) * std.select(d.f32(-1), 1, vid % 2 === 0) * 0.005,
121122
currentPoint.zw,
122123
),
@@ -294,6 +295,12 @@ async function tryRecreateComputePipeline(
294295
}
295296

296297
function queuePropertiesBufferUpdate() {
298+
const leftBot = properties.transformation.mul(d.vec4f(-1, -1, 0, 1));
299+
const rightTop = properties.transformation.mul(d.vec4f(1, 1, 0, 1));
300+
const currentCanvasRatio = (rightTop.x - leftBot.x) / (rightTop.y - leftBot.y);
301+
const desiredCanvasRatio = canvas.clientWidth / canvas.clientHeight;
302+
const rescaleMatrix = mat4.scaling([desiredCanvasRatio / currentCanvasRatio, 1, 1], d.mat4x4f());
303+
properties.transformation = std.mul(properties.transformation, rescaleMatrix);
297304
properties.inverseTransformation = mat4.inverse(properties.transformation, d.mat4x4f());
298305
propertiesUniform.write(properties);
299306
}
@@ -379,12 +386,7 @@ window.addEventListener('touchend', touchEndEventListener);
379386
// Resize observer and cleanup
380387

381388
const resizeObserver = new ResizeObserver(() => {
382-
const leftBot = properties.transformation.mul(d.vec4f(-1, -1, 0, 1));
383-
const rightTop = properties.transformation.mul(d.vec4f(1, 1, 0, 1));
384-
const currentCanvasRatio = (rightTop.x - leftBot.x) / (rightTop.y - leftBot.y);
385-
const desiredCanvasRatio = canvas.clientWidth / canvas.clientHeight;
386-
const rescaleMatrix = mat4.scaling([desiredCanvasRatio / currentCanvasRatio, 1, 1], d.mat4x4f());
387-
properties.transformation = std.mul(properties.transformation, rescaleMatrix);
389+
queuePropertiesBufferUpdate();
388390

389391
msTexture.destroy();
390392
msTexture = device.createTexture({

apps/typegpu-docs/src/examples/rendering/jelly-slider/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ const getFakeShadow = (position: d.v3f, lightDir: d.v3f): d.v3f => {
360360

361361
if (position.y < -GroundParams.groundThickness) {
362362
// Applying darkening under the ground (the shadow cast by the upper ground layer)
363-
const fadeSharpness = 30;
363+
const fadeSharpness = d.f32(30);
364364
const inset = 0.02;
365365
const cutout = rectangleCutoutDist(position.xz) + inset;
366366
const edgeDarkening = std.saturate(1 - cutout * fadeSharpness);
@@ -386,7 +386,7 @@ const getFakeShadow = (position: d.v3f, lightDir: d.v3f): d.v3f => {
386386

387387
const contrast = 20 * std.saturate(finalUV.y) * (0.8 + endCapX * 0.2);
388388
const shadowOffset = -0.3;
389-
const featherSharpness = 10;
389+
const featherSharpness = d.f32(10);
390390
const uvEdgeFeather =
391391
std.saturate(finalUV.x * featherSharpness) *
392392
std.saturate((1 - finalUV.x) * featherSharpness) *
@@ -714,7 +714,7 @@ const renderPipeline = root.createRenderPipeline({
714714
});
715715

716716
const eventHandler = new EventHandler(canvas);
717-
let lastTimeStamp = performance.now();
717+
let lastTimestamp: number | null = null;
718718
let frameCount = 0;
719719
const taaResolver = new TAAResolver(root, width, height);
720720

@@ -752,8 +752,8 @@ let animationFrameHandle: number;
752752
function render(timestamp: number) {
753753
frameCount++;
754754
camera.jitter();
755-
const deltaTime = Math.min((timestamp - lastTimeStamp) * 0.001, 0.1);
756-
lastTimeStamp = timestamp;
755+
const deltaTime = Math.min(lastTimestamp !== null ? (timestamp - lastTimestamp) * 0.001 : 0, 0.1);
756+
lastTimestamp = timestamp;
757757

758758
randomUniform.write(d.vec2f((Math.random() - 0.5) * 2, (Math.random() - 0.5) * 2));
759759

apps/typegpu-docs/src/examples/rendering/jelly-switch/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ const getFakeShadow = (position: d.v3f, lightDir: d.v3f): d.v3f => {
241241
'use gpu';
242242
if (position.y < -GroundParams.groundThickness) {
243243
// Applying darkening under the ground (the shadow cast by the upper ground layer)
244-
const fadeSharpness = 30;
244+
const fadeSharpness = d.f32(30);
245245
const inset = 0.02;
246246
const cutout = rectangleCutoutDist(position.xz) + inset;
247247
const edgeDarkening = std.saturate(1 - cutout * fadeSharpness);
@@ -484,7 +484,7 @@ const renderPipeline = root.createRenderPipeline({
484484
targets: { format: presentationFormat },
485485
});
486486

487-
let lastTimeStamp = performance.now();
487+
let lastTimestamp: number | null = null;
488488
let frameCount = 0;
489489
const taaResolver = new TAAResolver(root, width, height);
490490

@@ -507,8 +507,8 @@ let animationFrameHandle: number;
507507
function render(timestamp: number) {
508508
frameCount++;
509509
camera.jitter();
510-
const deltaTime = Math.min((timestamp - lastTimeStamp) * 0.001, 0.1);
511-
lastTimeStamp = timestamp;
510+
const deltaTime = Math.min(lastTimestamp !== null ? (timestamp - lastTimestamp) * 0.001 : 0, 0.1);
511+
lastTimestamp = timestamp;
512512

513513
randomUniform.write(d.vec2f((Math.random() - 0.5) * 2, (Math.random() - 0.5) * 2));
514514

apps/typegpu-docs/src/examples/rendering/point-light-shadow/index.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ const fragmentMain = tgpu.fragmentFn({
160160
const PCF_SAMPLES = shadowParams.$.pcfSamples;
161161
const diskRadius = shadowParams.$.diskRadius;
162162

163-
let visibilityAcc = 0.0;
164-
for (let i = 0; i < PCF_SAMPLES; i++) {
163+
let visibilityAcc = d.f32(0);
164+
for (let i = d.u32(0); i < PCF_SAMPLES; i++) {
165165
const o = samplesUniform.$[i].xy.mul(diskRadius);
166166

167167
const sampleDir = dir.add(right.mul(o.x)).add(realUp.mul(o.y));
@@ -352,11 +352,12 @@ const lightIndicatorBindGroup = root.createBindGroup(lightIndicatorLayout, {
352352

353353
let showDepthPreview = false;
354354
let showDistanceView = false;
355-
let lastTime = performance.now();
355+
let lastTime: number | null = null;
356356
let time = 0;
357+
let animationFrameId: number;
357358

358359
function render(timestamp: number) {
359-
const dt = (timestamp - lastTime) / 1000;
360+
const dt = lastTime !== null ? (timestamp - lastTime) / 1000 : 0;
360361
lastTime = timestamp;
361362
time += dt;
362363

@@ -376,7 +377,7 @@ function render(timestamp: number) {
376377

377378
if (showDepthPreview) {
378379
pipelinePreview.withColorAttachment({ view: context }).draw(3);
379-
requestAnimationFrame(render);
380+
animationFrameId = requestAnimationFrame(render);
380381
return;
381382
}
382383

@@ -415,9 +416,9 @@ function render(timestamp: number) {
415416
.with(vertexLayout, BoxGeometry.vertexBuffer)
416417
.drawIndexed(BoxGeometry.indexCount);
417418

418-
requestAnimationFrame(render);
419+
animationFrameId = requestAnimationFrame(render);
419420
}
420-
requestAnimationFrame(render);
421+
animationFrameId = requestAnimationFrame(render);
421422

422423
const resizeObserver = new ResizeObserver((entries) => {
423424
for (const entry of entries) {
@@ -644,6 +645,7 @@ export const controls = defineControls({
644645
});
645646

646647
export function onCleanup() {
648+
cancelAnimationFrame(animationFrameId);
647649
BoxGeometry.clearBuffers();
648650
window.removeEventListener('mouseup', mouseUpEventListener);
649651
window.removeEventListener('mousemove', mouseMoveEventListener);
1.29 MB
Loading

0 commit comments

Comments
 (0)