What Materials Do
A material defines how a mesh's surface responds to light. In Three.js, materials range from completely unlit (ignoring all light sources) to physically-based rendering (PBR) that simulates real-world light behavior. Choosing the right material is a trade-off between visual fidelity and performance.
Every material in Three.js extends the base Material class and shares common properties like opacity, transparent, side, and wireframe. The differences are in how they compute the color of each pixel.
MeshBasicMaterial: No Lighting
MeshBasicMaterial ignores all lights in the scene. It renders the mesh with a flat color, a texture, or vertex colors. Nothing more. This makes it the fastest material and useful for UI elements, backgrounds, wireframes, or any object that shouldn't react to lighting.
// Flat color, no light interaction
const material = new THREE.MeshBasicMaterial({
color: 0x4488cc
});
// With wireframe overlay
const wireframe = new THREE.MeshBasicMaterial({
color: 0x4488cc,
wireframe: true
});
// With transparency
const glass = new THREE.MeshBasicMaterial({
color: 0x88ccff,
transparent: true,
opacity: 0.5
});MeshNormalMaterial: Debugging and Visualization
MeshNormalMaterial maps each face's normal direction to a color. Faces pointing along the X axis appear red/cyan, Y axis appears green/magenta, and Z axis appears blue/yellow. It doesn't need lights and is invaluable for debugging geometry. You can immediately see if normals are correct, faces are oriented properly, or vertices are shared.
const material = new THREE.MeshNormalMaterial();
// With flat shading to see individual faces
const flat = new THREE.MeshNormalMaterial({
flatShading: true
});MeshLambertMaterial: Matte Surfaces
MeshLambertMaterial is the simplest lit material. It uses Lambertian reflectance, which calculates lighting only at vertices and interpolates across faces. This creates a soft, matte look, which is good for clay, fabric, unpolished wood, or any surface that doesn't have a shine. It's significantly cheaper than Phong or Standard materials.
const material = new THREE.MeshLambertMaterial({
color: 0xcc8844
});
// With emissive glow (self-illumination)
const glowing = new THREE.MeshLambertMaterial({
color: 0x884422,
emissive: 0x331100
});MeshPhongMaterial: Shiny Surfaces
MeshPhongMaterial adds specular highlights on top of Lambert's diffuse shading. The shininess property controls how tight the highlight is. Low values create a broad, soft sheen (like rubber), high values create a tight, bright spot (like polished metal). The specular color controls the highlight's tint.
// Moderate shine (plastic-like)
const plastic = new THREE.MeshPhongMaterial({
color: 0x4488cc,
shininess: 60,
specular: 0x222222
});
// High shine (polished)
const polished = new THREE.MeshPhongMaterial({
color: 0xcc4444,
shininess: 200,
specular: 0xffffff
});
// Low shine (rubber)
const rubber = new THREE.MeshPhongMaterial({
color: 0x44cc88,
shininess: 5,
specular: 0x111111
});MeshStandardMaterial: Physically-Based Rendering
MeshStandardMaterial is the workhorse PBR material. Instead of separate diffuse/specular/shininess controls, it uses two intuitive properties: roughness (0 = mirror, 1 = completely diffuse) and metalness (0 = dielectric like plastic, 1 = metal). This model produces more realistic results because it conserves energy. As a surface becomes more reflective, it scatters less light diffusely.
// Smooth metal
const chrome = new THREE.MeshStandardMaterial({
color: 0xcccccc,
roughness: 0.1,
metalness: 1.0
});
// Rough plastic
const plastic = new THREE.MeshStandardMaterial({
color: 0xcc4444,
roughness: 0.8,
metalness: 0.0
});
// Semi-rough metal
const brushedMetal = new THREE.MeshStandardMaterial({
color: 0xddaa44,
roughness: 0.4,
metalness: 0.9
});The demo above shows a grid of spheres with roughness increasing left-to-right and metalness increasing bottom-to-top. Notice how smooth metals reflect the environment crisply, while rough dielectrics scatter light softly.
MeshPhysicalMaterial: Advanced PBR
MeshPhysicalMaterial extends Standard with additional properties for specialized effects: clearcoat (a second reflective layer, like car paint or lacquered wood), transmission (light passing through, for glass), thickness (how deep the transparent object is), ior (index of refraction), and iridescence (thin-film interference, like soap bubbles or oil slicks). It's the most expensive material but produces the most realistic results.
// Glass sphere
const glass = new THREE.MeshPhysicalMaterial({
color: 0xffffff,
roughness: 0.0,
metalness: 0.0,
transmission: 1.0,
thickness: 1.5,
ior: 1.5
});
// Car paint (clearcoat)
const carPaint = new THREE.MeshPhysicalMaterial({
color: 0xcc0000,
roughness: 0.4,
metalness: 0.0,
clearcoat: 1.0,
clearcoatRoughness: 0.1
});
// Iridescent surface
const iridescent = new THREE.MeshPhysicalMaterial({
color: 0x888888,
roughness: 0.3,
metalness: 0.8,
iridescence: 1.0,
iridescenceIOR: 1.3
});MeshToonMaterial: Cel Shading
MeshToonMaterial renders surfaces with discrete shading steps instead of smooth gradients, creating a cartoon or cel-shaded look. By default it uses a two-tone (light/shadow) gradient, but you can provide a custom gradientMap texture for more steps. It responds to lights like Lambert but quantizes the result.
// Default two-tone cel shading
const toon = new THREE.MeshToonMaterial({
color: 0x44aacc
});
// Custom gradient with more steps
const format = THREE.RedFormat;
// Three-tone gradient
const colors = new Uint8Array(3);
colors[0] = 60; // Dark
colors[1] = 140; // Mid
colors[2] = 255; // Light
const gradientMap = new THREE.DataTexture(colors, 3, 1, format);
gradientMap.needsUpdate = true;
const threeTone = new THREE.MeshToonMaterial({
color: 0xcc6644,
gradientMap: gradientMap
});Comparing Materials Side by Side
The best way to understand materials is to see them on the same geometry under the same lighting. The demo below places seven spheres in a row, one for each material type, lit by the same directional and ambient lights. Notice how each responds differently to the same light conditions.
From left to right: Basic (flat, unlit), Normal (debug colors), Lambert (soft matte), Phong (specular highlight), Standard (PBR roughness/metalness), Physical (clearcoat), Toon (cel-shaded steps).
Common Material Properties
All materials share a set of properties inherited from the base Material class:
transparent/opacity: Enable transparency and set how see-through the surface is (0 = invisible, 1 = fully opaque).side: Which faces to render:THREE.FrontSide(default),THREE.BackSide, orTHREE.DoubleSide.wireframe: Render only the edges of each triangle.flatShading: Use face normals instead of vertex normals, making each triangle visually distinct.vertexColors: Use per-vertex colors from the geometry'scolorattribute instead of (or multiplied with) the material color.depthWrite/depthTest: Control whether the material writes to and reads from the depth buffer. Useful for overlays and particle effects.
Which Material Should You Use?
- MeshBasicMaterial: When you don't need lighting: UI, skyboxes, wireframes, flat-shaded stylized art.
- MeshNormalMaterial: Debugging geometry, visualizing normals, quick prototyping.
- MeshLambertMaterial: Performance-sensitive scenes with many objects that only need basic diffuse lighting.
- MeshPhongMaterial: When you need specular highlights but don't need full PBR realism.
- MeshStandardMaterial: The default choice for most 3D scenes. Good balance of realism and performance.
- MeshPhysicalMaterial: When you need glass, clearcoat, iridescence, or other advanced effects.
- MeshToonMaterial: Stylized, cartoon, or anime-inspired visuals.