「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」
示例代码采用three.js-r73版本: cdnjs.cloudflare.com/ajax/libs/t…
上节我们介绍了环境光,这次我们再介绍一个光的种类平行光DirectionalLight
方向光
- 平行光又称为方向光(Directional Light),是一组没有衰减的平行的光线。
- 平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光 的效果; 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的。
- 构造函数
THREE.DirectionalLight = function ( color, intensity )
- color: 16进制颜色
- intensity:光线的强度,默认为1
- RGB的三个值均在0~255之间,不能反映出光照的强度变化,光照越强,物体表面就更明亮。它的取值范围是0到1。如果为0,表示光线基本没什么作用。
方向光的特点
- 使用方向光需要注意以下几点
- 方向光不能在物体里面
- 改变方向光的位置
- 改变方向光的强度
- 改变方向光的颜色
- 不做特殊设置,光是可以穿透物体的
我们通过示例来说明下这几种情况。写一下我们的示例,之前的代码删除掉光源相关设置即可,重新定义一个平行光
function initCamera() {
camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
camera.position.x = 600;
camera.position.y = 0;
camera.position.z = 600;
camera.up.x = 0;
camera.up.y = 1;
camera.up.z = 0;
camera.lookAt({ x: 0, y: 0, z: 0 });
}
var param;
var light;
var lightPos
function initLight() {
light = new THREE.DirectionalLight(0xFF0000, 1)
light.position.set(0, 0, 600)
scene.add(light)
}
效果如下:
- 我们设置了摄像机的位置(600, 0, 600),平行光的位置(0, 0, 600),物体的位置(0, 0, 0),
- 相对来说,摄像机是垂直屏幕,面向屏幕里的,所以坐标轴转动了。
方向光不能在物体里面
- 我们添加gui,来动态改变平行光的位置
var param;
var light;
var lightPos
function initLight() {
var ParamObj = function () {
this.x = 0;
this.y = 0;
this.z = 0;
}
param = new ParamObj();
var gui = new dat.GUI();
gui.add(param, "x", -10000, 10000).name('平行光X的位置')
gui.add(param, "y", -10000, 10000).name('平行光Y的位置')
gui.add(param, "z", -10000, 10000).name('平行光Z的位置')
// 平行光定义为红色
light = new THREE.DirectionalLight(0xFF0000, 1)
light.position.set(param.x, param.y, param.z)
scene.add(light)
}
- 默认平行光是在 (0, 0, 0) 的位置,也就是说光源的位置是在几何体里面的,光射向方向也是在里面的,已经形成一个点完全射不出来了,所以外面看不出来颜色了。
- 所以说:方向光不能在物体里面
改变方向光的位置
- 我们改变参数的时候,动态更新平行光位置
function changeLightPos() {
light.position.set(param.x, param.y, param.z);
}
function animation() {
changeLightPos();
renderer.render(scene, camera);
requestAnimationFrame(animation);
update()
}
- 我们改变xyz数值为正值,可以看到对应的颜色变化
- 我们改变xyz数值为负值,然后按住鼠标左键转动到背面,我们可以看到背面颜色的变化
- 所以说,改变方向光的位置会有变化
改变方向光的强度
- 我们在gui中添加光照强度的改变
function initLight() {
var ParamObj = function () {
...
this.intensity = 1;
}
...
gui.add(param, "intensity", 0, 1).name('平行光的光照强度')
...
}
function changeLightPos() {
light.position.set(param.x, param.y, param.z);
light.intensity = param.intensity
}
- 所以说:改变光的强度会有变化
改变方向光的颜色
我们通过一个颜色选择器插件,来动态改变光的颜色。
- 文档地址:jscolor.com/
- cdn地址:cdnjs.cloudflare.com/ajax/libs/j…
<input
class="color-pricker"
data-jscolor="{value:'#FF0000', alpha:1}"
onChange="colorPickerUpdate(this.jscolor, '#pr3')"
/>
function initColorPicker() {
jscolor.presets.default = {
width: 141, // make the picker a little narrower
position: 'top', // position it to the right of the target
previewPosition: 'right', // display color preview on the right
previewSize: 40, // make the color preview bigger
format: 'hex',
previewSize: 40,
closeButton: true,
closeText: '关闭',
palette: [
'#000000', '#7d7d7d', '#870014', '#ec1c23', '#ff7e26',
'#fef100', '#22b14b', '#00a1e7', '#3f47cc', '#a349a4',
'#ffffff', '#c3c3c3', '#b87957', '#feaec9', '#ffc80d',
'#eee3af', '#b5e61d', '#99d9ea', '#7092be', '#c8bfe7',
],
};
}
function colorPickerUpdate(picker, selector) {
const hex = '0x' + picker.toHEXString().replace(/#/, '')
light.color.setHex(hex)
}
- 我们改变方向光的颜色,看看几何体显示颜色的变化
- 我们可以看到,由于我们的几何体反射红光吸收其他颜色,当方向光的颜色中不包含红色时,就会变成黑色,改变方向光的颜色类似于改变方向光的强度
上述三个特征,codepen示例代码
不做特殊设置,光是可以穿透物体的
我们创建多个物体,来表示层级关系
function initObject() {
var geometry = new THREE.CubeGeometry(200, 100, 50, 4, 4);
var material = new THREE.MeshLambertMaterial({ color: 0xFF0000 });
var mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0);
scene.add(mesh);
var geometry2 = new THREE.CubeGeometry(200, 100, 50, 4, 4);
var material2 = new THREE.MeshLambertMaterial({ color: 0xFF0000 });
var mesh2 = new THREE.Mesh(geometry2, material2);
mesh2.position.set(-300, 0, 0);
scene.add(mesh2);
var geometry3 = new THREE.CubeGeometry(200, 100, 50, 4, 4);
var material3 = new THREE.MeshLambertMaterial({ color: 0xFF0000 });
var mesh3 = new THREE.Mesh(geometry3, material3);
mesh3.position.set(0, -150, 0);
scene.add(mesh3);
var mesh4 = new THREE.Mesh(geometry3, material3);
mesh4.position.set(0, 150, 0);
scene.add(mesh4);
var mesh5 = new THREE.Mesh(geometry3, material3);
mesh5.position.set(300, 0, 0);
scene.add(mesh5);
var mesh6 = new THREE.Mesh(geometry3, material3);
mesh6.position.set(0, 0, 100);
scene.add(mesh6);
}
改变光的位置,查看显示效果
- 我们可以看到,蓝色框中的两个物体,前面的物体把后面的物体遮挡住,但是后面的物体还是有颜色的,这是为什么呢?
- 在计算机中,目前我们没有计算投影,也没有设定前面的物体要挡住后面的物体,也没有设定前面物体把阴影投影到后面物体上,所以光直接透过去了,并且没有衰减。
- 所以,如果不做特殊设置,光是可以穿透物体的
总结
- 光的种类-平行光(方向光) DirectionalLight
- 方向光与位置和强度有关
- 方向光不能在物体里面
- 光的位置影响方向光
- 光的强度影响方向光
- 光的颜色影响方向光
- 不做特殊设置,光是可以穿透物体