在three.js中,distance
设置与基于物理的照明有关意味着什么?
对于非基于物理的照明,distance
设置是灯光影响线性消失的设置。有效地
lightAffect = 1 - min(1, distanceFromLight / distance)
我不太了解基于物理的照明,但是在我看来,真实的照明没有距离设置,它们仅具有功率输出(流明)和基于大气密度的衰减。 Three.js既有power
设置又有decay
设置,尽管根本不清楚应将decay
设置为什么,因为文档实际上只是说将其设置为{{1} }。
例如,如果我要基于物理的照明,应该为基于物理的2
设置distance
吗?
PointLight
'use strict';
/* global dat */
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas: canvas});
renderer.physicallyCorrectLights = true;
const fov = 45;
const aspect = 2; // the canvas default
const zNear = 0.1;
const zFar = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, zNear, zFar);
camera.position.set(0, 10, 20);
camera.lookAt(0, 5, 0);
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
{
const planeSize = 40;
const planeGeo = new THREE.PlaneBufferGeometry(planeSize, planeSize);
const planeMat = new THREE.MeshPhongMaterial({
color: '#A86',
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(planeGeo, planeMat);
mesh.rotation.x = Math.PI * -.5;
scene.add(mesh);
} {
const cubeSize = 4;
const cubeGeo = new THREE.BoxBufferGeometry(cubeSize, cubeSize, cubeSize);
const cubeMat = new THREE.MeshPhongMaterial({color: '#8AC'});
const mesh = new THREE.Mesh(cubeGeo, cubeMat);
mesh.position.set(cubeSize + 1, cubeSize / 2, 0);
scene.add(mesh);
}
{
const sphereRadius = 3;
const sphereWidthDivisions = 32;
const sphereHeightDivisions = 16;
const sphereGeo = new THREE.SphereBufferGeometry(sphereRadius, sphereWidthDivisions, sphereHeightDivisions);
const sphereMat = new THREE.MeshPhongMaterial({color: '#CA8'});
const mesh = new THREE.Mesh(sphereGeo, sphereMat);
mesh.position.set(-sphereRadius - 1, sphereRadius + 2, 0);
scene.add(mesh);
}
{
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.PointLight(color, intensity);
light.power = 800;
light.distance = 20;
light.position.set(0, 10, 5);
scene.add(light);
light.decay = 2;
const helper = new THREE.PointLightHelper(light);
scene.add(helper);
const onChange = () => {
helper.update();
render();
};
setTimeout(onChange);
window.onresize = onChange;
const gui = new dat.GUI();
gui.add(light, 'distance', 0, 100).onChange(onChange);
gui.add(light, 'decay', 0, 4).onChange(onChange);
gui.add(light, 'power', 0, 3000).onChange(onChange);
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
}
}
main();
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
答案 0 :(得分:0)
至少从r95开始,通读three.js资料及其链接的纸张,对于基于物理的光源,距离设置基本上应该为Infinity
。
在论文中,他们指出了基于物理的灯光会发出无限远的光,但是在3D引擎中当然不好。大多数3D引擎需要计算每个绘制对象的最小灯光数量,因此添加了lightDistance
设置,如果灯光比lightDistance
更远,它们可以忽略该灯光。问题是,如果他们只是停止使用lightDistance
过去的光线,那么它们就会有锋利的边缘,因此他们陷入了崩溃。
three.js从论文中复制了lightDistance和falloff设置,但是three.js不会在灯光远处从计算中剔除灯光,因此似乎没有理由不将distance
设置为无穷远AFAICT至少从r95起。