Skip to content

Documentation / scene / Material

Class: Material ​

Defined in: libs/scene/src/material/material.ts:73

Base class for all materials.

Responsibilities:

  • Defines a multi-pass rendering interface (numPasses, apply, bind, draw, drawPrimitive).
  • Builds and caches GPU shader programs per pass and per-render-context hash.
  • Manages a per-material bind group (typically at index 2) for uniforms and resources.
  • Updates render states per pass (updateRenderStates) and uploads uniforms (_applyUniforms).
  • Tracks "option" changes that affect shader variant hashing and render bundles.

Caching and hashing:

  • createHash(pass) produces a stable hash representing shader variant options for a pass. Override _createHash() in subclasses to encode feature toggles (defines, keywords, macros).
  • The global hash used to key MaterialState also includes ctx.materialFlags and ctx.shaderVariantHash when provided, allowing context-sensitive variants without coupling shader programs to runtime texture identities.
  • GPU programs are additionally memoized in a global static _programCache across materials by constructor.name + hash, to avoid recompilation of identical variants.

Bind groups and uniforms:

  • If a program declares a bind group layout at index 2 (i.e., bindGroupLayouts.length > 2), apply() will allocate the group and keep it in the state. Subclasses should fill it in _applyUniforms().
  • applyUniforms() only calls _applyUniforms() when needUpdate is true, based on _optionTag changes (see optionChanged()).

Lifecycle:

  • Constructed materials register a persistent ID into a global registry for serialization.
  • apply(ctx) prepares all passes: creates/gets state, programs, bind groups, render states, and uploads uniforms as needed.
  • bind(device, pass) binds the program, bind group (index 2), and render states.
  • draw(primitive, ctx, numInstances) runs all passes, calling bind() and drawPrimitive().
  • onDispose() releases bind groups and registry entries.

Extending:

  • Override _createProgram(pb, ctx, pass) to build a shader.
  • Override _applyUniforms(bindGroup, ctx, pass) to upload uniforms and resources.
  • Override updateRenderStates(pass, renderStates, ctx) to set depth, blend, cull, etc.
  • Override _createHash() to encode options that affect program compilation.
  • Override supportLighting, supportInstancing, isTransparentPass, getQueueType, etc.

Thread-safety:

  • Intended for main-thread use in a renderer driving WebGPU/WebGL-like devices.

Extends ​

  • Disposable

Extended by ​

Implements ​

  • Clonable<Material>
  • IDisposable

Constructors ​

Constructor ​

new Material(): Material

Defined in: libs/scene/src/material/material.ts:133

Create a new material instance.

  • Initializes one pass by default.
  • Prepares per-pass hash storage and change tracking.
  • Registers a persistent ID in the global registry.

Returns ​

Material

Overrides ​

Disposable.constructor

Accessors ​

disposed ​

Get Signature ​

get disposed(): boolean

Defined in: libs/base/dist/index.d.ts:6107

Returns ​

boolean

Implementation of ​

IDisposable.disposed

Inherited from ​

Disposable.disposed


changeTag ​

Get Signature ​

get changeTag(): number

Defined in: libs/scene/src/material/material.ts:173

Incremented when the material’s GPU-relevant state changes and render bundles may need to be rebuilt.

Returns ​

number


instanceId ​

Get Signature ​

get instanceId(): number

Defined in: libs/scene/src/material/material.ts:179

Runtime-unique numeric identifier for the material instance.

Returns ​

number


numPasses ​

Get Signature ​

get numPasses(): number

Defined in: libs/scene/src/material/material.ts:189

Number of rendering passes this material uses.

Increasing this will expand the per-pass hash cache; make sure to implement createHash(pass), _createProgram(pb, ctx, pass), and updateRenderStates(pass, ...) accordingly for each pass.

Returns ​

number

Set Signature ​

set numPasses(val): void

Defined in: libs/scene/src/material/material.ts:192

Parameters ​
val ​

number

Returns ​

void


coreMaterial ​

Get Signature ​

get coreMaterial(): this

Defined in: libs/scene/src/material/material.ts:283

Returns the core material that owns GPU state.

Instances may delegate to a shared core to reuse compiled programs and caches.

Returns ​

this

Methods ​

on() ​

on<K>(type, listener, context?): void

Defined in: libs/base/dist/index.d.ts:630

IEventTarget.on

Type Parameters ​

K ​

K extends "dispose"

Parameters ​

type ​

K

listener ​

EventListener<{ dispose: []; }, K>

context? ​

unknown

Returns ​

void

Implementation of ​

IDisposable.on

Inherited from ​

Disposable.on


once() ​

once<K>(type, listener, context?): void

Defined in: libs/base/dist/index.d.ts:634

IEventTarget.once

Type Parameters ​

K ​

K extends "dispose"

Parameters ​

type ​

K

listener ​

EventListener<{ dispose: []; }, K>

context? ​

unknown

Returns ​

void

Implementation of ​

IDisposable.once

Inherited from ​

Disposable.once


off() ​

off<K>(type, listener?, context?): void

Defined in: libs/base/dist/index.d.ts:638

IEventTarget.off

Type Parameters ​

K ​

K extends "dispose"

Parameters ​

type ​

K

listener? ​

EventListener<{ dispose: []; }>

context? ​

unknown

Returns ​

void

Implementation of ​

IDisposable.off

Inherited from ​

Disposable.off


dispatchEvent() ​

dispatchEvent<K>(type, ...args): void

Defined in: libs/base/dist/index.d.ts:642

IEventTarget.dispatchEvent

Type Parameters ​

K ​

K extends "dispose"

Parameters ​

type ​

K

args ​

...object[K]

Returns ​

void

Implementation of ​

IDisposable.dispatchEvent

Inherited from ​

Disposable.dispatchEvent


dispose() ​

dispose(): void

Defined in: libs/base/dist/index.d.ts:6108

Returns ​

void

Implementation of ​

IDisposable.dispose

Inherited from ​

Disposable.dispose


clone() ​

clone(): Material

Defined in: libs/scene/src/material/material.ts:150

Create a shallow clone of this material.

Note: The base implementation returns a base Material. Subclasses should override to return their own type and copy custom fields.

Returns ​

Material

Implementation of ​

Clonable.clone


copyFrom() ​

copyFrom(other): void

Defined in: libs/scene/src/material/material.ts:164

Copy basic properties from another material.

Disposes existing bind groups/states, copies numPasses. Subclasses should extend this to copy their own fields and call optionChanged(true) if shader-affecting options differ.

Parameters ​

other ​

this

Source material.

Returns ​

void


getNumPassesForRender() ​

protected getNumPassesForRender(_ctx): number

Defined in: libs/scene/src/material/material.ts:205

Get the number of passes this material will render for the given draw context.

Default returns numPasses. Subclasses may override to skip passes based on context flags.

Parameters ​

_ctx ​

DrawContext

Draw context (device, flags, pass hash, instance data, etc.).

Returns ​

number

Number of passes to render for this context.


getQueueType() ​

getQueueType(): number

Defined in: libs/scene/src/material/material.ts:225

Return the queue type to which this material belongs.

Override this in transparent or special materials (e.g., post-process).

Returns ​

number


isTransparentPass() ​

isTransparentPass(_pass): boolean

Defined in: libs/scene/src/material/material.ts:233

Whether the given pass is transparent.

Used to place draw calls into appropriate render queues and set blending states.

Parameters ​

_pass ​

number

Returns ​

boolean


supportLighting() ​

supportLighting(): boolean

Defined in: libs/scene/src/material/material.ts:241

Whether this material's shading is affected by scene lights.

Override and return false for unlit materials.

Returns ​

boolean


supportInstancing() ​

supportInstancing(): boolean

Defined in: libs/scene/src/material/material.ts:249

Whether this material supports hardware instancing.

Override and return false if per-instance data is not supported in the shader.

Returns ​

boolean


isBatchable() ​

isBatchable(): boolean

Defined in: libs/scene/src/material/material.ts:253

Returns true if this is a instance of material

Returns ​

boolean


needSceneColor() ​

needSceneColor(): boolean

Defined in: libs/scene/src/material/material.ts:260

Whether this material requires the scene color texture (e.g., for refraction).

Returns ​

boolean


needSceneDepth() ​

needSceneDepth(): boolean

Defined in: libs/scene/src/material/material.ts:266

Whether this material requires the linear scene depth texture (e.g., for depth-aware effects).

Returns ​

boolean


createInstance() ​

createInstance(): this

Defined in: libs/scene/src/material/material.ts:274

Create a material instance (instance-uniform-driven variant).

Base returns null. Subclasses that support instancing can return a lightweight instance.

Returns ​

this


apply() ​

apply(ctx): boolean

Defined in: libs/scene/src/material/material.ts:300

Prepare the material for drawing across all passes for the given draw context.

Steps per pass:

  • Compute global hash (material variant + context).
  • Retrieve or build the GPU program, cache in _programCache.
  • Create per-material bind group (index 2) if the program exposes it.
  • Update uniforms if _optionTag indicates changes since last apply.
  • Update and cache render states for the pass.
  • Detect bind group GPU ID changes to bump changeTag and notify RenderBundleWrapper.

Parameters ​

ctx ​

DrawContext

Draw context (device, flags, pass hash, instance data, etc.).

Returns ​

boolean

true if successful; false if any pass lacks a valid program.


applyUniforms() ​

applyUniforms(bindGroup, ctx, needUpdate, pass): void

Defined in: libs/scene/src/material/material.ts:450

Conditionally update uniforms/resources into the material bind group.

Delegates to _applyUniforms() when needUpdate is true (based on _optionTag check).

Parameters ​

bindGroup ​

BindGroup

Material bind group at index 2 (may be null if program has no layout).

ctx ​

DrawContext

Draw context.

needUpdate ​

boolean

Whether uniforms need to be refreshed.

pass ​

number

Pass index.

Returns ​

void


clearCache() ​

clearCache(): void

Defined in: libs/scene/src/material/material.ts:475

Returns ​

void


passToHash() ​

passToHash(pass): string

Defined in: libs/scene/src/material/material.ts:503

Convert a pass index to a hash seed string.

Subclasses may override to encode per-pass role (e.g., "depth", "forward", "shadow").

Parameters ​

pass ​

number

Pass number.

Returns ​

string

String used when building full hash.


drawPrimitive() ​

drawPrimitive(pass, primitive, ctx, numInstances): void

Defined in: libs/scene/src/material/material.ts:531

Issue the actual draw call for a pass.

Override for custom per-pass draw behavior if necessary. The default implementation:

  • Draws instanced if numInstances > 0.
  • Else uses ctx.instanceData.numInstances if available.
  • Else issues a non-instanced draw.

Parameters ​

pass ​

number

Pass number.

primitive ​

Primitive

Primitive to draw.

ctx ​

DrawContext

Draw context.

numInstances ​

number

Explicit instance count (0 = auto).

Returns ​

void


onDispose() ​

protected onDispose(): void

Defined in: libs/scene/src/material/material.ts:546

Dispose the material and release GPU-side resource references.

  • Unregisters from the global registry.
  • Disposes the per-material bind groups kept in _states.

Returns ​

void

Overrides ​

Disposable.onDispose


_createProgram() ​

protected _createProgram(_pb, _ctx, _pass): GPUProgram

Defined in: libs/scene/src/material/material.ts:578

Create and compile the shader program for this material/pass.

Implement in subclasses:

  • Define shader stages, entry points, macros/defines, and resource layouts.
  • Return a compiled GPUProgram.

Parameters ​

_pb ​

ProgramBuilder

_ctx ​

DrawContext

_pass ​

number

Pass number.

Returns ​

GPUProgram

The created program, or null on failure.


_applyUniforms() ​

protected _applyUniforms(_bindGroup, _ctx, _pass): void

Defined in: libs/scene/src/material/material.ts:592

Upload uniforms and bind resources to the per-material bind group (index 2).

Implement in subclasses to:

  • Write uniform buffers/textures/samplers to the bindGroup.
  • Respect the current pass and ctx.

Parameters ​

_bindGroup ​

BindGroup

The bind group to populate.

_ctx ​

DrawContext

Draw context.

_pass ​

number

Pass number.

Returns ​

void


updateRenderStates() ​

protected updateRenderStates(_pass, _renderStates, _ctx): void

Defined in: libs/scene/src/material/material.ts:603

Update render states (depth/stencil, blending, rasterization) for the pass.

Implement in subclasses based on transparency, double-sidedness, depth writes/tests, color mask, stencil ops, etc., and any context flags in ctx.

Parameters ​

_pass ​

number

Current pass index.

_renderStates ​

RenderStateSet

Render state set to mutate.

_ctx ​

DrawContext

Draw context.

Returns ​

void


_createHash() ​

protected _createHash(): string

Defined in: libs/scene/src/material/material.ts:612

Compute the material-specific portion of the shader hash for the current options.

Subclasses should override to include macro/define sets that influence program compilation. Example return: "USE_NORMALMAP=1;ALPHA_MODE=BLEND;RECEIVE_SHADOWS=1".

Returns ​

string

Hash fragment string (no context/pass info).

Released under the MIT License.