Тени и почему объект чёрный
Самая частая загадка новичка: «добавил красивый материал, а куб чёрный». Разбираемся почему и включаем тени.
Материалы, кроме Basic, видны только за счёт отражённого света. Нет источников света — нечего отражать, поэтому поверхность чёрная.
Почему чёрный куб
Сценарий знаком каждому новичку: вы создали MeshStandardMaterial с ярким цветом, добавили меш — а на экране чёрный силуэт. Дело не в цвете. Физический материал не «светится» сам: он лишь отражает падающий на него свет. Если на сцене нет ни одного источника, отражать нечего — и вы видите черноту.
Лечение — добавить свет (см. прошлый урок). Хотя бы слабый Ambient уже покажет цвет; Directional добавит объём.
// было: чёрный куб
const cube = new THREE.Mesh(geo, new THREE.MeshStandardMaterial({ color: 0xff5544 }));
scene.add(cube);
// стало: добавили свет — куб виден
scene.add(new THREE.AmbientLight(0xffffff, 0.4));
const dir = new THREE.DirectionalLight(0xffffff, 1);
dir.position.set(5, 8, 5);
scene.add(dir);
Быстрый способ проверить, что проблема именно в свете: временно поставьте MeshBasicMaterial. Он игнорирует освещение — если объект стал виден, значит, не хватало света, а не объект «сломан».
Тени: три выключателя
Тени в Three.js выключены по умолчанию — они стоят дорого. Чтобы они появились, нужно щёлкнуть тремя «выключателями»:
- Включить тени у рендерера:
renderer.shadowMap.enabled = true. - Разрешить источнику отбрасывать тень:
light.castShadow = true(умеют Directional, Point, Spot; Ambient — нет). - У объектов указать, кто отбрасывает (
castShadow) и кто принимает (receiveShadow) тень.
renderer.shadowMap.enabled = true;
sun.castShadow = true; // источник отбрасывает тень
cube.castShadow = true; // куб отбрасывает
floor.receiveShadow = true; // пол принимает тень от куба
Логика человеческая: тень нужна, когда что-то (куб) загораживает свет и падает на что-то (пол). Поэтому у куба — castShadow, у пола — receiveShadow. Забыли одно из трёх — теней не будет.
Тени стоят дорого
Каждый источник с тенями заставляет рендерить сцену дополнительно с его точки зрения. Поэтому теней должно быть мало: обычно один теневой Directional на всю сцену. Качество регулируют разрешением теневой карты (light.shadow.mapSize) — больше значит чётче, но тяжелее.
Итог
- Чёрный объект = нет света; добавьте Ambient/Directional.
- Проверка: Basic-материал виден без света — значит, дело в освещении.
- Тени = три выключателя: renderer, light.castShadow, объекты cast/receive.