Currently, I am working on a complex static render in the browser using three.js and I have encountered an issue while trying to produce accurate shadows with a single THREE.DirectionalLight
that represents the sun in my scene. All the geometry in another .js file has shadows enabled. The green sphere serves as a debug tool and is moved to (50,0,50) at the center of the plane to indicate the camera target and location of DirectionalLight.target. Both the directional light position and main camera position are set correctly.
I suspect that the reason why the shadows are not functioning properly is because the orthogonal camera representing the shadow camera is not pointing in the correct direction. Despite trying to solve it yesterday, I couldn't figure out the behavior of the directional light helper (white line towards the origin) and the shadow camera helper.
My assumption is that for the correct orientation, the directional light helper and shadow camera helper should be aligned at the center of the plane. However, even after extensive research yesterday, my shadow camera does not seem to automatically detect the light position or light target vector. They still appear anchored to the origin. What could be causing this?
Does anyone have any suggestions on how to fix the DirectionalLight.target
in my scene? Why do the DirectionalLightHelper
and CameraHelper
show inconsistency?
// Initialization
const canvus = document.getElementById('canvus');
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
// Camera Setup
const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 500);
camera.position.set(200, 100, 100);
camera.lookAt(50, 0, 50);
// Lighting Configuration
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(100, 200, 200);
directionalLight.target.position.set(50, 0, 50);
directionalLight.castShadow = true;
directionalLight.shadow.bias = 0.0001;
directionalLight.shadow.mapSize.width = 1024; // default
directionalLight.shadow.mapSize.height = 1024; // default
const view_n = 50;
directionalLight.shadow.camera = new THREE.OrthographicCamera(
-view_n,
view_n,
view_n,
-view_n,
60,
150
);
scene.add(directionalLight, directionalLight.target);
// Helpers
const lighthelper = new THREE.DirectionalLightHelper(directionalLight, 10);
const camerahelper = new THREE.CameraHelper(directionalLight.shadow.camera);
scene.add(lighthelper);
scene.add(camerahelper);
// Main Rendering
createBasicGeometry(scene); // from geometry.js
createGroundPlane(scene); // from geometry.js
renderer.render(scene, camera);
Update 2020-1-5
Initially, I attempted setting the camera and also saw instances where people were directly setting a new ortho shadow camera. In my pursuit to resolve this issue, I made changes to reflect the suggestion but unfortunately, the problem persists. I double-checked that all mesh geometries are defined with both object.receiveShadow = true
and object.castShadow = true
, along with using MeshPhongMaterial
. It's perplexing why
directionalLight.target.position.set(50, 0, 50)
is not updating as anticipated. What could be triggering this behavior?
// Updated Lighting Configuration
const view_n = 50;
directionalLight.castShadow = true;
directionalLight.shadow.bias = 0.0001;
directionalLight.shadow.camera.right = view_n;
directionalLight.shadow.camera.left = -view_n;
directionalLight.shadow.camera.top = view_n;
directionalLight.shadow.camera.bottom = -view_n;
directionalLight.shadow.camera.near = 60;
directionalLight.shadow.camera.far = 150;
directionalLight.shadow.mapSize.width = 1024; // default
directionalLight.shadow.mapSize.height = 1024; // default
scene.add(directionalLight, directionalLight.target);
When I log the directionalLight
, I receive the expected target position, although it is not correctly aligned in the scene. Additionally, the camera position reveals unexpected results.
console.log(directionalLight.target.position);
//Vector3 {x: 50, y: 0, z: 50, isVector3: true}
console.log(directionalLight.shadow.camera.position);