One description writes colour, motion and depth for every drawing in the scene. Switch the view to see each target the drawings filled. Drag to turn the camera.
A scene has three parts. Targets are the textures a frame draws into. A description, made with passes.create, says what each target holds. Drawings are what renderers hand over: what each vertex carries to its pixels, what a pixel looks like and the draw call. scene.add(drawing) builds the pipeline that writes every target the description lists.
The sun’s shadow is a description too, of depth alone, so a lit renderer casts its shadow from the same drawing:
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(
constroot:TgpuRoot
root,
constsurface:web.Surface
surface,{
hdr:{
readonly format:"rgba16float";
readonly sampled:true;
}
hdr:{
format:"rgba16float"
format:'rgba16float',
sampled:true
sampled:true},
depth:{
readonly format:"depth24plus";
}
depth:{
format:"depth24plus"
format:'depth24plus'},
});
const
constlight:lighting.LightingOf<{
readonly shadow:{
readonly extent:9;
};
}>
light=
import lighting
lighting.
functioncreate<{
readonly shadow:{
readonly extent:9;
};
}>(root:TgpuRoot,options?:({
readonly shadow:{
readonly extent:9;
};
}&lighting.Options&{
readonly shadow:{
readonly extent:9;
};
})|undefined):lighting.LightingOf<{
readonly shadow:{
readonly extent:9;
};
}>
Creates lighting with a sun, sky and fog. It can also read point lights from a table or a
function and cast shadows. Pipe its injection into each pipeline that uses it. Throws if
points names no source or more than one, a light function has neither count nor
candidates, a table comes with count, or candidates.ranges is anything other than a
positive integer.
@injects ― hook the shading hooks its options name: reflect, ambient, fog, sunShadow and
attenuation
@injects ― definition the sun, sky and fog, the shadows and the point lights, which shading
reads
@binds ― 1 uniform: shading.shade, the sun, sky and fog
@binds ― 2 storage, 1 uniform: shading.shade with a table of point lights
@binds ― 3 storage, 1 uniform: shading.shade with a table of lights whose positions are on the
device, the table's two parts
@binds ― 1 uniform: shading.shade with points.light or points.spot, plus what the function
binds
@binds ― 0 storage: shading.shade with points.candidates, plus what their functions bind, 2
storage for a neighbour grid's range and slot
@binds ― 1 uniform: shading.shade with a shadow, the sun's light space and cascades, beside the
depth array and its comparison sampler
@binds ― 1 uniform: shading.shade with pointShadow, each shadow's light, layers and views,
beside their depth array and the comparison sampler
@owns ― 1 to 3 buffers, a sampler, targets, a cameras.layered, passes: the sun, sky and fog; with a
shadow, its light space, the views of its cascades, a comparison sampler, the depth array and
the passes that draw it; with pointShadow, the same for the lights' faces
@records ― shadow.record and pointShadow.record with what was added to them, before the passes
that shade
@param ― options.shadow the sun's shadow, with a depth pass per cascade
@param ― options.pointShadow shadows that cast gives to lights of points.table, with a depth
pass per face
@param ― options.points point lights from a table or a 'use gpu' function. Every lit point visits
each slot up to the table's highest live one, or count with a function, unless candidates
names the slots that may reach it
@returns ― lighting you destroy
create(
constroot:TgpuRoot
root,{
shadow:{
readonly extent:9;
}& FixedShadowOptions &{
readonly extent:9;
}
Enables and configures the shadow from the sun. Default none.
shadow:{
extent:9
Sets the width of the square covered by the map in world units. The square is centred on the
point passed to follow. Change it with setExtent. A shadow with an eye takes none.
Default 20.
extent:9}});
const
constscene:passes.Passes<{
readonly hdr:typeofpasses.color;
readonly depth:typeofpasses.depth;
}>
scene=
import passes
passes
.
functioncreate<{
readonly hdr:{
readonly format:"rgba16float";
readonly sampled:true;
};
readonly depth:{
readonly format:"depth24plus";
};
},{
readonly hdr:typeofpasses.color;
readonly depth:typeofpasses.depth;
}>(root:TgpuRoot,screen:targets.Targets<{
readonly hdr:{
readonly format:"rgba16float";
readonly sampled:true;
};
readonly depth:{
readonly format:"depth24plus";
};
}>,writes:{
readonly hdr:typeofpasses.color;
readonly depth:typeofpasses.depth;
},options?:passes.TargetOptions<{
readonly hdr:{
readonly format:"rgba16float";
readonly sampled:true;
};
readonly depth:{
readonly format:"depth24plus";
};
}>|undefined):passes.Passes<...>(+1overload)
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 depth:{
readonly format:"depth24plus";
};
}>
screen,{
hdr:typeofpasses.color
hdr:
import passes
passes.
constcolor:typeofpasses.color
Marks the target that receives each renderer's colour.
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.
Adds fill after the fills given to earlier beneath calls and returns a description of the
same passes. A drawing's own fills take precedence over these, and piped fills over both, so
beneath supplies defaults such as a lighting. A compound drawing that passes its own from
to pipeline gets them by starting from with inject().
beneath(
constlight:lighting.LightingOf<{
readonly shadow:{
readonly extent:9;
};
}>
light.
Lighting.inject(): Inject
Fills the shading hooks and resources for pipelines created from the configuration you pipe
it into.
Creates a renderer for colour and shadow pass descriptions, lit by the lighting each
description gives through beneath unless options.light replaces it. Use pipe to fill
resources read by kind callbacks.
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.
add(
constrenderer:instances.Renderer
renderer);// colour and depth, seen by the camera
const
constcast:passes.Drawn
cast=
constlight:lighting.LightingOf<{
readonly shadow:{
readonly extent:9;
};
}>
light.
shadow: Shadow |(Cascades & Shadow)
Provides the sun shadow when enabled in the options. Throws after destroy.
shadow.
ShadowPasses.add<{
color:v4f;
},{
position:v4f;
world:v3f;
normal:v3f;
uv:v2f;
uv1:v2f;
row:number;
}>(drawing:passes.Compound<{
color:v4f;
},{
position:v4f;
world:v3f;
normal:v3f;
uv:v2f;
uv1:v2f;
row:number;
}>):passes.Drawn(+1overload)
Builds a caster's depth pipeline with the shadow's bias and returns its draw methods.
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
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.
Uploads changed rows. When instances are added or removed, it also uploads live rows per
mesh and updates draw counts. Call this once per frame before drawing. HistoryInstances
take the frame's encoder and throw without it.
flush();
constlight:lighting.LightingOf<{
readonly shadow:{
readonly extent:9;
};
}>
light.
shadow: Shadow |(Cascades & Shadow)
Provides the sun shadow when enabled in the options. Throws after destroy.
Clears the map in a depth pass per cascade that redraw picks and draws the casters built by
add. Call this while recording each frame, before drawing shaded surfaces. When disabled, it
draws nothing and makes every point sunlit. A frame that draws no cascade writes a timer's
timestamps from an empty compute pass.
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.
Instances, particles, trails, lines and text each give a drawing and hold no pipeline. Each description they are added to builds the pipelines it needs, for its targets, sample count and fills:
One drawing can go into several descriptions. A particle system added to the scene and to the canvas draws the same particles into both.
A drawing can be a compound of several pipelines with resources for each view, such as the list of objects a camera sees, so the shadow and the scene cull separately.
Your own drawing is a plain object, typed passes.Drawing<Vertex, Surface>. passes.fullScreen gives the vertex for one that covers the screen, such as a sky.
An output is a value each drawing writes at every pixel, beside its colour. The description runs every output for every drawing, so adding one changes the description and no renderer:
TAA needs to know where each pixel was last frame. taa.motion computes it for every drawing from its vertices this frame and last.
An output whose write takes the surface’s id writes an id at every pixel, for a pick of your own. The picker instead projects candidates.
A drawing that lacks the data an output needs fails to type-check in scene.add. Add it through scene.without('id'), or give it an output of its own with scene.instead.
Motion needs each vertex where it was last frame. State that moves vertices lives in history, which keeps last frame’s copy, and a drawing’s vertex code runs once more with history.previously to read it. A table created with history: true keeps its rows that way, so instances moved by your kernels write correct motion.
Post-processing reads the targets the scene filled. Bloom, TAA, depth of field, FXAA and the final pass each take the frame, or its encoder, and open passes of their own. Each reads its source on every record, through a function or another module’s picture, such as source: aa, so a target rebuilt on resize keeps working. A region option reads part of the source when the scene draws below full resolution with dynamic resolution, and a module’s picture brings its region along.