Three.js Cheatsheet
Materials
Use this Three.js reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Material Overview
| Material | Lighting | Use Case |
|---|---|---|
MeshBasicMaterial | None (unlit) | Wireframes, flat color overlays, debug |
MeshLambertMaterial | Diffuse only | Fast, non-specular surfaces |
MeshPhongMaterial | Diffuse + specular | Shiny surfaces, older style |
MeshStandardMaterial | PBR (metalness/roughness) | Default choice for all real scenes |
MeshPhysicalMaterial | PBR + extra (clearcoat, sheen…) | Car paint, glass, fabric, skin |
MeshToonMaterial | Cel-shaded | Cartoon / stylized |
MeshNormalMaterial | Encodes normals as RGB | Debug normals |
MeshDepthMaterial | Encodes depth | Shadow maps, depth effects |
MeshMatcapMaterial | Matcap texture | Fast stylized shading, no lights needed |
SpriteMaterial | Billboard 2D sprite | Particles, billboards |
LineBasicMaterial | Unlit lines | Lines, wireframes |
LineDashedMaterial | Dashed lines | Dashed outlines |
PointsMaterial | Unlit points | Particle systems |
ShaderMaterial | Custom GLSL | Full GPU control |
RawShaderMaterial | Custom GLSL (no injections) | Bare-metal GLSL |
Common Properties (All Materials)
const mat = new THREE.MeshStandardMaterial(); mat.color = new THREE.Color(0xff0000); // or set in constructor mat.opacity = 0.5; mat.transparent = true; // MUST be true for opacity < 1 to work mat.alphaTest = 0.5; // discard pixels below this alpha (avoids sort issues) mat.side = THREE.FrontSide; // FrontSide | BackSide | DoubleSide mat.visible = true; mat.wireframe = false; mat.depthWrite = true; // set false for transparent objects to avoid z-fighting mat.depthTest = true; mat.blending = THREE.NormalBlending; // NormalBlending | AdditiveBlending | MultiplyBlending | SubtractiveBlending mat.vertexColors = false; // use geometry color attribute mat.fog = true; // react to scene fog mat.needsUpdate = false; // set true after changing defines/side/etc at runtime // After changing properties that affect the shader (side, transparent, etc.) mat.needsUpdate = true;
MeshBasicMaterial
const mat = new THREE.MeshBasicMaterial({ color: 0xffffff, map: colorTexture, wireframe: false, opacity: 1, transparent: false, side: THREE.FrontSide, });
MeshStandardMaterial (PBR)
const mat = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.5, // 0 = mirror, 1 = fully diffuse metalness: 0.0, // 0 = dielectric, 1 = metal map: colorTex, // albedo / color map roughnessMap: roughnessTex, // R channel metalnessMap: metalnessTex, // B channel (often same texture as roughness) normalMap: normalTex, normalScale: new THREE.Vector2(1, 1), aoMap: aoTex, // ambient occlusion (uses uv2 by default; uv in r152+) aoMapIntensity: 1, displacementMap: dispTex, displacementScale: 0.1, displacementBias: 0, envMap: envTexture, // scene.environment is applied automatically envMapIntensity:1, emissive: new THREE.Color(0x000000), emissiveMap: emissiveTex, emissiveIntensity: 1, alphaMap: alphaTex, // luminance → alpha lightMap: lightTex, // pre-baked lighting (uses uv2) lightMapIntensity: 1, });
MeshPhysicalMaterial (Extended PBR)
const mat = new THREE.MeshPhysicalMaterial({ // All MeshStandardMaterial options, plus: clearcoat: 1.0, // clear lacquer layer (car paint) clearcoatRoughness: 0.1, clearcoatMap: ccTex, clearcoatNormalMap: ccNormalTex, sheen: 1.0, // velvet/fabric sheen sheenRoughness: 0.5, sheenColor: new THREE.Color(0xffffff), transmission: 1.0, // glass/water (0–1); replaces opacity for refractive ior: 1.5, // index of refraction (glass ≈ 1.5, diamond ≈ 2.4) thickness: 0.5, // refraction depth transmissionMap: transTex, iridescence: 1.0, // soap-bubble effect iridescenceIOR: 1.3, iridescenceThicknessRange: [100, 400], anisotropy: 1.0, // brushed metal anisotropic highlight anisotropyRotation: 0, specularIntensity: 1.0, specularColor: new THREE.Color(0xffffff), });
MeshPhongMaterial
const mat = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x000000, specular: 0x111111, // specular highlight color shininess: 30, // 0–100+; higher = tighter highlight map: colorTex, normalMap: normalTex, bumpMap: bumpTex, bumpScale: 1, specularMap: specTex, });
MeshToonMaterial
// Requires a gradient map for step-shading const gradientTex = new THREE.DataTexture( new Uint8Array([0, 128, 255]), // 3 shading levels 3, 1 ); gradientTex.magFilter = THREE.NearestFilter; gradientTex.needsUpdate = true; const mat = new THREE.MeshToonMaterial({ color: 0x00aaff, gradientMap: gradientTex, });
ShaderMaterial
const mat = new THREE.ShaderMaterial({ uniforms: { uTime: { value: 0.0 }, uColor: { value: new THREE.Color(0xff0000) }, uTex: { value: texture }, }, vertexShader: ` uniform float uTime; varying vec2 vUv; void main() { vUv = uv; vec3 pos = position; pos.y += sin(pos.x * 5.0 + uTime) * 0.1; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } `, fragmentShader: ` uniform vec3 uColor; varying vec2 vUv; void main() { gl_FragColor = vec4(uColor * vUv.x, 1.0); } `, transparent: false, side: THREE.FrontSide, }); // Update a uniform each frame mat.uniforms.uTime.value = clock.getElapsedTime();
Built-in GLSL Uniforms in ShaderMaterial
| Uniform | Type | Value |
|---|---|---|
modelMatrix | mat4 | Object world transform |
viewMatrix | mat4 | Camera view matrix |
projectionMatrix | mat4 | Camera projection |
modelViewMatrix | mat4 | viewMatrix * modelMatrix |
normalMatrix | mat3 | Inverse transpose of modelViewMatrix |
cameraPosition | vec3 | Camera world position |
Built-in GLSL Attributes in ShaderMaterial
| Attribute | Type | Value |
|---|---|---|
position | vec3 | Vertex position |
normal | vec3 | Vertex normal |
uv | vec2 | UV coordinates |
uv2 | vec2 | Second UV set |
color | vec3 | Vertex color |
SpriteMaterial / PointsMaterial
// Sprite — always faces camera const spriteMat = new THREE.SpriteMaterial({ map: spriteTexture, color: 0xffffff, sizeAttenuation: true, // scale with distance transparent: true, }); const sprite = new THREE.Sprite(spriteMat); // Points — particle cloud const pointsMat = new THREE.PointsMaterial({ size: 0.1, sizeAttenuation: true, color: 0xffffff, map: particleTexture, alphaMap: alphaTexture, transparent: true, depthWrite: false, // critical for transparent particles blending: THREE.AdditiveBlending, vertexColors: false, }); const points = new THREE.Points(geometry, pointsMat);
LineBasicMaterial / LineDashedMaterial
const lineMat = new THREE.LineBasicMaterial({ color: 0x00ff00, linewidth: 1, // NOTE: only 1 works in WebGL on most GPUs }); const dashedMat = new THREE.LineDashedMaterial({ color: 0xffffff, dashSize: 0.2, gapSize: 0.1, scale: 1, }); // REQUIRED for dashes to appear line.computeLineDistances();
Texture Maps Summary
| Map | Channel | Property |
|---|---|---|
| Albedo / Color | RGB | map |
| Normal | RGB | normalMap |
| Roughness | R or G | roughnessMap |
| Metalness | B | metalnessMap |
| Ambient Occlusion | R | aoMap |
| Emissive | RGB | emissiveMap |
| Alpha | R or A | alphaMap |
| Displacement | R | displacementMap |
| Environment | RGB cube / equirect | envMap |
| Light (baked) | RGB | lightMap |
| Bump | R | bumpMap |
Material Gotchas
transparent: truemust be set explicitly — opacity alone does nothing.
depthWrite: falseon transparent/additive materials prevents them from occluding objects behind them (important for particles).
side: THREE.DoubleSidedoubles draw calls for that material — use only when needed (open geometry, planes seen from both sides).
needsUpdate = trueis required when you switchtransparent,side,vertexColors, or add/removedefinesat runtime.
PBR materials require at least one light or an
envMap/scene.environmentto show anything other than black.
aoMapandlightMapuse the second UV set (uv2). Many GLTF exports already includeuv2; for custom geometry setgeo.setAttribute('uv2', geo.getAttribute('uv'))if they share the same UVs.