Skip to content
Frontend
Skill

/threejs-materials

Choosing and configuring three.js materials - unlit, diffuse, specular, PBR, toon, point and line materials - shared properties like blending and stencil, environment response, and the WebGPU node-material and TSL equivalents. Use when styling meshes or tuning material behavior.

From plugin
threejs-skills
3.9k13 skills

Claude Code

$ npx -y skills add cloudai-x/threejs-skills --skill threejs-materials --agent claude-code

SKILL.md

threejs-materials.SKILL.md
name: threejs-materials
description: "Choosing and configuring three.js materials - unlit, diffuse, specular, PBR, toon, point and line materials - shared properties like blending and stencil, environment response, and the WebGPU node-material and TSL equivalents. Use when styling meshes or tuning material behavior."

Three.js Materials

Targets three.js r186. Examples use WebGLRenderer; the WebGPU and TSL section uses WebGPURenderer.

Quick Start

import * as THREE from "three";

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 0, 3);

// PBR material - the default choice for lit, realistic surfaces
const material = new THREE.MeshStandardMaterial({
  color: 0x00aaff,
  roughness: 0.35,
  metalness: 0.1,
});
const mesh = new THREE.Mesh(new THREE.SphereGeometry(1, 48, 32), material);
scene.add(mesh);
scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 1)); // lit materials render black without lights
const light = new THREE.DirectionalLight(0xffffff, 2);
light.position.set(3, 3, 3);
scene.add(light);

function animate() {
  mesh.rotation.y += 0.01;
  renderer.render(scene, camera);
}

renderer.setAnimationLoop(animate);

Material Types Overview

| Material | Use case | Lighting | | -------------------- | ------------------------------------- | ------------------ | | MeshBasicMaterial | Unlit color, textures, wireframes | None | | MeshLambertMaterial | Matte diffuse surfaces | Diffuse | | MeshPhongMaterial | Shiny plastic, cheap specular | Diffuse + specular | | MeshStandardMaterial | PBR metal/rough workflow | PBR | | MeshPhysicalMaterial | PBR plus clearcoat, transmission, sheen, iridescence | PBR | | MeshToonMaterial | Cel shading | Toon steps | | MeshMatcapMaterial | Lit look baked into a matcap texture, no lights needed | Baked | | ShadowMaterial | Transparent surface that shows only the shadows it receives | Shadows only | | PointsMaterial | Point clouds | None | | LineBasicMaterial / LineDashedMaterial | Lines | None | | ShaderMaterial / RawShaderMaterial | Custom GLSL, WebGLRenderer only | Custom |

Color data textures (map, emissiveMap, specularMap, sheenColorMap, specularColorMap, LDR matcap, a canvas or video used as color) need `texture.colorSpace = THREE.SRGBColorSpace`, or colors render washed out. Scalar maps (normal, bump, displacement, roughness, metalness, ao, alpha, toon gradientMap) keep the default. HDR loaders set their own color space.

MeshBasicMaterial

No lighting calculations. Fast, always visible. Supports `envMap` with `reflectivity` (0 to 1) and `combine` (`THREE.MultiplyOperation`, `THREE.MixOperation`, `THREE.AddOperation`); `specularMap` (sRGB) masks the env-map contribution.

const map = await new THREE.TextureLoader().loadAsync("color.jpg");
map.colorSpace = THREE.SRGBColorSpace;

const material = new THREE.MeshBasicMaterial({
  color: 0xffffff, // multiplied with the map
  map,
  transparent: true,
  opacity: 0.5,
  side: THREE.DoubleSide, // FrontSide (default), BackSide, DoubleSide
  fog: true, // affected by scene fog
});

MeshLambertMaterial and MeshPhongMaterial

Lambert is diffuse-only. Phong adds a specular highlight; it is the cheap alternative when Standard is too heavy.

const lambert = new THREE.MeshLambertMaterial({
  color: 0x00ff00,
  emissive: 0x111111, // self-illumination color
  emissiveIntensity: 1,
});

const phong = new THREE.MeshPhongMaterial({
  color: 0x0000ff,
  specular: 0x111111, // highlight color
  shininess: 30, // higher = sharper highlight
  flatShading: false, // flat vs smooth normals
});

Both also support `map`, `emissiveMap`, `specularMap` (sRGB; masks the env-map reflection, and the highlight on Phong), `normalMap`, `bumpMap`, `displacementMap`, `aoMap`, `envMap`, `envMapIntensity` and `envMapRotation`.

MeshStandardMaterial (PBR)

Physically-based rendering. Recommended for realistic results.

const map = await new THREE.TextureLoader().loadAsync("color.jpg");
map.colorSpace = THREE.SRGBColorSpace;
const ormMap = await new THREE.TextureLoader().loadAsync("orm.jpg"); // glTF ORM: ao red, roughness green, metalness blue; scalar: keep default

const material = new THREE.MeshStandardMaterial({
  color: 0xffffff, // multiplied with the map
  roughness: 1.0, // 0 = mirror, 1 = fully diffuse; multiplied by roughnessMap (green)
  metalness: 1.0, // 0 = dielectric, 1 = metal; multiplied by metalnessMap (blue), so keep 1 with a map
  map,
  roughnessMap: ormMap,
  metalnessMap: ormMap,
  normalMap: null, // surface detail; scale with normalScale (a Vector2)
  aoMap: ormMap, // ambient occlusion (red); intensity with aoMapIntensity
  displacementMap: null, // vertex displacement; scale with displacementScale, offset with displacementBias
  emissive: 0x000000,
  emissiveIntensity: 1,
  emissiveMap: null, // sRGB
  envMap: null, // or rely on scene.environment (see below)
  fog: true,
});

`lightMap` (with `lightMapIntensity`) bakes indirect light the same way aoMap bakes occlusion; an HDR or EXR lightMap is `LinearSRGBColorSpace`, which the loaders set.

UV channels: aoMap and lightMap read the channel you pick

Every UV-mapped texture samples the attribute selected by `texture.channel`: 0 reads `uv` (the default), 1 reads `uv1`, 2 reads `uv2`, 3 reads `uv3`. aoMap and lightMap need no second UV set - they sample `uv` unless you change `channel`. GLTFLoader loads `TEXCOORD_1` as `uv1` and sets `channel` itself.

const aoMap = await new THREE.TextureLoader().loadAsync("ao.jpg"); // scalar: keep default
const material = new THREE.MeshStandardMaterial({ aoMap }); // samples uv: no extra attribute
Read more
@cloudai-x
Ships withthreejs-skills

Skill files that give Claude Code current, verified knowledge of three.js, so the code it writes runs on the release you actually install. The skills target three.js r186 (three@0.186), React Three Fiber 9.8 with drei 10.7, and gltf-transform 4.5.

Stars on GitHub

Momentum

stars in total
3.9k
Star history of cloudai-x/threejs-skills on GitHub, a chart by star-history.com

Other skills on threejs-skills.

threejs-geometry

threejs-geometry

Creating and shaping three.js geometry: built-in shapes, 3D text, vertex buffers and attributes, merging, instancing, batching,…

threejs-lighting

threejs-lighting

Light types and physical units, shadow maps, HDR environment lighting, light probes, and lighting performance, on WebGL or with…

More skills from other plugins.

next-bundle-optimizer
Auto-invoked

next-bundle-optimizer

Audit and reduce Next.js browser initial-load work. Use for slow route startup, oversized client bundles, duplicate browser…

nextjs1d143k
@vercel@vercelInstall Skill
migrate-radix-to-base

migrate-radix-to-base

Migrates React projects and components from Radix UI to Base UI. Use when asked to migrate from radix, move to base-ui, convert…

ui10d127k
@shadcn-ui@shadcn-uiInstall Skill
chrome-release-cls

chrome-release-cls

Given a Chrome Releases blog post URL (chromereleases.googleblog.com), extract every CVE/bug and find the underlying Gerrit CL…

electron1d124k
@electron@electronInstall Skill
taste-skill
Auto-invoked

taste-skill

tasteskill v2, the anti-slop frontend skill. Art direction for websites, distilled from a study of 247 curated gallery sites (One…

@leonxlnx@leonxlnxInstall Skill

Questions about threejs-materials.

Which coding agents can use threejs-materials?
threejs-materials installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.