The lattice stores its turn angle in history.create(root, d.f32, { usage: 'uniform' }).
TAA’s motion output runs the vertex code again with previously to read last frame’s angle.
Switch to a plain uniform to make both runs read the current angle. The motion view then shows
only camera motion. TAA samples last frame’s colour at the wrong positions, and the beams dim as
they turn. Raise the speed to see the effect.
Motion vectors and reprojection need last frame’s camera and object positions. Maintaining separate shader functions for current and previous state risks differences between them.
history.previously(fn) compiles fn a second time. In that copy, accessors filled with history.temporal(current, previous) read previous. history.create stores last frame’s buffer state for that fill. The kit’s cameras store their own previous views, and a table or a set of instances created with history: true keeps its own rows. Passes use previously to compute last frame’s vertex for outputs such as motion.
Creates buffers for the current and previous state. write queues values until advance
records copies into the frame encoder. This preserves the previous state, because CPU writes
reach the queue before submitted commands.
@param ― schema the state, such as d.arrayOf(Transform, 256)
Fills an accessor with current, or previous in code compiled with previously. Storage
binds read-only in render pipelines and read-write in compute pipelines. This fill also works
with mutable accessors that kernels write through.
Runs the loop on each scheduled frame. Time advances by at most maxDt per frame, never steps
back, and stops while the surface is paused. Destroying the animation keeps the loop alive.
Another animation on the same loop continues from its recorded time. A frame error stops the
animation.
@param ― loop the loop to run on each unpaused frame. Continues from its seconds if it ran before
@returns ― an animation you destroy to stop the frames
Copies the current state to previous, then applies pending writes. Call once per frame
before passes and kernels that read or update the state. A write without a following advance
never becomes current, and a frame that does not submit leaves it for the next.
advance(
frame:frames.Frame
frame);
const
constpass:TgpuComputePass
pass=
frame:frames.Frame
frame.
Frame.encoder: TgpuCommandEncoder
Records commands for submission after the recorder returns. submit() replaces this encoder.
Read it at each call instead of keeping it, and let the frame submit it.
history.epoch is a slot, 'current' or 'previous', and previously resolves its function with 'previous'. Call what it returns from any 'use gpu' function, in any stage.
history.temporal(current, previous) fills an accessor with any values it accepts. You can use two uniforms, two buffers, or a current constant and a previous uniform.
Code that never calls a previously function binds current only.
history.create(root, schema, options) owns three buffers, for current state, previous state and the next write.
reading fills a state accessor. The default storage usage binds read-only in render pipelines and read-write in compute pipelines. It can fill a mutable accessor for kernels that update the state. usage: 'uniform' suits small state written by the CPU.
write(value) holds a value for the next advance. A queue write lands before everything the frame submits, so a write straight into current would be copied aside as last frame’s too.
advance(frame) copies current to previous, then the held write into current. Call it once a frame, before what reads or moves the state. A write that no advance follows never shows. A frame that does not submit, such as one that throws, leaves the write for the next.
current and previous are the buffers, for readback and copies.
destroy(), or [Symbol.dispose], destroys the three buffers.
write
Choose write on click, then write a frame index t. Both versions copy current to previous, but direct writes arrive before the copy and erase motion; history preserves it for the written frame.
Store state that moves a drawing, such as the lattice’s turn angle, in a history. Read it through a vertex-code accessor filled with reading by the drawing. Outputs that compute last frame’s vertex then include the object’s motion:
import{
import history
history}from'@typegpu/kit';
// How far the triangle has turned, now and last frame
Creates buffers for the current and previous state. write queues values until advance
records copies into the frame encoder. This preserves the previous state, because CPU writes
reach the queue before submitted commands.
@param ― schema the state, such as d.arrayOf(Transform, 256)
@returns ― a history you destroy
create(
constroot:TgpuRoot
root,
import d
d.
constf32:d.F32
export f32
A schema that represents a 32-bit float value. (equivalent to f32 in WGSL)
Can also be called to cast a value to an f32.
@exampleconst value = f32(); // 0
@exampleconst value = f32(1.23); // 1.23
@exampleconst value = f32(true); // 1
f32,{
Options<F32,"uniform">.usage?:"uniform"|undefined
Selects the buffer usage. Use uniform for small CPU-written state, such as a clock, or
storage for arrays that kernels can also update. Default storage.
Builds a pipeline for drawing that writes every described output and returns its draw
methods. If the drawing cannot supply the fields an output needs, type checking fails with
that output's name. Use without to leave it out or instead to replace it.
Fills an accessor with current, or previous in code compiled with previously. Storage
binds read-only in render pipelines and read-write in compute pipelines. This fill also works
with mutable accessors that kernels write through.
Records a draw into the pass, on which the description has set the pipeline it built. That
pipeline binds indices if supplied. drawIndexed throws without an index buffer. A group
the drawing sets with pass.setBindGroup stays for later drawings in the pass that read its
layout, so give such a layout to one drawing.
Copies the current state to previous, then applies pending writes. Call once per frame
before passes and kernels that read or update the state. A write without a following advance
never becomes current, and a frame that does not submit leaves it for the next.
advance(
constframe:Frame
frame);
Filled with a plain uniform, last frame’s code reads this frame’s turn, and the motion output sees only the camera move.