开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
光源类型
设置光源对象是为了让场景中提高ThreeJS的渲染效果。因此,ThreeJS场景对象为Scene主要是由模型对象mesh和光源对象light构成的。例如:scene.add(mesh)、scene.add(light)。光源对象有几种不同光源的类型,如下图:
环境光(AmbientLight)
环境光一般是没有方向的,最多的是让物体对象明暗的现象。这环境光有两个参数,分别是颜色(color)和强度(intensity)。强度一般默认是1,数值越大灯光强度越亮。
// 环境光
const color = OxFFFFFF;
const intensity = 1;
const light = new THREE.AmbientLight(color, intensity);
// 让灯光添加到场景中
scene.add(light);
效果图:
平行光(DirectionalLight)
平行光一般像太阳光射线一样,但是和它们光源类型不同,就算有了光线方向,但是物体对象是起不作用的。因此这种平行光提供了位置.position和目标.target,同时一起可以确定平行光方向,例如这种目标.target就是一般针对在场景中任何一个三维模型对象光源的效果。
//平行光(DirectionalLight)
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(0, 10, 0);
light.target.position.set(-5, 0, 0);
scene.add(light);
scene.add(light.target);
效果图:
如果对于这种光源的位置及灯光的方向还是模糊,或者空间感不好的人,ThreeJS提供了有一堆辅助对象,可以让辅助对象到场景中,在场景中可以看出它们的方向及光源类型。
采用DirectionalLightHelper辅助对象加入到场景中,能可以实现看出它们的灯光。
//采用灯光光源
const helper = new THREE.DirectionalLightHelper(light);
scene.add(helper);
//创建一个调用平行光和目标的位置函数
function makeXYZGUI(gui, vector3, name, onChangeFn){
// gui组件的调用
const folder = gui.addFolder(name);
folder.add(vector3, 'x', -10, 10).onChange(onChangeFn);
folder.add(vector3, 'y', 0, 10).onChange(onChangeFn);
folder.add(vector3, 'z', -10, 10).onChange(onChangeFn);
folder.open();
}
function updateLight(){
light.target.updateMatrixWorld();
helper.update();
}
updateLight();
//GUI交互
const gui = new GUI();
gui.addColor(new ColorGUIHelper(light, 'color'), 'value').name('color');
gui.add(light, 'intensity', 0, 2, 0.01);
//平行光的位置
makeXYZGUI(gui, light.position, 'position', updateLight);
//平行光的目标
makeXYZGUI(gui, light.target.position, 'target', updateLight);
gui组件就是提供工具的,然后调灯光辅助工具的位置,在模型中支持可以实时更新灯光辅助工具的位置。注意:如果我们更改gui方向的属性的时候,一般需要调用gui的函数, 然后可以更新,所以,需要传入一个onChangeFn函数以在GUI更新值时调用。
效果图:
点光源(PointLight)
点光源一般是光线从发光核心向外发散。除了intensity和position,还附加属性有distance。如果distance为0,那么整个发光到无穷大。如果大于0的话,那么整个灯光强度照射在灯光上,而且远离灯光的位置,灯光强度就会减少。
// 点光源
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.PointLight(color, intensity);
light.position.set(0, 10, 0);
scene.add(light);
效果图:
聚光灯光源(SpootLight)
聚光灯一般是就会发散的光源,在场景中就像是圆锥体。除了position位置和target目标,还增加了angle、penumbra的属性。angle属性就是圆锥体的锥角大小,这个值越大,那么圆锥体的锥角就会变大;penumbra属性就是比如锥体的中心灯光强度减少到外锥体。
//聚光灯
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.SpotLight(color, intensity);
light.position.set(0, 10, 0);
light.target.position.set(-5, 0, 0);
scene.add(light);
scene.add(light.target);
效果图:
光源辅助对象
| 辅助对象 | 构造函数名 |
|---|---|
| 聚光源辅助对象 | SpotLightHelper |
| 点光源辅助对象 | PointLightHelper |
| 平行光光源辅助对象 | DirectionalLightHelper |
思考问题:
如果创建多个灯光,还有创建一个灯光对象,另一个创建不同的灯光对象,如何解决?这种基本可以解决,不建议创建过多个光源对象,至少两个不同的灯光对象即可。
// 聚光灯
const color = 0xFFFFFF; const intensity = 1;
const light = new THREE.SpotLight(color, intensity);
scene.add(light); scene.add(light.target);
// 点光源
const light1 = new THREE.PointLight(color, intensity);
light1.position.set(15, 10, 0);
scene.add(light1);
// 聚光灯辅助对象
const helper = new THREE.SpotLightHelper(light);
scene.add(helper);
// 点光源辅助对象
const helper1 = new THREE.PointLightHelper(light1);
scene.add(helper1);
效果图: