Вопрос по javascript, three.js – Как создать направленную светлую тень в Three.JS?

23

Можно ли создавать тени отDirectionalLight?

Если я используюSpotLight тогда я вижу тень, но если я используюDirectionalLight это не работает.

Можете ли вы поделиться кодом, который вы пробовали и который не работал? mrdoob
@mrdoob Я попробовал все, но все еще не работает. Код:jsfiddle.net/Q4uqE/1 eqiproo

Ваш Ответ

2   ответа
35

can использовать направленный свет, чтобы отбрасывать тени. Вы должны убедиться, что вы не используетеMeshBasicMaterial поскольку они не поддерживают тени. использованиеMeshLambertMaterial или жеMeshPhongMaterial вместо.

Вам нужно включить тени для рендерера с чем-то вроде этого:

renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;

renderer.shadowCameraNear = 3;
renderer.shadowCameraFar = camera.far;
renderer.shadowCameraFov = 50;

renderer.shadowMapBias = 0.0039;
renderer.shadowMapDarkness = 0.5;
renderer.shadowMapWidth = 1024;
renderer.shadowMapHeight = 1024;

И затем вы должны включить отбрасывание теней и получение теней для каждого объекта и для каждого света, чтобы вы имели

dirLight.castShadow = true;
object.castShadow = true;
otherObject.receiveShadow = true;

Затем,if свет и объекты размещены в соответствующих местах.dirLight вызовет теньobject быть брошенным противotherObject.

[EDIT]: Вотрабочая демо для тех, кто хочет сделать что-то подобное.

Все еще не работает. Код:jsfiddle.net/Q4uqE/1 eqiproo
Да, в вашей скрипке у вас есть направленный свет, расположенный внутри куба. Вот та же скрипка со светом, перемещенным вверх и наружу из куба.jsfiddle.net/Q4uqE/5
Ты знаешь почемуlight.shadowCameraVisible ничего не делает в этом раздвоенном примере?jsfiddle.net/Q4uqE/566
Как получается, что вы должны двигать свет? Из документа Three.js: & quot; Создает источник света, который светит с определенного направления, а не с определенной позиции. & Quot ;, изменение position.x должно просто изменить направление?
Разве параметры shadowCameraNear, shadowCameraFar, shadowCameraFov, shadowMapBias, shadowMapDarkness, shadowMapWidth и shadowMapHeight должны быть заданы для источника света, а не для средства визуализации?
48

что карты теней зависят от масштаба. Я работаю над сценой, где единичное расстояние составляет один метр, а мои объекты имеют размер около 0,4 метра. Это довольно мало по стандартам Three.js. Если у вас тоже есть такая ситуация, вы можете сделать несколько важных шагов:

Ensure the shadow camera's near/far planes are reasonable given your scene's dimensions. Ensure the shadow camera top/left/bottom/right values are not too large, otherwise each shadow 'pixel' may be so large that you don't even notice the shadow in your scene.

Давайте посмотрим, как это сделать.

Debugging

Не забудьте включить отладочный рендеринг для каждого источника света черезCameraHelper:

scene.add(new THREE.CameraHelper(camera)) 

Или в более старых версиях Three.js:

light.shadowCameraVisible = true;

Это покажет вам объем, на который рассчитывается тень. Вот пример того, как это может выглядеть:

Обратите внимание на ближнюю и дальнюю плоскости (с черными крестиками) и верхнюю / левую / нижнюю / правую части теневой камеры (внешние стены желтого прямоугольника). Вы хотите, чтобы этот прямоугольник был плотно прилегающим к любым объектам, которые вы собираетесь иметь в тень & # x2014; возможно, даже сильнее, чем я показываю здесь.

Code

Вот некоторые фрагменты кода, которые могут быть полезны.

var light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 2, 2);
light.target.position.set(0, 0, 0);
light.castShadow = true;
light.shadowDarkness = 0.5;
light.shadowCameraVisible = true; // only for debugging
// these six values define the boundaries of the yellow box seen above
light.shadowCameraNear = 2;
light.shadowCameraFar = 5;
light.shadowCameraLeft = -0.5;
light.shadowCameraRight = 0.5;
light.shadowCameraTop = 0.5;
light.shadowCameraBottom = -0.5;
scene.add(light);

Убедитесь, что некоторые объекты отбрасывают тени:

object.castShadow = true;

Убедитесь, что некоторые объекты получают тени:

object.receiveShadow = true;

Наконец, настройте некоторые значения наWebGLRenderer:

renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(canvasWidth, canvasHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
Есть ли хитрость, чтобы сделатьlight.shadowCameraVisible = true Работа? Похоже, что он ничего не делает в этом раздвоенном примере (из принятого ответа выше):jsfiddle.net/Q4uqE/566
Потрясающие. Спасибо за это.
В последних версиях Three.js следует использоватьCameraHelper вместоlight.shadowCameraVisible = true: scene.add(new THREE.CameraHelper(camera))

Похожие вопросы