Подтвердить что ты не робот

Как создать направленную светлую тень в Three.JS?

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

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

4b9b3361

Ответ 1

Да, вы, безусловно, можете использовать направленные света для отбрасывания теней. Вам нужно убедиться, что вы не используете 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;

Затем, если свет и объекты помещаются в соответствующие положения. dirLight приведет к тому, что тень object будет отлита от otherObject.

[EDIT]: Ниже приведена рабочая демонстрация для тех, кто хочет сделать что-то подобное. p >

Ответ 2

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

  • Обеспечьте, чтобы теневая камера приближалась/далека была разумной, учитывая размеры вашей сцены.
  • Убедитесь, что верхние/нижние/правые значения теневой камеры не слишком велики, иначе каждый пиксель тени может быть настолько большим, что вы даже не заметите тень в своей сцене.

Посмотрите, как это сделать.

Отладка

Обязательно включите визуализацию отладки на свет:

light.shadowCameraVisible = true;

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

N0SZvRy.png

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

Код

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

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;