前言
在上篇文章中,我们学习了如何去创建一个基础的 3D 内容,而在上篇文章中,我们可以看到我们构建的内容可以看作是一个静止不动的平面,没有 3D 物体的透视感。这节课我们便来学习如何让物体具有“立体感” 与 如何能够控制视角的移动。
光照(让物体有了立体感)
原理
在 3D 世界中,如果想要一个物体具有立体感,我们需要让这个物体的表面具有一定的明暗关系,这时我们便需要将物体的材质更换为具有反射的材质。然后通过一个光源对物体进行照射,从而使得物体表面具有一定的明暗变化,最终使得物体具有 "立体感" 。
材质的改变
在本节,我们通过将材质更改为 MeshLambertMaterial 使得物体表面的材质不再是光滑的表面,他会使得物体的表面具有反射的效果,从而使得不同的位置具有不同的明暗效果。
const material = new THREE.MeshLambertMaterial({
color: 0x00ffff,
side: THREE.DoubleSide, // 决定你的材质是单面还是双面
})
光照
在具有一个能够处理反射的物体后,还需要一个具有衰减的光源来照射物体。从而使得物体表面的亮度具有一定的衰减趋势,而通过点光源便能很好的满足我们的需求。
const light = new THREE.PointLight(0xffffff, 0.4)
light.position.set(500, 300, 200)
scene.add(light)
OrbitControls.js(开启旋转缩放等功能)
原理
在 3D 世界中,所谓的旋转与缩放等操作,实际上就是更改摄像机的位置信息。并且根据上一篇文章,我们得知,当我们想看到摄像机的内容时,我们需要重新渲染当前的视图。因此,我们需要对摄像机的信息进行监听,在其发生变化后重新进行渲染。
const controls = new THREE.OrbitControls(camera, render.domElement)
controls.addEventListener('change', () => {
// 监听然后重新渲染
render.render(scene, camera)
})
一些可能用到的 API
minDistance / maxDistance
用于限制可以移动的最大和最小距离
autoRotate
autoRotate 指的是自动旋转,但需要搭配 update 方法与 定时渲染方法 进行使用(这里下一篇文章会涉及到)
示例代码
// 创建三维场景
const scene = new THREE.Scene()
// 创建一个正方形
const geometry = new THREE.BoxGeometry(100, 100, 100)
// 创建一个材质
const material = new THREE.MeshLambertMaterial({
color: 0x00ffff,
side: THREE.DoubleSide, // 决定你的材质是单面还是双面
})
const axios = new THREE.AxesHelper(300)
scene.add(axios)
// 创建一个网格模型对象
const mesh = new THREE.Mesh(geometry, material)
// 将网格模型对象添加到三维场景中
scene.add(mesh)
// 创建光源
const abbientLight = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(abbientLight)
// 创建点光源
const light = new THREE.PointLight(0xffffff, 0.4)
light.position.set(500, 300, 200)
scene.add(light)
// 创建透视相机
const width = 1500
const height = 700
const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000)
// 摄像机的起始位置
camera.position.set(200, 200, 200)
// 摄像机对准的位置
camera.lookAt(0, 0, 0)
// 创建渲染器
const render = new THREE.WebGLRenderer()
render.setSize(width, height)
// 渲染出内容
render.render(scene, camera)
// 输出内容
document.body.appendChild(render.domElement)
const controls = new THREE.OrbitControls(camera, render.domElement)
controls.addEventListener('change', () => {
// 监听然后重新渲染
render.render(scene, camera)
})
下章预告
---《Three.js 入门指南:让 3D 场景“可交互”的魔法》