| name | threejs-materials |
| allowed-tools | Read, Glob |
| description | Three.js materials - PBR, basic, phong, shader materials, material properties. Use when styling meshes, working with textures, creating custom shaders, or optimizing material performance. |
Three.js Materials
Iron Law
Always set needsUpdate = true after changing material maps or transparency at runtime — Three.js caches the compiled shader program and will not recompile without it.
Quick Start
import * as THREE from "three";
const material = new THREE.MeshStandardMaterial({
color: 0x00ff00,
roughness: 0.5,
metalness: 0.5,
});
const mesh = new THREE.Mesh(geometry, material);
Material Types Overview
| Material | Use Case | Lighting |
|---|
| MeshBasicMaterial | Unlit, flat colors, wireframes | No |
| MeshLambertMaterial | Matte surfaces, performance | Yes (diffuse only) |
| MeshPhongMaterial | Shiny surfaces, specular highlights | Yes |
| MeshStandardMaterial | PBR, realistic materials | Yes (PBR) |
| MeshPhysicalMaterial | Advanced PBR, clearcoat, transmission | Yes (PBR+) |
| MeshToonMaterial | Cel-shaded, cartoon look | Yes (toon) |
| MeshNormalMaterial | Debug normals | No |
| MeshDepthMaterial | Depth visualization | No |
| ShaderMaterial | Custom GLSL shaders | Custom |
| RawShaderMaterial | Full shader control | Custom |
MeshBasicMaterial
No lighting calculations. Fast, always visible.
const material = new THREE.MeshBasicMaterial({
color: 0xff0000,
transparent: true,
opacity: 0.5,
side: THREE.DoubleSide,
wireframe: false,
map: texture,
alphaMap: alphaTexture,
envMap: envTexture,
reflectivity: 1,
fog: true,
});
MeshLambertMaterial
Diffuse-only lighting. Fast, no specular highlights.
const material = new THREE.MeshLambertMaterial({
color: 0x00ff00,
emissive: 0x111111,
emissiveIntensity: 1,
map: texture,
emissiveMap: emissiveTexture,
envMap: envTexture,
reflectivity: 0.5,
});
MeshPhongMaterial
Specular highlights. Good for shiny, plastic-like surfaces.
const material = new THREE.MeshPhongMaterial({
color: 0x0000ff,
specular: 0xffffff,
shininess: 100,
emissive: 0x000000,
flatShading: false,
map: texture,
specularMap: specTexture,
normalMap: normalTexture,
normalScale: new THREE.Vector2(1, 1),
bumpMap: bumpTexture,
bumpScale: 1,
displacementMap: dispTexture,
displacementScale: 1,
});
MeshStandardMaterial (PBR)
Physically-based rendering. Recommended for realistic results.
const material = new THREE.MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5,
metalness: 0.0,
map: colorTexture,
roughnessMap: roughTexture,
metalnessMap: metalTexture,
normalMap: normalTexture,
normalScale: new THREE.Vector2(1, 1),
aoMap: aoTexture,
aoMapIntensity: 1,
displacementMap: dispTexture,
displacementScale: 0.1,
displacementBias: 0,
emissive: 0x000000,
emissiveIntensity: 1,
emissiveMap: emissiveTexture,
envMap: envTexture,
envMapIntensity: 1,
flatShading: false,
wireframe: false,
fog: true,
});
geometry.setAttribute("uv2", geometry.attributes.uv);
MeshPhysicalMaterial (Advanced PBR)
Extends MeshStandardMaterial with clearcoat, transmission (glass), sheen (fabric), iridescence, and anisotropy.
const glass = new THREE.MeshPhysicalMaterial({
transmission: 1, thickness: 0.5, ior: 1.5, roughness: 0,
});
const carPaint = new THREE.MeshPhysicalMaterial({
color: 0xff0000, metalness: 0.9, roughness: 0.5, clearcoat: 1, clearcoatRoughness: 0.1,
});
Full property list (clearcoat, sheen, iridescence, anisotropy) → references/api-reference.md
MeshToonMaterial
Cel-shaded cartoon look.
const material = new THREE.MeshToonMaterial({
color: 0x00ff00,
gradientMap: gradientTexture,
});
const colors = new Uint8Array([0, 128, 255]);
const gradientMap = new THREE.DataTexture(colors, 3, 1, THREE.RedFormat);
gradientMap.minFilter = THREE.NearestFilter;
gradientMap.magFilter = THREE.NearestFilter;
gradientMap.needsUpdate = true;
MeshNormalMaterial
Visualize surface normals. Useful for debugging.
const material = new THREE.MeshNormalMaterial({
flatShading: false,
wireframe: false,
});
MeshDepthMaterial
Render depth values. Used for shadow maps, DOF effects.
const material = new THREE.MeshDepthMaterial({
depthPacking: THREE.RGBADepthPacking,
});
PointsMaterial
For point clouds.
const material = new THREE.PointsMaterial({
color: 0xffffff,
size: 0.1,
sizeAttenuation: true,
map: pointTexture,
alphaMap: alphaTexture,
transparent: true,
alphaTest: 0.5,
vertexColors: true,
});
const points = new THREE.Points(geometry, material);
LineBasicMaterial & LineDashedMaterial
const lineMaterial = new THREE.LineBasicMaterial({
color: 0xffffff,
linewidth: 1,
linecap: "round",
linejoin: "round",
});
const dashedMaterial = new THREE.LineDashedMaterial({
color: 0xffffff,
dashSize: 0.5,
gapSize: 0.25,
scale: 1,
});
const line = new THREE.Line(geometry, dashedMaterial);
line.computeLineDistances();
ShaderMaterial
Custom GLSL shaders with Three.js uniforms.
const material = new THREE.ShaderMaterial({
uniforms: {
time: { value: 0 },
color: { value: new THREE.Color(0xff0000) },
texture1: { value: texture },
},
vertexShader: `
varying vec2 vUv;
uniform float time;
void main() {
vUv = uv;
vec3 pos = position;
pos.z += sin(pos.x * 10.0 + time) * 0.1;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`,
fragmentShader: `
varying vec2 vUv;
uniform vec3 color;
uniform sampler2D texture1;
void main() {
// Use texture2D() for GLSL 1.0, texture() for GLSL 3.0 (glslVersion: THREE.GLSL3)
vec4 texColor = texture2D(texture1, vUv);
gl_FragColor = vec4(color * texColor.rgb, 1.0);
}
`,
transparent: true,
side: THREE.DoubleSide,
});
material.uniforms.time.value = clock.getElapsedTime();
Built-in Uniforms (auto-provided)
// Vertex shader
uniform mat4 modelMatrix; // Object to world
uniform mat4 modelViewMatrix; // Object to camera
uniform mat4 projectionMatrix; // Camera projection
uniform mat4 viewMatrix; // World to camera
uniform mat3 normalMatrix; // For transforming normals
uniform vec3 cameraPosition; // Camera world position
// Attributes
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
Multiple Materials
const geometry = new THREE.BoxGeometry(1, 1, 1);
const materials = [
new THREE.MeshBasicMaterial({ color: 0xff0000 }),
new THREE.MeshBasicMaterial({ color: 0x00ff00 }),
new THREE.MeshBasicMaterial({ color: 0x0000ff }),
new THREE.MeshBasicMaterial({ color: 0xffff00 }),
new THREE.MeshBasicMaterial({ color: 0xff00ff }),
new THREE.MeshBasicMaterial({ color: 0x00ffff }),
];
const mesh = new THREE.Mesh(geometry, materials);
geometry.clearGroups();
geometry.addGroup(0, 6, 0);
geometry.addGroup(6, 6, 1);
Material Cloning and Modification
const clone = material.clone();
clone.color.set(0x00ff00);
material.color.set(0xff0000);
material.needsUpdate = true;
Performance Tips
- Reuse materials — same material = batched draw calls
- Avoid transparent when possible — requires sorting
- Use alphaTest instead of transparency when applicable
- Choose simpler materials — Basic > Lambert > Phong > Standard > Physical
- Limit active lights — each light adds shader complexity
References
references/api-reference.md — MeshPhysicalMaterial full property list, RawShaderMaterial, common base properties table, environment map setup, and material pooling pattern
See Also
threejs-textures - Texture loading and configuration
threejs-shaders - Custom shader development
threejs-lighting - Light interaction with materials