Renderers and Passes


Use.GPU has a modular system of renderers and passes. There is no core renderer per-se: the way a particular draw is realized depends entirely on which components were combined.

The <Pass> component is somewhat misleading: it is not a single "render pass" in classic GPU parlance. Rather, it represents a virtual render pass, realized as multiple actual concrete render passes. For example, geometry can be rendered both to the screen and to the GPU mouse picking buffer. This requires different shaders for each, and this specialization and retargeting happens automatically.

These components are also extensible: you can define custom versions of all of them, and there are no privileged "core" components. The rendering system 'eats its own dog food'.

For the majority of use, the default renderers and passes should be sufficient. They only define the overall rendering flow, using standard graphics techniques. You can already inject custom shader functions into many components without reinventing any wheels (see: Shaders).


There are several levels to this architecture, each realized as separate Live components.


Geometry layers can choose one of several methods to render themselves with. By default these are solid, shaded and ui.

Each corresponds to a combination of a base vertex + fragment shader interface, and defines what kind of information is available at every pixel (the classic varyings). A component will render a <Virtual> draw call, and this will be resolved into one or more concrete render components such as <SolidRender> or <ShadedRender>.


Geometry layers also choose one of several buckets to fit into. By default these are opaque, transparent, picking, shadow and debug.

Each bucket can be handled separately. Opaque and transparent geometry is rendered directly to the screen. Picking geometry is rendered to the global picking buffer. Shadow geometry is rendered to one or more shadow maps. Debug geometry is used for rendering inspector wireframes.

Specialized buckets can have their own render components, such as <PickingRender> or <ShadowRender>, as they are independent of the actual material and method used.


The rules for how to resolve each <Virtual> draw call are defined by the renderer and its passes. By default there is a typical forward and a deferred renderer, as well as a simple fullscreen renderer for effects.

The <ForwardRenderer> will use a classic <ColorPass> to render the opaque geometry front-to-back, and the transparent geometry back-to-front. The <DeferredRenderer> will use a <DeferredPass> instead, using a typical GBuffer with a stenciled lighting pass.

The renderer also decides which render component to use. The forward renderer's <ShadedRender> is swapped out for a <DeferredShadedRender> in the deferred renderer.


<Pass> handles the necessary default set up out-of-the box, but it is merely a convenient shorthand wrapper.

In custom scenarios, you should work with a renderer and its buffers directly. Custom components can be injected without having to fork it.

There are several options to extend it:

  • Custom rendering methods, to be used by custom geometry layers.
  • Custom rendering buckets, to be used by custom rendering passes.
  • Custom renderers and/or passes, to override the default rendering systems entirely.

These are roughly ordered from least-work to most-work.

Supplemental Buckets

In addition to the visible buckets, there are also supplemental buckets. These hold raw lambdas and are used for a few different purposes:

  • dispatch: Arbitrary JS dispatches before rendering
  • compute: GPU compute before rendering
  • post: GPU commands on rendered data
  • readback: Async JS readback of rendered data

These have matching passes, e.g. the <ComputePass> will handle the compute bucket. When doing a <Compute>, these 4 are the only passes that are run.