Loading...
Loading...
Light and shade a three.js scene: choose materials (MeshStandardMaterial PBR vs unlit MeshBasicMaterial), add ambient/hemisphere/directional/point/spot lights, turn on shadow maps, and use an environment map (IBL) for realistic reflections. Use when a three.js model looks black, flat, or wrong — when the user mentions three.js materials, MeshStandardMaterial, lights, shadows, envMap, or PBR. For renderer/loop setup use threejs-scene-setup; for loading models use threejs-gltf-loading.
npx skill4agent add gamedev-skills/awesome-gamedev-agent-skills threejs-materials-lightingMeshStandardMaterialDirectionalLightrenderer.shadowMap.enabledscene.environmentthreejs-scene-setupthreejs-gltf-loadingShaderMaterialshader-programmingMeshStandardMaterialroughnessmetalnessMeshPhysicalMaterialMeshBasicMaterialMeshNormalMaterialMeshDepthMaterialscene.environmentAmbientLightHemisphereLightDirectionalLightDirectionalLightrenderer.shadowMap.enabled = truecastShadow = truecastShadowreceiveShadowscene.environmentimport * 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 shadowconst 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.environmentMeshBasicMaterialMeshNormalMaterialrenderer.shadowMap.enabledlight.castShadowcastShadowreceiveShadowDirectionalLightshadow.cameraleft/right/top/bottom/near/farshadow.mapSizenew THREE.CameraHelper(light.shadow.camera)light.shadow.biaslight.shadow.normalBiastexture.colorSpace = THREE.SRGBColorSpaceNoColorSpaceDirectionalLightMesh*MaterialalphaTestPMREMGeneratorRoomEnvironmentreferences/materials-lights-table.mdthreejs-scene-setupshadowMapthreejs-gltf-loadingshader-programming