From workflows
Configures three.js materials (MeshStandardMaterial PBR, MeshBasicMaterial) and lighting (ambient, directional, point, spot, hemisphere, IBL) with shadow maps. Use when a 3D model looks black, flat, or wrong.
How this skill is triggered — by the user, by Claude, or both
Slash command
/workflows:threejs-materials-lightingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Make three.js surfaces look right: pick the correct material, light the scene,
Make three.js surfaces look right: pick the correct material, light the scene, enable shadows, and add image-based lighting. Patterns target r165+, verified against r184 (lighting is physically based by default since r155).
MeshStandardMaterial, DirectionalLight, etc., or sets
renderer.shadowMap.enabled or scene.environment.When not to use: the renderer/camera/loop → threejs-scene-setup. Loading
models (whose PBR materials this complements) → threejs-gltf-loading. Custom
GLSL/ShaderMaterial is its own topic; for the portable concept see
shader-programming.
MeshStandardMaterial (PBR: roughness,
metalness, reacts to lights/IBL) for realism; MeshPhysicalMaterial for
clearcoat/transmission; MeshBasicMaterial (unlit, ignores lights) for UI/flat;
MeshNormalMaterial/MeshDepthMaterial for debugging.scene.environment. Combine a soft fill (AmbientLight/HemisphereLight) with a
key DirectionalLight.DirectionalLight ≈ 1–3).renderer.shadowMap.enabled = true, the
light's castShadow = true, and each mesh's castShadow/receiveShadow. Then
fit the light's shadow camera to the scene.scene.environment; PBR materials pick it up
automatically.import * as THREE from 'three';
const material = new THREE.MeshStandardMaterial({
color: 0xcc4444,
roughness: 0.5, // 0 = mirror, 1 = fully matte
metalness: 0.0, // 0 = dielectric (plastic/wood), 1 = metal
});
const mesh = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 16), material);
scene.add(mesh);
// Soft sky/ground fill + a directional key light.
scene.add(new THREE.HemisphereLight(0xbbddff, 0x443322, 1.0)); // sky, ground, intensity
const key = new THREE.DirectionalLight(0xffffff, 2.5);
key.position.set(5, 10, 7);
scene.add(key);
// MeshBasicMaterial ignores lights — for flat color, UI, or sprites/labels.
const flat = new THREE.MeshBasicMaterial({ color: 0x44aa88 });
// A textured color map should be tagged sRGB so colors aren't washed out:
const tex = new THREE.TextureLoader().load('assets/logo.png');
tex.colorSpace = THREE.SRGBColorSpace;
const logo = new THREE.MeshBasicMaterial({ map: tex, transparent: true });
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // softer edges
const sun = new THREE.DirectionalLight(0xffffff, 3);
sun.position.set(8, 12, 6);
sun.castShadow = true;
sun.shadow.mapSize.set(2048, 2048); // default 512; raise for crisp
// DirectionalLight uses an OrthographicCamera — fit it tightly to the scene:
const cam = sun.shadow.camera;
cam.near = 1; cam.far = 40;
cam.left = -15; cam.right = 15; cam.top = 15; cam.bottom = -15;
scene.add(sun);
mesh.castShadow = true;
ground.receiveShadow = true; // a plane to catch the shadow
const loader = new THREE.TextureLoader();
const colorMap = loader.load('assets/brick_color.jpg');
colorMap.colorSpace = THREE.SRGBColorSpace; // color maps are sRGB
const normalMap = loader.load('assets/brick_normal.jpg'); // data maps stay linear
const roughMap = loader.load('assets/brick_rough.jpg');
const brick = new THREE.MeshStandardMaterial({
map: colorMap,
normalMap,
roughnessMap: roughMap,
metalness: 0,
});
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
new RGBELoader().load('assets/studio.hdr', (hdr) => {
hdr.mapping = THREE.EquirectangularReflectionMapping;
scene.environment = hdr; // lights + reflects all PBR materials
scene.background = hdr; // optional: show it as the backdrop
});
// Optional cinematic tone curve:
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;
scene.environment.
Add a light or an environment map; to confirm geometry, temporarily swap to
MeshBasicMaterial/MeshNormalMaterial.renderer.shadowMap.enabled, light.castShadow, mesh castShadow/
receiveShadow).DirectionalLight's orthographic
shadow.camera frustum is too big/small or doesn't cover the scene; tighten
left/right/top/bottom/near/far and raise shadow.mapSize. Visualise it with
new THREE.CameraHelper(light.shadow.camera).light.shadow.bias (small negative) and
light.shadow.normalBias.texture.colorSpace = THREE.SRGBColorSpace; normal/roughness/metalness maps must
stay linear (leave them as NoColorSpace).DirectionalLight; use cheaper fakes
elsewhere.Mesh*Material for which look), light types
and their parameters/units, transparency vs alphaTest ordering, and the
PMREMGenerator/RoomEnvironment route to IBL without an HDR file, read
references/materials-lights-table.md.threejs-scene-setup — renderer, camera, and loop (set shadowMap, tone mapping).threejs-gltf-loading — models arrive with PBR materials this skill tunes.shader-programming — custom shader effects (engine-agnostic concept).npx claudepluginhub gamedev-skills/awesome-gamedev-agent-skills --plugin gamedevGuides on Three.js materials including MeshBasic, Lambert, Phong, Standard (PBR), Physical, Toon, shaders. Covers styling meshes, textures, lighting, custom shaders, performance optimization.
Provides Three.js API references, best practices, and code examples for scene setup, geometry, materials, lighting, textures, animation, loaders, shaders, postprocessing, and interaction in 3D web apps.
Builds interactive 3D web scenes with Three.js using WebGL/WebGPU. Guides on scenes, cameras, renderers, geometries, materials, meshes, lights, animations, and OrbitControls.