DirectionalLightHelper 和 CameraHelper 之间的问题是否会导致场景阴影问题?

时间:2021-01-05 16:20:58

标签: javascript three.js

我正在使用three.js 在浏览器中构建相当复杂的静态渲染,并且在尝试使用单个THREE.DirectionalLight 代表我的场景中的太阳生成正确阴影的过程中很早就被卡住了。所有几何图形(包含在另一个 .js 文件中)都启用了阴影。绿色球体用于调试目的,并被平移 (50,0,50) 到平面的中心以表示相机的目标和 DirectionalLight.target 的位置。定向光位置和主摄像头位置设置正确。

我关于为什么阴影不起作用的理论是因为代表阴影摄像机的正交摄像机指向错误的方向。我昨天没能弄清楚并解决定向光助手(白线到原点)和阴影相机助手(右)的行为。

我假设了正确的方向,并且我的目标方向是定向光助手和阴影相机助手与平面中心对齐。经过昨天的大量研究,我的影子相机似乎没有自动拾取光位置/光目标矢量。为什么他们仍然锚定在原点?

有人对如何修复我的场景中的 DirectionalLight.target 有任何建议吗?为什么 DirectionalLightHelperCameraHelper 不一致?

// Set up
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
const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 500);
camera.position.set(200, 100, 100);
camera.lookAt(50, 0, 50);

// Lighting
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 Render
createBasicGeometry(scene); // from geometry.js
createGroundPlane(scene); // from geometry.js
renderer.render(scene, camera);

更新 2020-1-5

我最初尝试设置相机,还发现有人直接设置新的正射阴影相机的例子。由于我有动力克服这个问题,并且为了彻底,我更新了我的代码以反映建议,但不幸的是问题仍然存在。我已经重新检查了所有网格几何体是否都设置为 object.receiveShadow = trueobject.castShadow = true,并带有 MeshPhongMaterialdirectionalLight.target.position.set(50, 0, 50) 未按预期更新的原因完全令人困惑。这种行为的原因是什么?

// Updated Lighting
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);

当我转储 directionalLight 时,我得到了预期的目标位置,尽管在场景中没有正确对齐。而相机位置给出了另一个奇怪的结果。

console.log(directionalLight.target.position);
//Vector3 {x: 50, y: 0, z: 50, isVector3: true}
console.log(directionalLight.shadow.camera.position);

2 个答案:

答案 0 :(得分:1)

<块引用>

directionalLight.shadow.camera = new THREE.OrthographicCamera( -view_n, 视图_n, 视图_n, -view_n, 60, 150 );

请不要覆盖 LightShadow.camera 的相机参考。像这样配置定向光:

dirLight.castShadow = true;
dirLight.shadow.camera.top = view_n;
dirLight.shadow.camera.bottom = - view_n;
dirLight.shadow.camera.left = - view_n;
dirLight.shadow.camera.right = view_n;
dirLight.shadow.camera.near = 60;
dirLight.shadow.camera.far = 150;

除了阴影投射之外,仅当所有阴影投射对象(如您的盒子)都将 castShadow 设置为 true 时才有效。所有阴影接收对象(如您的地板)必须将 receiveShadow 设置为 true

答案 1 :(得分:0)

也许是因为我在没有动画循环的情况下静态地进行渲染,这个问题突然出现,但通过将 updateMatrixWorld 插入定向光目标解决了。 (不幸的是,我无法更新阴影的 camerahelper,但至少阴影现在按预期工作。)

directionalLight.target.updateMatrixWorld();
scene.add(directionalLight);
scene.add(directionalLight.target);
相关问题