GuideView source ↗
Optimize a pass
Optimize one pass by first deciding what changes every frame.
0. Measure first
Attach a timer(gpu) span (requires init({ requiredFeatures: ["timestamp-query"] })) and judge every change by the reported GPU milliseconds:
TypeScript
1
2
3
const timer = timer(gpu);
timer.onResults((spans) => console.log(`pass ${spans.pass}ms`));
frameLoop(gpu, (f) => f.pass({ target, timer: timer.span("pass") }, (p) => p.draw(effect)));1. Static commands
If the draw list is static, record it once:
TypeScript
1
2
3
4
5
const effectBundle = bundle(gpu, { target }, (b) => {
b.draw(background);
b.draw(grid);
});
frameLoop(gpu, (f) => f.pass(target, (p) => p.bundles(effectBundle)));2. Animated scalar/vector values
Keep the pass object and write values in place:
TypeScript
1
2
3
4
5
6
const effect = effect(gpu, WGSL, { set: { time: 0, exposure: 1 } });
const time = clock(gpu);
frameLoop(gpu, (f) => {
effect.set({ time: time.time });
f.pass(target, effect);
});3. Resources that swap
Use ping-pong rather than allocating a new target or storage buffer:
TypeScript
1
2
3
4
5
6
const state = pingPong(gpu, 512, 512, { format: "rgba16float" });
frameLoop(gpu, (f) => {
step.set({ src: state.read.color });
f.pass(state.write, step);
state.swap();
});4. Many objects
Use instancing for many copies of the same draw, or use UniformPool plus draw.group() when every object needs a different uniform block.