Class MaterialPropertyBlock<T>

MaterialPropertyBlock allows per-object material property overrides without creating new material instances.
This is useful for rendering multiple objects with the same base material but different properties
(e.g., different colors, textures, or shader parameters).

The property block system works by:

  • Temporarily applying overrides in onBeforeRender
  • Restoring original values in onAfterRender
  • Managing shader defines and program cache keys for correct shader compilation
  • Supporting texture coordinate transforms per object

Common use cases:

  • Lightmaps: Apply unique lightmap textures to individual objects sharing the same material
  • Reflection Probes: Apply different environment maps per object for localized reflections
  • See-through effects: Temporarily override transparency/transmission properties for X-ray effects

Important: Do not use the constructor directly. Instead, use the static MaterialPropertyBlock.get method:

const block = MaterialPropertyBlock.get(myMesh);

This method will either return an existing property block or create a new one if it doesn't exist. It automatically:

  • Creates the property block instance
  • Registers it in the internal registry
  • Attaches the necessary render callbacks to the object
  • Handles Groups by applying overrides to all child meshes
// Get or create a property block for an object
const block = MaterialPropertyBlock.get(myMesh);

// Override the color property
block.setOverride("color", new Color(1, 0, 0));

// Override a texture with custom UV transform (useful for lightmaps)
block.setOverride("lightMap", myLightmapTexture, {
offset: new Vector2(0.5, 0.5),
repeat: new Vector2(2, 2)
});

// Set a shader define
block.setDefine("USE_CUSTOM_FEATURE", 1);
const block = MaterialPropertyBlock.get(mesh);
block.setOverride("lightMap", lightmapTexture);
block.setOverride("lightMapIntensity", 1.5);
const block = MaterialPropertyBlock.get(mesh);
block.setOverride("transparent", true);
block.setOverride("opacity", 0.3);

Type Parameters

  • T extends Material = Material

    The material type this property block is associated with

Constructors

Accessors

  • get object(): null | Object3D<Object3DEventMap>

    The object this property block is attached to

    Returns null | Object3D<Object3DEventMap>

  • get overrides(): readonly PropertyBlockOverride<MaterialPropertyType>[]

    Gets all property overrides as a readonly array

    Returns readonly PropertyBlockOverride<MaterialPropertyType>[]

    Array of all property overrides

Methods

  • Removes all property overrides from this block

    Returns void

  • Remove a shader define

    Parameters

    • name: string

      The define name to remove

    Returns void

  • Disposes this property block and cleans up associated resources. After calling dispose, this property block should not be used.

    Returns void

  • Get all defines set on this property block

    Returns Readonly<Record<string, string | number | boolean>>

    A readonly record of all defines

  • Gets the override for a specific property with type-safe value inference

    Type Parameters

    • K extends string | number | symbol

    Parameters

    • name: K

      The property name to get

    Returns undefined | PropertyBlockOverride<T[K] & MaterialPropertyType>

    The PropertyBlockOverride with correctly typed value if it exists, undefined otherwise

    const block = MaterialPropertyBlock.get<MeshStandardMaterial>(mesh);

    // Value is inferred as number | undefined
    const roughness = block.getOverride("roughness")?.value;

    // Value is inferred as Color | undefined
    const color = block.getOverride("color")?.value;

    // Value is inferred as Texture | null | undefined
    const map = block.getOverride("map")?.value;

    // Explicitly specify the type for properties not on the base material type
    const transmission = block.getOverride<number>("transmission")?.value;

    // Or use a more specific material type
    const physicalBlock = block as MaterialPropertyBlock<MeshPhysicalMaterial>;
    const transmissionTyped = physicalBlock.getOverride("transmission")?.value; // number
  • Gets the override for a specific property with type-safe value inference

    Type Parameters

    • V extends MaterialPropertyType = MaterialPropertyType

    Parameters

    • name: string

      The property name to get

    Returns undefined | PropertyBlockOverride<V>

    The PropertyBlockOverride with correctly typed value if it exists, undefined otherwise

    const block = MaterialPropertyBlock.get<MeshStandardMaterial>(mesh);

    // Value is inferred as number | undefined
    const roughness = block.getOverride("roughness")?.value;

    // Value is inferred as Color | undefined
    const color = block.getOverride("color")?.value;

    // Value is inferred as Texture | null | undefined
    const map = block.getOverride("map")?.value;

    // Explicitly specify the type for properties not on the base material type
    const transmission = block.getOverride<number>("transmission")?.value;

    // Or use a more specific material type
    const physicalBlock = block as MaterialPropertyBlock<MeshPhysicalMaterial>;
    const transmissionTyped = physicalBlock.getOverride("transmission")?.value; // number
  • Checks if this property block has any overrides

    Returns boolean

    True if there are any overrides set

  • Removes a specific property override

    Type Parameters

    • K extends string | number | symbol

    Parameters

    • name: K | {} & string

      The property name to clear

    Returns void

  • Set a shader define that will be included in the program cache key. This allows different objects sharing the same material to have different shader programs.

    Defines affect shader compilation and are useful for enabling/disabling features per-object.

    Parameters

    • name: string

      The define name (e.g., "USE_LIGHTMAP", "ENABLE_REFLECTIONS")

    • value: string | number | boolean

      The define value (typically a boolean, number, or string)

    Returns void

    // Enable a feature for this specific object
    block.setDefine("USE_CUSTOM_SHADER", true);
    block.setDefine("QUALITY_LEVEL", 2);
  • Sets or updates a material property override. The override will be applied to the material during rendering.

    Type Parameters

    • K extends string | number | symbol

    Parameters

    • name: K

      The name of the material property to override (e.g., "color", "map", "roughness")

    • value: T[K]

      The value to set

    • OptionaltextureTransform: TextureTransform

      Optional UV transform (only used when value is a Texture)

    Returns void

    // Override a simple property
    block.setOverride("roughness", 0.8);

    // Override a color
    block.setOverride("color", new Color(0xff0000));

    // Override a texture with UV transform
    block.setOverride("map", texture, {
    offset: new Vector2(0, 0),
    repeat: new Vector2(2, 2)
    });
  • Sets or updates a material property override. The override will be applied to the material during rendering.

    Parameters

    • name: string

      The name of the material property to override (e.g., "color", "map", "roughness")

    • value: MaterialPropertyType

      The value to set

    • OptionaltextureTransform: TextureTransform

      Optional UV transform (only used when value is a Texture)

    Returns void

    // Override a simple property
    block.setOverride("roughness", 0.8);

    // Override a color
    block.setOverride("color", new Color(0xff0000));

    // Override a texture with UV transform
    block.setOverride("map", texture, {
    offset: new Vector2(0, 0),
    repeat: new Vector2(2, 2)
    });
  • Gets or creates a MaterialPropertyBlock for the given object. This is the recommended way to obtain a property block instance.

    Type Parameters

    Parameters

    • object: Object3D

      The object to get/create a property block for

    Returns MaterialPropertyBlock<T>

    The MaterialPropertyBlock associated with this object

    const block = MaterialPropertyBlock.get(myMesh);
    block.setOverride("roughness", 0.5);
  • Checks if an object has any property overrides

    Parameters

    Returns boolean

    True if the object has a property block with overrides