Three.js Materials
Use this skill for mesh surface semantics and cost. Route image maps/UVs/HDR assets to
threejs-textures, lighting and shadow setup to threejs-lighting, and custom GLSL to
threejs-shaders.
When to use this skill
- Select a material type that matches unlit, classic-lighting, PBR, stylized, or custom work
- Configure base color, metalness, roughness, normal/AO/emissive maps, and environment response
- Fix transparency sorting, invisible backsides, unexpectedly shared edits, or material leaks
- Reduce material variants, shader complexity, or draw-call fragmentation after profiling
Instructions
Step 1: Choose the simplest material that expresses the intent
| Requirement |
Default material |
| No lighting / debug / sprite-like mesh |
MeshBasicMaterial |
| Low-cost classic diffuse scene |
MeshLambertMaterial |
| Classic specular look |
MeshPhongMaterial |
| Normal physically based surface |
MeshStandardMaterial |
| Clearcoat, transmission, advanced PBR |
MeshPhysicalMaterial |
| Cel-shaded style |
MeshToonMaterial |
| Custom vertex/fragment program |
ShaderMaterial via threejs-shaders |
Start with MeshStandardMaterial for normal PBR work, then add physical features only
when their visual benefit justifies the shader cost and renderer support.
Step 2: Set PBR inputs coherently
const material = new THREE.MeshStandardMaterial({
color: 0x9ca3af,
metalness: 0.65,
roughness: 0.28,
map: baseColorTexture,
normalMap,
roughnessMap,
metalnessMap,
envMapIntensity: 1,
});
Base-color textures need the correct color-space configuration; data maps such as normal,
roughness, metalness, and AO do not use the same display color treatment. See
threejs-textures for map loading and UV-channel requirements. Evaluate material values
under representative lights and an environment map, not in an unlit empty scene.
Step 3: Handle transparency explicitly
Use transparent: true only when alpha blending is necessary. Set depthWrite,
side, alphaTest, and renderOrder based on a diagnosed visual requirement; broad
render-order overrides can hide an underlying sort problem. Prefer alpha test for hard-cut
foliage/decals when it satisfies the desired appearance.
Step 4: Respect material ownership
Materials are commonly shared. A mutation to mesh.material.color changes every consumer
of that material. Clone before per-object changes, keep the clone's lifecycle explicit,
and call dispose() when its final consumer leaves.
const uniqueMaterial = sharedMaterial.clone();
mesh.material = uniqueMaterial;
uniqueMaterial.color.set("#3b82f6");
Step 5: Verify look and cost
- Test direct light, environment response, shadows, and a neutral background.
- Test transparent objects overlapping one another and opaque geometry.
- Inspect whether a change creates many distinct material/program variants.
- Test cleanup for replaced or cloned materials and their owned maps.
Examples
Metal product surface
Use MeshStandardMaterial, a calibrated base color, metallic/roughness maps, and an HDR
environment. A metallic object with no environment has little to reflect; adding arbitrary
point lights is not a substitute for the missing IBL signal.
Per-object highlight
Clone a shared material only if the highlight cannot be represented through a uniform,
instance attribute, outline pass, or other non-duplicating mechanism. Restore/dispose it
when selection changes.
Best practices
- Match material choice to the rendering intent before adjusting many parameters.
- Keep texture color-space and UV-channel rules correct; a wrong map interpretation is
not fixable with roughness guesses.
- Minimize material variants in repeated geometry.
- Measure expensive physical/transmission features on target devices.
- Dispose clones and their feature-owned textures, but never dispose shared assets early.
References
1---2name: threejs-materials3description: Choose, configure, and optimize Three.js mesh materials: basic, Lambert, Phong, Standard, Physical, toon, points, lines, and shader-backed surfaces; PBR maps, transparency, environment reflections, cloning, and disposal. Use when styling meshes, tuning PBR, fixing transparency or material sharing bugs, or reducing material cost. Triggers on: Three.js material, MeshStandardMaterial, MeshPhysicalMaterial, PBR, roughness, metalness, transparency, environment map, mesh surface, material clone.4license: MIT5---67# Three.js Materials89Use this skill for mesh surface semantics and cost. Route image maps/UVs/HDR assets to10`threejs-textures`, lighting and shadow setup to `threejs-lighting`, and custom GLSL to11`threejs-shaders`.1213## When to use this skill1415- Select a material type that matches unlit, classic-lighting, PBR, stylized, or custom work16- Configure base color, metalness, roughness, normal/AO/emissive maps, and environment response17- Fix transparency sorting, invisible backsides, unexpectedly shared edits, or material leaks18- Reduce material variants, shader complexity, or draw-call fragmentation after profiling1920## Instructions2122### Step 1: Choose the simplest material that expresses the intent2324| Requirement | Default material |25|---|---|26| No lighting / debug / sprite-like mesh | `MeshBasicMaterial` |27| Low-cost classic diffuse scene | `MeshLambertMaterial` |28| Classic specular look | `MeshPhongMaterial` |29| Normal physically based surface | `MeshStandardMaterial` |30| Clearcoat, transmission, advanced PBR | `MeshPhysicalMaterial` |31| Cel-shaded style | `MeshToonMaterial` |32| Custom vertex/fragment program | `ShaderMaterial` via `threejs-shaders` |3334Start with `MeshStandardMaterial` for normal PBR work, then add physical features only35when their visual benefit justifies the shader cost and renderer support.3637### Step 2: Set PBR inputs coherently3839```js40const material = new THREE.MeshStandardMaterial({41 color: 0x9ca3af,42 metalness: 0.65,43 roughness: 0.28,44 map: baseColorTexture,45 normalMap,46 roughnessMap,47 metalnessMap,48 envMapIntensity: 1,49});50```5152Base-color textures need the correct color-space configuration; data maps such as normal,53roughness, metalness, and AO do not use the same display color treatment. See54`threejs-textures` for map loading and UV-channel requirements. Evaluate material values55under representative lights and an environment map, not in an unlit empty scene.5657### Step 3: Handle transparency explicitly5859Use `transparent: true` only when alpha blending is necessary. Set `depthWrite`,60`side`, `alphaTest`, and `renderOrder` based on a diagnosed visual requirement; broad61render-order overrides can hide an underlying sort problem. Prefer alpha test for hard-cut62foliage/decals when it satisfies the desired appearance.6364### Step 4: Respect material ownership6566Materials are commonly shared. A mutation to `mesh.material.color` changes every consumer67of that material. Clone before per-object changes, keep the clone's lifecycle explicit,68and call `dispose()` when its final consumer leaves.6970```js71const uniqueMaterial = sharedMaterial.clone();72mesh.material = uniqueMaterial;73uniqueMaterial.color.set("#3b82f6");74```7576### Step 5: Verify look and cost7778- Test direct light, environment response, shadows, and a neutral background.79- Test transparent objects overlapping one another and opaque geometry.80- Inspect whether a change creates many distinct material/program variants.81- Test cleanup for replaced or cloned materials and their owned maps.8283## Examples8485### Metal product surface8687Use `MeshStandardMaterial`, a calibrated base color, metallic/roughness maps, and an HDR88environment. A metallic object with no environment has little to reflect; adding arbitrary89point lights is not a substitute for the missing IBL signal.9091### Per-object highlight9293Clone a shared material only if the highlight cannot be represented through a uniform,94instance attribute, outline pass, or other non-duplicating mechanism. Restore/dispose it95when selection changes.9697## Best practices98991. Match material choice to the rendering intent before adjusting many parameters.1002. Keep texture color-space and UV-channel rules correct; a wrong map interpretation is101 not fixable with roughness guesses.1023. Minimize material variants in repeated geometry.1034. Measure expensive physical/transmission features on target devices.1045. Dispose clones and their feature-owned textures, but never dispose shared assets early.105106## References107108- [Three.js Materials source coverage](https://github.com/CloudAI-X/threejs-skills/tree/main/skills/threejs-materials)109- [Materials documentation](https://threejs.org/docs/#api/en/materials/Material)110- [Three.js manual: materials](https://threejs.org/manual/#en/materials)