01 起步案例:
接下来, 我们通过一个起步案例来快速体验threejs
基础概念
在三维世界中, 有这样几个概念我们需要先理解
-
场景
-
相机
-
物体
-
光源
1) 场景
如何理解场景
场景就是一个三维的世界, 在这个世界中可以放置各种各样的物体
可以理解成一个空间, 或者容器
2) 相机
如何理解相机
思考: 如何在二维平面表现三维效果
由于我们的显示器是二维平面, 只有两个维度, 如何在一个二维平面表现出三维效果呢?
在现实生活中, 得益于拍照技术, 从不同的角度拍射(观察)同一个物体, 然后通过一些光照阴影我们的大脑可以自行脑补出三维的画图
这里的相机就是三维空间的观察者
当相机从不同的角度观察同一个物体会得到不同的图像, 然后把这些图像使用一定的技术拼接组合, 我们的大脑会根据生活在三维世界的经验自行脑补出三维空间
3) 物体
在三维空间, 可以放置一些物体, 这些物体就是被观察的对象
不同的物体形状, 大小, 材质和纹理不相同
尽可能模拟现实生活中的实际物体, 比如:
three.js实现3D看车
4) 光源
为了更好的模拟三维效果, 需要一些光照和阴影
2 实现步骤
使用three.js需要这样几步
-
创建一个三维场景(Scene)
-
创建一个相机(Camera)
-
创建渲染器渲染(Renderer)
1) 创建三维场景
const scene = new THREE.Scene()
2) 创建相机
// 2. 创建透视相机
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
1000
)
camera.position.z = 5
3) 创建渲染器
// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// 4. 渲染
renderer.render(scene, camera)
如何理解渲染
渲染就是拿相机在场景中拍照, 拍的照片显示在canvas画布上
上述完整示例
// 导入threejs
import * as THREE from 'three'
// 1. 创建场景
const scene = new THREE.Scene()
// 2. 创建透视相机
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
1000
)
camera.position.z = 5
// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// 4. 渲染
renderer.render(scene, camera)
4) 添加物体
创建一个立方体, 添加到场景中
在three.js中, 使用Mesh(网格)表示一个物体, 包括
-
几何形状(Geometry)
-
表面材质(Material)
// 5. 创建立方体(几何+材质)
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1)
const cubeMaterial = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
// 添加到场景
scene.add(cube)
上述代码
-
创建了长宽高均为1个单位的立方体BoxGeometry
-
使用法向量材质MeshNormalMaterial
-
基于几何形状和材质创建立方体
-
添加到场景中
效果
思考:为什么感觉是一个二维的正方形?
5) 添加动画
为了方便观察三维效果, 我们可以使用两种方式
-
物体不变, 相机围绕物体旋转, 从不同的位置观察
-
相机不变, 物体旋转
这里, 为了便于大家理解, 我们先固定相机, 通过动画旋转物体演示
function animation() {
// 改变角度
cube.rotation.x += 0.01
cube.rotation.y += 0.01
// 重新渲染
renderer.render(scene, camera)
// 下一帧渲染回调
requestAnimationFrame(animation)
}
animation()
6) 渲染优化
上述我们会看到明显的锯齿, 显示也不够清晰, 这里我们通过设置两个参数, 改善渲染效果
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
上述代码
-
通过设置渲染器的antialias属性为true, 开启抗锯齿
-
设置DPI, 使用更多的像素点来描述同一个物体
完整示例:
// 导入threejs
import * as THREE from 'three'
// 1. 创建场景
const scene = new THREE.Scene()
// 2. 创建相机
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
1000
)
camera.position.z = 5
// 5. 创建立方体(几何+材质)
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1)
const cubeMaterial = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
// 添加到场景
scene.add(cube)
// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// 4. 渲染
function animation() {
// 改变角度
cube.rotation.x += 0.01
cube.rotation.y += 0.01
// 重新渲染
renderer.render(scene, camera)
// 下一帧渲染回调
requestAnimationFrame(animation)
}
animation()