Shaders
Overview​
@luma.gl/shaders assembles reusable shader behavior. It resolves module dependencies,
typed props and bindings, injection targets, injections, plugins, and passes into shader source. It does
not create a device or compile shaders itself.
The generated Shaders API index at /docs/api-reference/generated/shaders contains every
public descriptor, helper, built-in module, and type with source links.
How the pieces fit together​
| Concept | Responsibility | Example |
|---|---|---|
| Shader source | Defines entry points and the algorithm the GPU executes | A vertex transform and fragment color calculation |
ShaderModule | Reuses shader helpers and declares uniforms, bindings, and dependencies | Lighting calculations and material parameters |
ShaderPlugin | Packages optional assembly behavior around one primary module | Clipping, filtering, or tinting |
| Injection target | Declares a callable extension point in the host shader | FILTER_COLOR(color) |
| Injection | Adds language-specific source to a callable target or built-in target | Multiply the color inside FILTER_COLOR |
| Shader assembler | Resolves dependencies and contributions into shader source | Select WGSL for WebGPU or GLSL for WebGL |
ShaderInputs | Updates module props and manages their uniform/binding representation | Change a material color between draws |
Model | Creates a render pipeline, binds resources, and draws | Render geometry with optional plugins |
A host shader computes a value, calls a callable target, and uses the modified value. A plugin can declare that target, contribute injections to it, or do both. The assembler collects declarations before resolving consumers, selects language variants, and emits a no-op function when a declared target has no injections. Shader code must still call the function: assembly does not infer where behavior belongs.
A module and a plugin are complementary. Put reusable math and data contracts in a module; use a plugin to connect optional behavior to a host's extension points. Plugin input declarations describe interfaces, while the application retains buffer allocation, attribute generation, and cleanup. Neither modules nor plugins schedule additional passes.
Start with the Shader Injection guide for a provider/consumer example with GLSL and WGSL variants. Then read ShaderModule for uniform contracts and dependencies, and Shader Assembly for assembly mechanics.
Language entry points​
Use @luma.gl/shaders/glsl for GLSLShaderAssembler and GLSL assembly helpers, or
@luma.gl/shaders/wgsl for WGSLShaderAssembler, WGSL assembly, interface scanning and binding
diagnostics. The language entries share the abstract ShaderAssembler contract and common module
logic, while keeping the other assembly backend out of application bundles. Root exports retain
constructor identity. See ShaderAssembler for explicit assembler ownership.
When to use it​
Use Shaders when shader behavior must be shared, configured, or composed. Use plain WGSL or GLSL for a tiny one-off shader. Move up to Engine when the assembled shader needs geometry, inputs, a pipeline, and draw lifecycle management.
Live example​
Toggle the module behavior in the running example and compare the reusable module inputs with the assembled WGSL/GLSL application that Engine submits.
- Dependencies
- color → lighting
- Hook
fragmentColor(baseColor)- Injection
- lighting::shade
- Uniforms
- lighting.intensity
Assembled teaching source
// module: color
fn applyColor(base: vec3<f32>) -> vec3<f32> { return base; }
// module: lighting
fn shade(base: vec3<f32>) -> vec3<f32> { return applyColor(base) * 0.85; }Core concepts​
- shader moduleReusable shader behavior with source, dependencies, typed props or bindings, and optional injection points.
- Reusable shader behavior with source, dependencies, typed props or bindings, and optional injection points.
- bindingThe connection that makes a buffer, texture, sampler, or uniform block available to shader code.
- The connection that makes a buffer, texture, sampler, or uniform block available to shader code.
- hookA named extension point in shader source that modules or plugins may call or implement.
- A named extension point in shader source that modules or plugins may call or implement.
- injectionShader source inserted at a declared hook or source location during assembly.
- Shader source inserted at a declared hook or source location during assembly.
- pluginA configurable shader extension that selects modules, bindings, and source changes for a rendering feature.
- A configurable shader extension that selects modules, bindings, and source changes for a rendering feature.
- pipelineCompiled shader stages plus fixed GPU state used for rendering or compute work.
- Compiled shader stages plus fixed GPU state used for rendering or compute work.
The learning spine is: modules and dependencies; uniforms and bindings; targets and injections; assembly; plugins and passes; portability; then the built-in module and pass catalogs.
Feature card​
Workflows​
- Learn the workflowBuild the mental model before choosing classes.
- Copy a focused recipeStart from a complete, small task.
- Check the complete APIConfirm exact types, defaults, and ownership.
The Shaders cookbook covers authoring modules, exposing props, adding injection targets, injecting source, composing dependencies, creating plugins, and defining passes.
API index​
Composable shader modules, dependencies, hooks, injections, plugins, passes, and portable assembly.
- Modules and dependencies
- Props and bindings
- Hooks and injections
- Assembly
- Plugins and passes
- Portability and catalogs
The generated Shaders API index is the exhaustive, source-linked inventory of every public value and TypeScript export. The curated pages explain how the related families fit together.
Keep the shader module catalog and shader pass catalog separate from the teaching path; use them after choosing the relevant descriptor family.
Limits and compatibility​
- A module may provide WGSL, GLSL, or both. The selected backend requires a compatible source path.
- Shaders assembles text and metadata; Core adapters perform validation and compilation.
- Dependency order is deterministic, but conflicting target or binding contracts remain author errors.
- Plugins should state their source, binding, and backend requirements explicitly.
Related modules​
- Use Engine to bind module props and draw a
Model. - Use Core for the resources and pipelines that compile assembled source.
- Shader modules can also be consumed by GPU Core render and compute nodes.
Standalone shader contracts​
@luma.gl/shaders has no dependency on core or a GPU device. Import shader value types,
ShaderLayout, TextureFormat, sampler options, getVariableShaderTypeInfo, and
makeShaderBlockLayout from @luma.gl/shaders/types. WGSL interface and binding scanners
are available from @luma.gl/shaders/wgsl. Core re-exports its existing contracts and scanner
entry points from these implementations, preserving constructor and function identity.
Shader modules describe resource bindings without owning GPU resources. PBR material, scene
and IBL props accept a resource type parameter, for example PBRMaterialProps<Texture> when
using core textures. Core validates and binds concrete Buffer, Texture and Sampler resources.
Device-backed area-light lookup allocation is createAreaLightLTCTextures from
@luma.gl/engine; the shader definitions remain in shaders.