简介
本系列教程需要具备threejs的基础入门知识,了场景、几何体、相机等基础概念。
学习本教程之前,建议学习【几何体】的基础知识。
根据前置知识,我们能够实现一个如下的3D效果
在这个示例中,我们使用PlaneGeometry创建了平面几何体
const geometry = new THREE.PlaneGeometry(5, 5);
使用texture设置了其纹理贴图
// 创建纹理
const texture = new THREE.TextureLoader().load("/bg.jpg");
并且通过uv坐标设置了其纹理贴图的渲染范围
// 创建平面几何体
const geometry = new THREE.PlaneGeometry(5, 5);
// 创建纹理
const texture = new THREE.TextureLoader().load("/bg.jpg");
// 定义uv的取值范围,左上、右上、左下、右下
const uv = new Float32Array([0, 1, 0.5, 1, 0, 0, 0.5, 0]);
geometry.attributes.uv = new THREE.BufferAttribute(uv, 2);
const material = new THREE.MeshBasicMaterial({
map: texture, side: THREE.DoubleSide });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
光照对物体的影响
实际生活中物体表面的明暗效果是会受到光照的影响,比如晚上不开灯,你就看不到物体,灯光比较暗,物体也比较暗。在threejs中,咱们用网格模型Mesh模拟生活中物体,所以threejs中模拟光照Light对物体表面的影响,就是模拟光照Light对网格模型Mesh表面的影响。
上述代码示例中,我们使用了MeshBasicMaterial设置了物体的材质,这种材质是不受光照影响的,所以有没有光都无所谓。
我们将MeshBasicMaterial材质换成一种漫反射材质MeshLambertMaterial试试
很明显,这种材质如果没有光照就会是一团黑。
我们给他加一个环境光试试
// 添加光源
const light = new THREE.AmbientLight(0xffffff, 1);
scene.add(light);
可见,这种受到光照影响的材质有了光源后才能被我们看见。
现在,我们对光源已经有了初步的了解,现在我们学习一下光照影响的材质、光源等更详细的知识
受光照影响材质
threejs提供的网格材质,有的受光照影响,有的不受光照影响。
基础网格材质MeshBasicMaterial(opens new window)不会受到光照影响。
//MeshBasicMaterial不受光照影响
const material = new THREE.MeshBasicMaterial();
漫反射网格材质MeshLambertMaterial(opens new window)会受到光照影响。受光照影响的材质,在相同光源下,表现的特性也是不一样的。
创建光影观察模型
为了更好的演示灯光对物体的影响,我们创建一个面
// 2.1创建地面模型
const floorMesh = new THREE.Mesh(
new THREE.PlaneGeometry(10, 10),
// 使用高光材质
new THREE.MeshPhongMaterial({
side: THREE.DoubleSide, color: 0x1b5e20 })
);
scene.add(floorMesh);
面上有一个立方体
// 2.2创建一个立方体
const boxMesh = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
// 使用高光材质
new THREE.MeshPhongMaterial({
color: 0x0099ff })
);
scene.add(boxMesh);
上述代码中,我们使用了高光材质,但是没有设置光源,因此,物体表面是黑色的。
不同光源下的物体渲染效果
光源简介
Three.js提供了多种模拟生活中光源的API,文档搜索关键词light就可以看到。
环境光AmbientLight
环境光会均匀的照亮场景中的所有物体,它没有方向,不能用来投射阴影。
API:https://threejs.org/docs/?q=AmbientLight#api/zh/lights/AmbientLight
构造函数
AmbientLight( color : Color, intensity : Float )
我们试着添加一个环境光源
// 添加光源
const light = new THREE.AmbientLight(0xffffff, 1);
scene.add(light);
可以看出,环境光会照亮所有物体,而且物体的每个位置光照颜色是一致的。
我们更改光照强度试试
物体位置移动
现在立方体的位置卡在平面中间,看着很难受,我们把它抬高一点。
点光源PointLight
点光源PointLight(opens new window)可以类比为一个发光点,就像生活中一个灯泡以灯泡为中心向四周发射光线。
PointLight构造函数:
PointLight( color : Color, intensity : Float, distance : Number, decay : Float )
- color -(可选)一个表示颜色的 Color 的实例、字符串或数字,默认为一个白色(0xffffff)的 Color 对象。
- intensity -(可选)光照强度。默认值为 1。
- distance - 光源照射的最大距离。默认值为 0(无限远)。
- decay - 沿着光照距离的衰退量。默认值为 2。
我们试着添加一个点光源
// 添加点光源
const pointLight = new THREE.PointLight(0xffffff, 100, 100);
// 设置光源位置
pointLight.position.set(5, 3, 5);
scene.add(pointLight);
反光强度
MeshPhongMaterial材质的物体在点光源下可以设置不同的反光程度
API:https://threejs.org/docs/index.html?q=MeshPhongMaterial#api/zh/materials/MeshPhongMaterial
// 2.2创建一个立方体
const boxMesh = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
// 使用高光材质
new THREE.MeshPhongMaterial({
color: 0x0099ff,
+ shininess: 800
})
);
实现物体阴影效果
在光照下,立方体盒子应该在地面上有个阴影,实现这个效果需要以下几步
打开物体的投射光源功能
// 物体投射光源
boxMesh.castShadow = true;
打开地面的接受光源光源功能
// 地面接受光源
floorMesh.receiveShadow = true;
打开点光源的投射光源功能
// 投射光源
pointLight.castShadow = true;
启用渲染器的阴影渲染开关
// 渲染器的阴影渲染开关
renderer.shadowMap.enabled = true;