# Material

Class · category: Graphics

Source: https://github.com/playcanvas/engine/blob/b5b983982a9860d21e0c1dafb2f85f72e2c01afb/src/scene/materials/material.js#L77

A material determines how a particular [MeshInstance](https://api.playcanvas.com/engine/classes/MeshInstance.md) is rendered, and specifies
render state including uniforms, textures, defines, and other properties.

This is a base class and cannot be instantiated and used directly. Only subclasses such
as [ShaderMaterial](https://api.playcanvas.com/engine/classes/ShaderMaterial.md) and [StandardMaterial](https://api.playcanvas.com/engine/classes/StandardMaterial.md) can be used to define materials
for rendering.

## Constructors

### constructor

```ts
protected new Material()
```

## Properties

### alphaTest

```ts
alphaTest: number = 0
```

The alpha test reference value to control which fragments are written to the currently
active render target based on alpha value. All fragments with an alpha value of less than
the alphaTest reference value will be discarded. alphaTest defaults to 0 (all fragments
pass).

### alphaToCoverage

```ts
alphaToCoverage: boolean = false
```

Enables or disables alpha to coverage. When enabled, and if hardware anti-aliasing is on,
limited order-independent transparency can be achieved. Quality depends on the number of
MSAA samples of the current render target. It can nicely soften edges of otherwise sharp
alpha cutouts, but isn't recommended for large area semi-transparent surfaces. Note, that
you don't need to enable blending to make alpha to coverage work. It will work without it,
just like alphaTest.

This requires a multi-sampled render target, and is silently ignored when rendering to a
single-sampled one. On WebGPU it additionally requires the first color attachment of the
render target to use a blendable format with an alpha channel, and is silently ignored
otherwise - note that [PIXELFORMAT_111110F](https://api.playcanvas.com/engine/variables/PIXELFORMAT_111110F.md), the default HDR format used by
[CameraFrame](https://api.playcanvas.com/engine/classes/CameraFrame.md), has no alpha channel.

### cull

```ts
cull: number = CULLFACE_BACK
```

Controls how triangles are culled based on their face direction with respect to the
viewpoint. Can be:

- [CULLFACE_NONE](https://api.playcanvas.com/engine/variables/CULLFACE_NONE.md): Do not cull triangles based on face direction.
- [CULLFACE_BACK](https://api.playcanvas.com/engine/variables/CULLFACE_BACK.md): Cull the back faces of triangles (do not render triangles facing
away from the view point).
- [CULLFACE_FRONT](https://api.playcanvas.com/engine/variables/CULLFACE_FRONT.md): Cull the front faces of triangles (do not render triangles facing
towards the view point).

Defaults to [CULLFACE_BACK](https://api.playcanvas.com/engine/variables/CULLFACE_BACK.md).

### frontFace

```ts
frontFace: number = FRONTFACE_CCW
```

Controls whether polygons are front- or back-facing by setting a winding
orientation. Can be:

- [FRONTFACE_CW](https://api.playcanvas.com/engine/variables/FRONTFACE_CW.md): The clock-wise winding.
- [FRONTFACE_CCW](https://api.playcanvas.com/engine/variables/FRONTFACE_CCW.md): The counterclockwise winding.

Defaults to [FRONTFACE_CCW](https://api.playcanvas.com/engine/variables/FRONTFACE_CCW.md).

### name

```ts
name: string = 'Untitled'
```

The name of the material.

### stencilBack

```ts
stencilBack: StencilParameters | null = null
```

Stencil parameters for back faces (default is null).

### stencilFront

```ts
stencilFront: StencilParameters | null = null
```

Stencil parameters for front faces (default is null).

### userId

```ts
userId: string = ''
```

A unique id the user can assign to the material. The engine internally does not use this for
anything, and the user can assign a value to this id for any purpose they like. Defaults to
an empty string.

## Accessors

### alphaWrite

```ts
get alphaWrite(): boolean
set alphaWrite(value: boolean)
```

Gets whether the alpha channel is written to the color buffer.

### blendState

```ts
get blendState(): Readonly<BlendState>
set blendState(value: Readonly<BlendState>)
```

Gets the blend state for this material. Use the setter to update transparency and sort state.

### blendType

```ts
get blendType(): number
set blendType(type: number)
```

Gets the blend mode for this material.

### blueWrite

```ts
get blueWrite(): boolean
set blueWrite(value: boolean)
```

Gets whether the blue channel is written to the color buffer.

### depthBias

```ts
get depthBias(): number
set depthBias(value: number)
```

Gets the offset for the output depth buffer value.

### depthFunc

```ts
get depthFunc(): number
set depthFunc(value: number)
```

Gets the depth test function.

### depthState

```ts
get depthState(): DepthState
set depthState(value: DepthState)
```

Gets the depth state.

### depthTest

```ts
get depthTest(): boolean
set depthTest(value: boolean)
```

Gets whether depth testing is enabled.

### depthWrite

```ts
get depthWrite(): boolean
set depthWrite(value: boolean)
```

Gets whether depth writing is enabled.

### flatShading

```ts
get flatShading(): boolean
set flatShading(value: boolean)
```

Gets whether flat shading is enabled.

### greenWrite

```ts
get greenWrite(): boolean
set greenWrite(value: boolean)
```

Gets whether the green channel is written to the color buffer.

### redWrite

```ts
get redWrite(): boolean
set redWrite(value: boolean)
```

Gets whether the red channel is written to the color buffer.

### shaderChunksVersion

```ts
get shaderChunksVersion(): string
set shaderChunksVersion(value: string)
```

Returns the version of the shader chunks.

### slopeDepthBias

```ts
get slopeDepthBias(): number
set slopeDepthBias(value: number)
```

Gets the offset for the output depth buffer value based on the slope of the triangle
relative to the camera.

## Methods

### clone

```ts
clone(): Material
```

Clone a material.

**Returns** [`Material`](https://api.playcanvas.com/engine/classes/Material.md): A newly cloned material.

### copy

```ts
copy(source: Material): Material
```

Copy a material.

**Parameters**

- `source` ([`Material`](https://api.playcanvas.com/engine/classes/Material.md)): The material to copy.

**Returns** [`Material`](https://api.playcanvas.com/engine/classes/Material.md): The destination material.

### deleteParameter

```ts
deleteParameter(name: string): void
```

Deletes a shader parameter on a material.

**Parameters**

- `name` (`string`): The name of the parameter to delete.

### destroy

```ts
destroy(): void
```

Removes this material from the scene and possibly frees up memory from its shaders (if there
are no other materials using it).

### getDefine

```ts
getDefine(name: string): boolean
```

Returns true if a define is enabled on the material, otherwise false.

**Parameters**

- `name` (`string`): The name of the define to check.

**Returns** `boolean`: The value of the define.

### getParameter

```ts
getParameter(name: string): any
```

Retrieves the specified shader parameter from a material.

**Parameters**

- `name` (`string`): The name of the parameter to query.

**Returns** `any`: The named parameter.

### getShaderChunks

```ts
getShaderChunks(shaderLanguage?: string): ShaderChunkMap
```

Returns an object containing shader chunks for a specific shader language for the material.
These chunks define custom GLSL or WGSL code used to construct the final shader for the
material. The chunks can be also be included in shaders using the `#include "ChunkName"`
directive.

On the WebGL platform:
 - If GLSL chunks are provided, they are used directly.

On the WebGPU platform:
- If WGSL chunks are provided, they are used directly.
- If only GLSL chunks are provided, a GLSL shader is generated and then transpiled to WGSL,
which is less efficient.

To ensure faster shader compilation, it is recommended to provide shader chunks for all
supported platforms.

A simple example on how to override a shader chunk providing emissive color for both GLSL and
WGSL to simply return a red color:

```javascript
material.getShaderChunks(SHADERLANGUAGE_GLSL).set('emissivePS', `
    void getEmission() {
        dEmission = vec3(1.0, 0.0, 1.0);
    }
`);

material.getShaderChunks(SHADERLANGUAGE_WGSL).set('emissivePS', `
    fn getEmission() {
        dEmission = vec3f(1.0, 0.0, 1.0);
    }
`);

// call update to apply the changes
material.update();
```

**Parameters**

- `shaderLanguage` (`string`, optional, default `SHADERLANGUAGE_GLSL`): Specifies the shader language of shaders. Defaults to
  [SHADERLANGUAGE_GLSL](https://api.playcanvas.com/engine/variables/SHADERLANGUAGE_GLSL.md).

**Returns** [`ShaderChunkMap`](https://api.playcanvas.com/engine/classes/ShaderChunkMap.md): - The shader chunks for the specified shader language.

### setDefine

```ts
setDefine(name: string, value: string | boolean | undefined): void
```

Adds or removes a define on the material. Defines can be used to enable or disable various
parts of the shader code.

**Parameters**

- `name` (`string`): The name of the define to set.
- `value` (`string | boolean | undefined`): The value of the define. If undefined or false, the
  define is removed.

  A simple example on how to set a custom shader define value used by the shader processor.

  ```javascript
  material.setDefine('MY_DEFINE', true);

  // call update to apply the changes, which will recompile the shader using the new define
  material.update();
  ```

### setParameter

```ts
setParameter(name: string, data: number | number[] | ArrayBufferView<ArrayBufferLike> | StorageBuffer | Texture): void
```

Sets a shader parameter on a material.

**Parameters**

- `name` (`string`): The name of the parameter to set.
- `data` (`number | number[] | ArrayBufferView<ArrayBufferLike> |` [`StorageBuffer`](https://api.playcanvas.com/engine/classes/StorageBuffer.md) `|` [`Texture`](https://api.playcanvas.com/engine/classes/Texture.md)): The value for the specified parameter.

### update

```ts
update(): void
```

Applies any changes made to the material's properties. This method should be called after
modifying material properties to ensure the changes take effect.

The method will clear cached shader variants and trigger recompilation if:
- Modified material properties require a different shader variant (e.g., enabling/disabling
  textures or other properties that affect shader generation)
- Material-specific shader chunks (from [getShaderChunks](https://api.playcanvas.com/engine/classes/Material.md#getshaderchunks)) have been modified
- Global shader chunks (from [ShaderChunks.get](https://api.playcanvas.com/engine/classes/ShaderChunks.md#get)) have been modified
- Material defines have been changed

Note: Shaders are not compiled immediately. Instead, existing shader variants are cleared
and new variants will be compiled on-demand as they are needed for different render passes
(e.g., forward, shadow, pick).

When global shader chunks are modified, `update()` must be called on each material that
should reflect those changes.
