| name | threejs-materials |
| description | Configures Three.js materials — MeshStandardMaterial, MeshPhysicalMaterial, PBR pipeline, texture maps (color, normal, roughness, metalness, AO, emissive, environment). Use when the user asks about materials, textures, PBR, shading, opacity, transparency, or material properties. Trigger keywords: material, texture, PBR, roughness, metalness, normal map, emissive, transparent, MeshStandardMaterial. |
Three.js Materials
MeshStandardMaterial (default PBR material)
const mat = new THREE.MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5,
metalness: 0.0,
envMapIntensity: 1.0,
});
See MAPS.md for complete texture map reference.
MeshPhysicalMaterial (extended PBR)
const mat = new THREE.MeshPhysicalMaterial({
roughness: 0.1,
metalness: 0.0,
transmission: 1.0,
thickness: 0.5,
ior: 1.5,
reflectivity: 0.5,
iridescence: 1.0,
iridescenceIOR: 1.3,
sheen: 1.0,
sheenColor: 0xffffff,
clearcoat: 1.0,
clearcoatRoughness: 0.1,
});
Loading Textures
const loader = new THREE.TextureLoader();
const texture = loader.load("/textures/diffuse.jpg", (tex) => {
tex.colorSpace = THREE.SRGBColorSpace;
});
const normalMap = loader.load("/textures/normal.jpg");
const mat = new THREE.MeshStandardMaterial({
map: texture,
normalMap: normalMap,
roughnessMap: loader.load("/textures/roughness.jpg"),
metalnessMap: loader.load("/textures/metalness.jpg"),
aoMap: loader.load("/textures/ao.jpg"),
aoMapIntensity: 1.0,
emissiveMap: loader.load("/textures/emissive.jpg"),
emissive: new THREE.Color(0xffffff),
emissiveIntensity: 1.0,
});
Texture Settings
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(4, 4);
texture.offset.set(0.5, 0);
texture.rotation = Math.PI / 4;
texture.center.set(0.5, 0.5);
texture.minFilter = THREE.LinearMipmapLinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
texture.generateMipmaps = true;
Environment Map
import { RGBELoader } from "three/addons/loaders/RGBELoader.js";
import { PMREMGenerator } from "three";
const pmrem = new PMREMGenerator(renderer);
pmrem.compileEquirectangularShader();
new RGBELoader().load("/env/studio.hdr", (hdr) => {
const envMap = pmrem.fromEquirectangular(hdr).texture;
scene.background = envMap;
scene.environment = envMap;
hdr.dispose();
pmrem.dispose();
});
Transparency & Blending
mat.alphaMap = loader.load("/textures/alpha.jpg");
mat.transparent = true;
mat.alphaTest = 0.5;
mat.transparent = true;
mat.opacity = 0.5;
mat.depthWrite = false;
mat.side = THREE.DoubleSide;
mat.blending = THREE.NormalBlending;
mat.blending = THREE.AdditiveBlending;
mat.blending = THREE.MultiplyBlending;
Other Materials
new THREE.MeshBasicMaterial({ color: 0xff0000 });
new THREE.MeshLambertMaterial({ color: 0xff0000 });
new THREE.MeshPhongMaterial({ color: 0xff0000, shininess: 100 });
new THREE.MeshToonMaterial({ color: 0xff0000 });
new THREE.MeshNormalMaterial();
new THREE.MeshDepthMaterial();
new THREE.LineBasicMaterial({ color: 0xffffff });
new THREE.LineDashedMaterial({ color: 0xffffff, dashSize: 0.1, gapSize: 0.05 });
new THREE.PointsMaterial({ size: 0.05, sizeAttenuation: true });
new THREE.SpriteMaterial({ map: texture });
Material Disposal
mat.dispose();
mat.map?.dispose();
mat.normalMap?.dispose();
Common Gotchas
aoMap requires a second UV set: geo.setAttribute('uv2', geo.attributes.uv) or uv1 in r152+
- Color/albedo textures: set
colorSpace = THREE.SRGBColorSpace
- Non-color textures (normal, rough, metal, AO): leave as
LinearSRGBColorSpace
transparent: true triggers alpha sorting — use alphaTest instead for hard cutouts
MeshPhysicalMaterial with transmission requires a background or scene.environment
envMapIntensity only works on MeshStandardMaterial and MeshPhysicalMaterial