Provides the current linear-colour picture, drawn through jitter: a function returning a texture, such as () => screen.textures.hdr, or a rendered picture.
motion?
() => FloatTexture= none, which moves every pixel as camera moves depth, or keeps it in place without both
Returns the motion texture written by motion.
depth?
() => Depth= none, which uses motion at each pixel
Returns sampled scene depth without stencil.
camera?
CameraBase= none
Supplies the scene camera with its preceding view, such as cameras.orbit.
region?
SizeSource= the region of a rendered source, else the whole texture
Selects the source region from its top-left corner, such as regions.hdr when drawing below full resolution.
settings?
Partial<d.InferInput<typeof Settings>>= defaults, with blend 0.1 and spread 1
Sets initial values over defaults.
records
record→encoder
record after the passes that draw the source and the motion, before what reads output.
owns
targets ·4 buffers ·a sampler ·a pipeline ·2 or 3 bind groups
Two histories, each frame written into one from the other, the settings, the region and whether to blend, the jitter and its sequence, a group each for the frames that read either history with the source and motion, and one for depth.
allocates
on resize
Targets for the new size and the bind groups of its passes; so does a new source, motion or depth.
Hold the pointer over distant beams and turn TAA off. The loupe shows thin beams stepping and shimmering as they turn.
With one sample per pixel, angled edges form steps, and thin lines shimmer as they move. MSAA takes multiple samples in each drawing pass, and FXAA smooths the finished picture. TAA distributes samples across frames. Each frame offsets the scene by a fraction of a pixel. The resolve blends it with the previous image using motion to find each surface’s previous position. Every scene pass must jitter, and drawings that move must write motion. Use pass descriptions for those passes:
Creates render targets that follow a size. Replaces the whole set when the size changes. Put
targets needed only sometimes in their own set and create that set when needed. Throws for
transient targets with sampling, storage or mip levels, for multisampled targets with storage or
mip levels, and for layered targets that are multisampled, mipped or have more layers than the
device allows.
@param ― source the size it follows, such as a surface
@param ― specs a format and options per target, by name
@param ― options.resolution the fraction of each side drawn, which changes without allocating
@returns ― a set of targets you fit every frame and destroy
Creates temporal antialiasing from subpixel-jittered frames. The resolve blends each frame
with history sampled where motion, or depth and camera movement, place the preceding pixel.
Without either, it samples history at the same pixel. It clamps history colour to
the local colour spread to reduce trails and weights by brightness to reduce bright-pixel
flicker. Record its single pass after scene passes and before the final pass reads output.
@allocates ― on resize: targets for the new size and the bind groups of its passes; so does a new
source, motion or depth
@owns ― targets, 4 buffers, a sampler, a pipeline, 2 or 3 bind groups: two histories, each frame
written into one from the other, the settings, the region and whether to blend, the jitter and
its sequence, a group each for the frames that read either history with the source and
motion, and one for depth
@binds ― 1 uniform: jitter, this frame's offset
@records ― record after the passes that draw the source and the motion, before what reads
output.
@param ― options.source this frame's picture, drawn through jitter, read at every record
@param ― options.motion how far each pixel's surface moved since last frame, read at every
record; without it, pixels move only with the camera
@param ― options.depth the scene's depth, for the motion of the nearest surface around each pixel
and for motion from the camera
@returns ― a resolve you record every frame and destroy
Provides the current linear-colour picture, drawn through jitter: a function returning a
texture, such as () => screen.textures.hdr, or a rendered picture. record reads it on
every call.
Returns the motion texture written by motion. Each vector is the preceding UV position
minus the current UV position. record reads it on every call. Default none, which moves
every pixel as camera moves depth, or keeps it in place without both.
Provides the current textures. A size change replaces them. Throws after destroy.
textures.
motion:targets.Texture<{
readonly format:"rg16float";
readonly sampled:true;
}>
motion,
Options.depth?:(()=>targets.Depth)|undefined
Returns sampled scene depth without stencil. Motion then follows the nearest surrounding
surface to avoid smearing moving edges over the background. record reads it on every call.
Unused without motion or camera. Default none, which uses motion at each pixel.
Provides the current textures. A size change replaces them. Throws after destroy.
textures.
depth:targets.Texture<{
readonly format:"depth24plus";
readonly sampled:true;
}>
depth,
Options.camera?:cameras.CameraBase|undefined
Supplies the scene camera with its preceding view, such as cameras.orbit. With depth,
pixels without renderer-written motion reconstruct motion from depth and camera movement.
Without both, these pixels stay in place. Default none.
Describes the targets and outputs for scene passes. With a surface such as the canvas, writes
only each renderer's colour. With a target set, writes colour into the target marked color,
depth into the target marked depth, and other outputs into their named targets. Multisampled
targets resolve according to resolve. Targets with layers draw one pass per layer, and every
target the description draws into needs the same layers. add builds a renderer's drawing.
begin starts a pass. pipe supplies fills such as a camera.
@param ― screen the surface, or the targets, which give the formats; each one the description
names is drawn into
@param ― writes what fills each target, by its key in screen
@returns ― a description you destroy, which holds the pipelines it builds
create(
constroot:TgpuRoot
root,
constscreen:targets.Targets<{
readonly hdr:{
readonly format:"rgba16float";
readonly sampled:true;
};
readonly motion:{
readonly format:"rg16float";
readonly sampled:true;
};
readonly depth:{
readonly format:"depth24plus";
readonly sampled:true;
};
}>
screen,
{
hdr:typeofpasses.color
hdr:
import passes
passes.
constcolor:typeofpasses.color
Marks the target that receives each renderer's colour.
color,
motion:passes.Output<unknown,{
position:d.v4f;
}>
motion:
import taa
taa.
constmotion:passes.Output<unknown,{
position:d.v4f;
}>
This output writes surface motion into an rg16float target. It stores preceding UV position
minus current UV position. It computes the preceding position by compiling renderer vertex
code with history.previously, which reads the preceding camera and values of other
temporal fills.
motion,
depth:typeofpasses.depth
depth:
import passes
passes.
constdepth:typeofpasses.depth
Marks the depth target.
depth},
{
Options.jitter?: Position |undefined
Moves clip positions for rasterisation in a 'use gpu' function. Outputs read the original
vertex positions. Use for a sub-pixel offset in temporal antialiasing. Default none.
jitter:
constaa:taa.Taa
aa.
Taa.jitter: (position:d.v4f)=>d.v4f
Offsets vertices by a different fraction of a pixel each frame so frames sample the whole
pixel together. Supply this as jitter in passes.create.
Adds fill after existing fills and returns a description of the same passes. Piped fills
take precedence over a drawing's own. For example, passes.create(…).pipe(view.inject()) uses
the camera from view.
pipe(
constview:cameras.OrbitCamera
view.
CameraBase.inject(): Inject
Fills cameras.current for the pipelines created from the configuration it is piped into.
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.
Creates the final pass of a frame. It reads the source, adds glow, tone maps, grades, applies
the vignette, encodes and dithers. It draws one triangle into the caller pass.
@allocates ― on resize: a bind group for a new source or glow
@owns ― 2 buffers, a sampler, a pipeline, 2 bind groups: the settings, the regions it reads, and a
group each for the source and the glow
@records ― record into a pass of its own on the view you give, usually the canvas's, or draw
into the caller's pass, after the bloom's record.
@param ― options.source the picture, rendered or a texture, read at every draw
@param ― options.region the part of the source that holds the picture, read at every draw
@param ― options.glow a bloom, or a glow of your own, added before tone mapping
@param ― options.exposure an adapted exposure, read on the GPU
@returns ― a final pass you draw every frame and destroy
create(
constroot:TgpuRoot
root,{
Options.format: GPUTextureFormat
Sets the output format, such as the canvas format.
Provides the picture at any size: a rendered picture, such as aa or blur, or a function
returning a texture, such as () => screen.textures.hdr. draw reads it on every call, so
the texture can be rebuilt.
Rebuilds all textures if the source size changed, destroying the old textures. Updates
regions for the current resolution. Returns true after a rebuild so callers can update bind
groups that hold old textures. Call before recording passes that use the targets. Throws after
destroy.
Begins a pass, draws drawn or each drawing in a list in order, then ends the pass. Reuse the
list to avoid allocating each frame. Call begin yourself when you need to choose drawings
per frame. Records nothing while enabled is false.
Records the resolve after source and motion passes, then sets jitter for the next frame.
Records nothing while disabled. Optional timer writes measure the resolve.
Opens a pass on view, such as surface.view(frame), draws into it and ends it. A
viewport draws the picture into that rectangle and clears the rest, transparent with
alpha: 'premultiplied' and black otherwise. Optional timer writes measure the pass.
record(
constframe:Frame
frame,
constsurface:web.Surface
surface.
Surface.view(frame: Frame): GPUTextureView
Returns a view of the current canvas texture, created once per texture. Applies pending size
changes first, which a pass using context would skip.
view(
constframe:Frame
frame));
taa.motion writes each surface’s movement since the previous frame in UV coordinates. It reruns vertex code with history.previously to read the previous camera and other temporal fills.
All renderers include camera motion. Object motion requires vertex code to read temporal state. Particles use velocity, and the lattice stores its turn in a history. Skinned poses keep last frame’s joints, so posed joints show their own motion. By default, instances, trails and text include only camera motion. A set of instances or a table created with history: true gives each row that moves its own motion, whether write or a kernel moved it.
Renderers with stationary vertices, such as a full-screen sky, use scene.without('motion'). See Passes for their outputs.
Unwritten motion pixels retain the taa.motion clear value, and taa.written(motion) is false for them in a shader of yours. With camera and depth, the resolve reconstructs surface position from depth and applies camera motion. Otherwise those pixels stay fixed.
Omit motion when no drawing’s vertices move, as in the ray-marched jelly slider. The resolve then binds no motion texture, and the scene writes no motion target. With camera and depth, every pixel follows the camera. Without them, history stays at each pixel, which suits a still camera.
Jitter cycles through 8 subpixel offsets. GPU copies advance it after each resolve without per-frame CPU writes. aa.offset holds the current clip-space offset for custom jitter shaders.
The resolve clamps previous colour within spread standard deviations of nearby current colours. It takes blend of the current frame and downweights bright values in both frames. With depth, each pixel uses motion from the nearest surrounding surface.
Call reset() after a camera cut. Resizing, region changes and enable(true) also reset history. After enable(false), jitter is zero, record records nothing and output is the source, so keep calling record and keep aa as the next pass’s source.
Give bloom source: aa to bloom the antialiased picture. Every post-processing source takes aa and reads its output and region at each call, because output alternates between two textures.
record takes the frame or an encoder. record(frame, { timestampWrites }) times the resolve under a profiler timer.