Skip to content

@typegpu/kitfxaa

FXAA

Smooth stepped edges in the finished picture with one full-screen pass.

kit.fxaa

module

fxaa.create(root, { format, source, region?, … }) → Fxaa

rootborrows
the root
sourcetakes
the picture as the screen shows it, read at every draw
region?takes
the part of the source that holds the picture, read at every draw
Fxaareturns
a pass you draw every frame and destroy
schemas
Settings
constants
defaults
types
Fxaa
Optionscreate · 4 fields
format

GPUTextureFormat

Sets the output format, such as the canvas format.

source

(() => FloatTexture) | Rendered

Provides an encoded picture in display range, such as an rgba8unorm target drawn by the final pass, as a function returning the texture or a rendered picture.

region?

SizeSource= the region of a rendered source, else the whole texture

Selects the source region from its top-left corner, such as regions.ldr when drawing below full resolution.

settings?

Partial<d.InferInput<typeof Settings>>= defaults, with edge 0.166, floor 0.0833 and subpixel 0.75

Sets initial values over defaults.

records
  • drawrender
  • recordencoder

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 pass that drew the source.

owns

2 buffers ·a sampler ·a pipeline ·a bind group

The settings, the region it reads and the source's group.

allocates

on resize

A bind group for a new source.

lifecycle

initAsync()destroy()[Symbol.dispose]

raymarchBalls melting into a cube, a distance field marched per pixel, its edges smoothed with FXAA.
Hold the pointer over an edge against the floor and toggle FXAA. The loupe shows stepped edges on the raymarched balls and cube, then the smoothed pixels.

With one sample per pixel, angled edges form steps. MSAA takes multiple samples in each drawing pass, and TAA gathers samples over several frames. FXAA 3.11 by Timothy Lottes smooths the finished image in one full-screen pass, using nearby colours to detect edges. Draw the final pass into an rgba8unorm target, then draw it to the screen with FXAA:

import {
import fxaa
fxaa
,
import finish
finish
} from '@typegpu/kit';
const
const screen: targets.Targets<{
readonly hdr: {
readonly format: "rgba16float";
readonly sampled: true;
};
readonly ldr: {
readonly format: "rgba8unorm";
readonly sampled: true;
};
}>
screen
=
import targets
targets
.
function create<{
readonly hdr: {
readonly format: "rgba16float";
readonly sampled: true;
};
readonly ldr: {
readonly format: "rgba8unorm";
readonly sampled: true;
};
}>(root: TgpuRoot, source: targets.SizeSource, specs: {
readonly hdr: {
readonly format: "rgba16float";
readonly sampled: true;
};
readonly ldr: {
readonly format: "rgba8unorm";
readonly sampled: true;
};
}, options?: targets.Options): targets.Targets<{
readonly hdr: {
readonly format: "rgba16float";
readonly sampled: true;
};
readonly ldr: {
readonly format: "rgba8unorm";
readonly sampled: true;
};
}>

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

create
(
const root: TgpuRoot
root
,
const surface: web.Surface
surface
, {
hdr: {
readonly format: "rgba16float";
readonly sampled: true;
}
hdr
: {
format: "rgba16float"
format
: 'rgba16float',
sampled: true
sampled
: true },
ldr: {
readonly format: "rgba8unorm";
readonly sampled: true;
}
ldr
: {
format: "rgba8unorm"
format
: 'rgba8unorm',
sampled: true
sampled
: true },
});
const
const final: finish.Finish
final
=
import finish
finish
.
function create(root: TgpuRoot, options: finish.Options): finish.Finish

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
(
const root: TgpuRoot
root
, {
Options.format: GPUTextureFormat

Sets the output format, such as the canvas format.

format
: 'rgba8unorm',
Options.source: (() => finish.FloatTexture) | finish.Rendered

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.

source
: () =>
const screen: targets.Targets<{
readonly hdr: {
readonly format: "rgba16float";
readonly sampled: true;
};
readonly ldr: {
readonly format: "rgba8unorm";
readonly sampled: true;
};
}>
screen
.
Targets<{ readonly hdr: { readonly format: "rgba16float"; readonly sampled: true; }; readonly ldr: { readonly format: "rgba8unorm"; readonly sampled: true; }; }>.textures: {
readonly hdr: targets.Texture<{
readonly format: "rgba16float";
readonly sampled: true;
}>;
readonly ldr: targets.Texture<{
readonly format: "rgba8unorm";
readonly sampled: true;
}>;
}

Provides the current textures. A size change replaces them. Throws after destroy.

textures
.
hdr: targets.Texture<{
readonly format: "rgba16float";
readonly sampled: true;
}>
hdr
});
const
const smooth: fxaa.Fxaa
smooth
=
import fxaa
fxaa
.
function create(root: TgpuRoot, options: fxaa.Options): fxaa.Fxaa

Creates an FXAA 3.11 pass at the default quality. It smooths edges after the source is in display range. Each pixel follows its edge in both directions to estimate its length, then samples across the edge. It draws one triangle into the caller pass.

@allocates ― on resize: a bind group for a new source

@owns ― 2 buffers, a sampler, a pipeline, a bind group: the settings, the region it reads and the source's group

@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 pass that drew the source.

@param ― options.source the picture as the screen shows it, read at every draw

@param ― options.region the part of the source that holds the picture, read at every draw

@returns ― a pass you draw every frame and destroy

create
(
const root: TgpuRoot
root
, {
Options.format: GPUTextureFormat

Sets the output format, such as the canvas format.

format
:
const surface: web.Surface
surface
.
Surface.format: GPUTextureFormat
format
,
Options.source: finish.Rendered | (() => finish.FloatTexture)

Provides an encoded picture in display range, such as an rgba8unorm target drawn by the final pass, as a function returning the texture or a rendered picture. draw reads it on every call and throws for -srgb formats, which decode on sampling.

source
: () =>
const screen: targets.Targets<{
readonly hdr: {
readonly format: "rgba16float";
readonly sampled: true;
};
readonly ldr: {
readonly format: "rgba8unorm";
readonly sampled: true;
};
}>
screen
.
Targets<{ readonly hdr: { readonly format: "rgba16float"; readonly sampled: true; }; readonly ldr: { readonly format: "rgba8unorm"; readonly sampled: true; }; }>.textures: {
readonly hdr: targets.Texture<{
readonly format: "rgba16float";
readonly sampled: true;
}>;
readonly ldr: targets.Texture<{
readonly format: "rgba8unorm";
readonly sampled: true;
}>;
}

Provides the current textures. A size change replaces them. Throws after destroy.

textures
.
ldr: targets.Texture<{
readonly format: "rgba8unorm";
readonly sampled: true;
}>
ldr
});
// After the scene each frame
const final: finish.Finish
final
.
Finish.record(target: Frame | TgpuCommandEncoder, view: GPUTextureView, options?: finish.RecordOptions): void

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
(
const frame: Frame
frame
,
const screen: targets.Targets<{
readonly hdr: {
readonly format: "rgba16float";
readonly sampled: true;
};
readonly ldr: {
readonly format: "rgba8unorm";
readonly sampled: true;
};
}>
screen
.
Targets<{ readonly hdr: { readonly format: "rgba16float"; readonly sampled: true; }; readonly ldr: { readonly format: "rgba8unorm"; readonly sampled: true; }; }>.views: {
readonly hdr: GPUTextureView;
readonly ldr: GPUTextureView;
}

Provides attachment views of mip 0, created once per rebuild. Throws after destroy.

views
.
ldr: GPUTextureView
ldr
);
const smooth: fxaa.Fxaa
smooth
.
Fxaa.record(target: Frame | TgpuCommandEncoder, view: GPUTextureView, options?: Timed): void

Opens a pass on view, such as surface.view(frame), draws into it and ends it. Optional timer writes measure the pass.

record
(
const frame: Frame
frame
,
const surface: 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
(
const frame: Frame
frame
));
  • record(frame, view) opens a pass on view, draws and ends it, and also takes an encoder in place of the frame. smooth.draw(pass) draws into a pass you opened.
  • FXAA detects brightness edges in display-range colour. An -srgb source would decode while sampling, so it throws. An -srgb output is supported.
  • A rendered picture brings its region. Give region yourself only with a function source drawn below full resolution, such as screen.regions.ldr. FXAA follows edges in source pixels and stretches the region over the output.
  • FXAA also smooths texture edges such as checkerboards and can blur text. Draw the HUD after smooth.draw in the same pass.

smooth.settings is a uniform. Use TypeGPU’s patch when settings change, as the final pass does. Raise edge and floor to preserve fine texture edges: they set the least contrast FXAA smooths. Set subpixel to 0 to keep details smaller than a pixel sharp.

  • FXAA uses the default FXAA 3.11 edge-search quality. It is not configurable.