Skip to main content

Module scene

Module scene 

Source
Expand description

The declarative description of a frame.

A Scene is pure data: it names the pipelines to run, the bind groups and vertex buffers each draw binds, and the ranges to draw. Recording it (Scene::record) is a separate step, so a caller can build the description once and reuse, inspect or modify it — and custom draw commands are expressed with the same shapes as the built-in ones.

The recording loop is flat: each draw names its own pipeline and every resource it binds.

for draw in scene.draws {
    set the pipeline, then the draw's bind groups
    set the draw's vertex and index buffers
    draw (indexed or not)
}

Consecutive draws that bind the same resource skip the redundant set_* call.

A draw owns the handles it names — wgpu handles are reference-counted, so holding one keeps the resource alive and cloning one is cheap. A scene therefore borrows nothing, which is what lets several scenes be built from one resource graph and then recorded in turn.

Scissor rectangles are the exception to “a draw is independent”: wgpu has no reset call, so a rectangle set by one draw stays set for every draw after it in the pass. A scene therefore orders its clipped draws last — or sets DrawEntry::scissor on every draw. In a composite, DrawOrder::After is that last stretch: nothing outside the trailing tier follows the clipped draws, so their rectangle cannot leak into one. The stencil reference is the same kind of pass state, but it is set on every draw (from DrawEntry::stencil_reference), so it never leaks from one draw to the next. Both are per-Scene state: Scene::record starts from the pass’s own defaults, so nothing a scene leaves behind is seen by the next one.

The viewport is pass state of the same kind — wgpu has no call that resets it either — but it covers a whole scene rather than one draw, so a scene states it once in Scene::viewport. A scene that states none draws into whatever region the pass already holds, which is the whole target only if the caller put it there; the frame driver in unlit3d does that for every scene that states none, so one scene’s letterbox never crops the next one’s.

Scene::record lists a single scene’s draws in the order they are given. Recording several scenes as one composite — Scene::record_composited — orders them by DrawOrder instead: the sequenced draws of every scene first, then the depth-sorted ones of every scene pooled together back-to-front, then the trailing ones. A scene that states no order keeps its place: DrawOrder::Before is the default, and only draws that join the sorted pool are reordered.

Re-exports§

use arrayvec::ArrayVec; 🔒
use core::ops::Range; 🔒

Structs§

DrawEntry
One draw: the pipeline and every resource it binds, followed by what to draw.
PassState 🔒
Which resources the previous draw left bound.
Scene
A frame’s worth of draws.
ScissorRect
A scissor rectangle, in pixels.
SortedDraw 🔒
A depth-sorted draw waiting for the pool to be complete.
ViewportRect
The region of the render target a scene draws into, in pixels.

Enums§

DrawOrder
Where a draw sits in the composite of a pass’s scenes.
DrawRange
What to draw for one mesh.

Constants§

MAX_BIND_GROUPS
Maximum number of bind-group slots a pass is tracked for.
MAX_VERTEX_BUFFERS
Maximum number of vertex-buffer slots a pass is tracked for.

Traits§

RenderPassInterface 🔒
The render-pass operations PassState records through.

Functions§

record_composited_into 🔒
The composite recorder behind Scene::record_composited, generic over the pass so tests can drive it with a mock.
record_draw 🔒
Records one draw: the state it changes, then the draw call itself.

Type Aliases§

BindGroupBinding
One bind-group slot: the group index and the group to bind there.
VertexBufferBinding
One vertex-buffer slot: the slot index, the buffer to bind and the byte range of it the draw reads.