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

MaterialLightingUse Case
MeshBasicMaterialNone (unlit)Wireframes, flat color overlays, debug
MeshLambertMaterialDiffuse onlyFast, non-specular surfaces
MeshPhongMaterialDiffuse + specularShiny surfaces, older style
MeshStandardMaterialPBR (metalness/roughness)Default choice for all real scenes
MeshPhysicalMaterialPBR + extra (clearcoat, sheen…)Car paint, glass, fabric, skin
MeshToonMaterialCel-shadedCartoon / stylized
MeshNormalMaterialEncodes normals as RGBDebug normals
MeshDepthMaterialEncodes depthShadow maps, depth effects
MeshMatcapMaterialMatcap textureFast stylized shading, no lights needed
SpriteMaterialBillboard 2D spriteParticles, billboards
LineBasicMaterialUnlit linesLines, wireframes
LineDashedMaterialDashed linesDashed outlines
PointsMaterialUnlit pointsParticle systems
ShaderMaterialCustom GLSLFull GPU control
RawShaderMaterialCustom 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

UniformTypeValue
modelMatrixmat4Object world transform
viewMatrixmat4Camera view matrix
projectionMatrixmat4Camera projection
modelViewMatrixmat4viewMatrix * modelMatrix
normalMatrixmat3Inverse transpose of modelViewMatrix
cameraPositionvec3Camera world position

Built-in GLSL Attributes in ShaderMaterial

AttributeTypeValue
positionvec3Vertex position
normalvec3Vertex normal
uvvec2UV coordinates
uv2vec2Second UV set
colorvec3Vertex 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

MapChannelProperty
Albedo / ColorRGBmap
NormalRGBnormalMap
RoughnessR or GroughnessMap
MetalnessBmetalnessMap
Ambient OcclusionRaoMap
EmissiveRGBemissiveMap
AlphaR or AalphaMap
DisplacementRdisplacementMap
EnvironmentRGB cube / equirectenvMap
Light (baked)RGBlightMap
BumpRbumpMap

Material Gotchas

transparent: true must be set explicitly — opacity alone does nothing.

depthWrite: false on transparent/additive materials prevents them from occluding objects behind them (important for particles).

side: THREE.DoubleSide doubles draw calls for that material — use only when needed (open geometry, planes seen from both sides).

needsUpdate = true is required when you switch transparent, side, vertexColors, or add/remove defines at runtime.

PBR materials require at least one light or an envMap / scene.environment to show anything other than black.

aoMap and lightMap use the second UV set (uv2). Many GLTF exports already include uv2; for custom geometry set geo.setAttribute('uv2', geo.getAttribute('uv')) if they share the same UVs.