我可能误会了一些东西,但是...我试图在three.js中使用物理上正确的照明和基于物理的渲染
我做了一个简单的场景。在这种情况下,只有一架飞机。我在飞机上方放了2个灯(2米)。飞机使用的MeshStandardMaterial
的{{1}}为.9,roughness
的为0。光的metalness
设置为800,如果我理解正确,则为800流明,这等效一个60瓦的灯泡我设置了power
。
结果如下:
该结果看上去与地板上方2米的60瓦灯泡完全不同。
我做错什么了吗?
renderer.physicallyCorrectLights = true
'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;
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.MeshStandardMaterial({
color: '#C84',
side: THREE.DoubleSide,
roughness: 0.9,
metalness: 0,
});
const mesh = new THREE.Mesh(planeGeo, planeMat);
mesh.rotation.x = Math.PI * -.5;
scene.add(mesh);
}
{
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.PointLight(color, intensity);
light.power = 800;
light.decay = 2;
light.distance = Infinity;
light.position.set(0, 2, 0);
scene.add(light);
const helper = new THREE.PointLightHelper(light);
scene.add(helper);
}
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);
}
render();
window.onresize = render;
}
main();
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
答案 0 :(得分:2)
在进行物理场景拍摄时,必须考虑曝光(光圈值)设置。我找不到相机的专用设置来允许此设置(也许会很自然地找到它),但是渲染器本身有一个曝光设置-
您可以使用渲染器上的toneMappingExposure
设置来寻找合适的值,例如:
renderer.toneMappingExposure = Math.pow(0.7, 5.0); // -> exposure: 0.168
例如更真实的功率值:
light.power = 740; // GE Lumens @ 60W incandescent
技术上的考虑:瓦特不能仅仅因为不同品牌在相同瓦特上产生不同的流明值而直接转换成流明;在60W白炽灯的情况下(GE使用740左右),它们实际上可以在400-1000流明之间变化。但这是一个副题..:)
'use strict';
/* global dat */
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas: canvas});
renderer.physicallyCorrectLights = true;
renderer.toneMappingExposure = Math.pow(0.7, 5.0);
const fov = 45;
const aspect = 2;
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.MeshStandardMaterial({
color: '#C84',
side: THREE.DoubleSide,
roughness: 0.9,
metalness: 0,
});
const mesh = new THREE.Mesh(planeGeo, planeMat);
mesh.rotation.x = Math.PI * -.5;
scene.add(mesh);
}
{
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.PointLight(color, intensity);
light.power = 740; // GE Lumens @ 60W incade.
light.decay = 2;
light.distance = Infinity;
light.position.set(0, 2, 0);
scene.add(light);
const helper = new THREE.PointLightHelper(light);
scene.add(helper);
}
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);
}
render();
window.onresize = render;
}
main();
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
<script src=" https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<canvas id="c"></canvas>