往期回顾:
物体的位置, 大小, 动画都离不开坐标系.
我们先了解坐标系对我们理解threejs
的3D世界是非常有帮助的
1 显示坐标系
threejs
采用的是右手坐标系
-
x轴水平方向: 向右为正
-
y轴垂直方向: 向上为正
-
z轴内外方向(垂直于xy平面): 向外为正
// 6. 显示坐标轴(x轴: 红色; y轴: 绿色; z轴: 蓝色 rgb)
// x轴水平方向(右正); y轴垂直方向(上正); z轴垂直xy平面即屏幕(外正)
const axesHelper = new THREE.AxesHelper(10)
scene.add(axesHelper)
完整示例:
// 导入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 = 100
// 5. 创建立方体(几何+材质)
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1)
const cubeMaterial = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
// 添加到场景
scene.add(cube)
// 6. 显示坐标轴(x轴: 红色; y轴: 绿色; z轴: 蓝色 rgb)
// x轴水平方向(右正); y轴垂直方向(上正); z轴垂直xy平面即屏幕(外正)
const axesHelper = new THREE.AxesHelper(10)
scene.add(axesHelper)
// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// 4. 渲染
renderer.render(scene, camera)
1. 将相机的z坐标设置为100, 在远处观察
2. 通过坐标辅助对象AxesHelper
显示三维坐标系
-
10表示显示的坐标的长度为10个单位(立方体的宽高为1个单位)
3. 将坐标辅助对象添加到场景中
但是我们并没有看到z轴
这是因为我们相机就位于z轴上在观察, 相当于侧视图
为了方便调试与观察.
我们可以使用OrbitControls
(轨道控制器)控制相机的位置
2 轨道控制器
轨道控制器可以改变相机在空间坐标系中的位置
进而方便从不同的角度观察物体
-
轨道控制器响应鼠标事件(按住左键旋转, 滚轮缩放, 按住右键平移)
-
调整相机在空间坐标系中的位置(坐标值)
-
改变坐标后, 重新渲染
相对运动
这里有两套坐标系统
-
3D世界的坐标系, 由红绿蓝三色线表示
-
相机观察的坐标系
由于人眼的位置是固定不变的, 相当于站在相机的角度看3D世界
相机不变, 3D世界做相对运动
效果
1) 导入组件
OrbitControls
是一个附加组件, 在使用之前需要先导入
// 导入轨道控制器
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
2) 创建控制器
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
-
相机对象
-
渲染dom
3) 动态渲染
// 4. 动态渲染
function animation() {
controls.update()
renderer.render(scene, camera)
requestAnimationFrame(animation)
}
animation()
完整示例
// 导入threejs
import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 1. 创建场景
const scene = new THREE.Scene()
// 2. 创建相机
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
1000
)
camera.position.z = 50
// 5. 创建立方体(几何+材质)
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1)
const cubeMaterial = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
// 添加到场景
scene.add(cube)
// 6. 显示坐标轴(x轴: 红色; y轴: 绿色; z轴: 蓝色 rgb)
// x轴水平方向(右正); y轴垂直方向(上正); z轴垂直xy平面即屏幕(外正)
const axesHelper = new THREE.AxesHelper(10)
scene.add(axesHelper)
// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// 7. 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
// 4. 动态渲染
function animation() {
controls.update()
renderer.render(scene, camera)
requestAnimationFrame(animation)
}
animation()
3 自适应画布
当浏览器的显示窗口改变时, 会引起尺寸改变(innerWidth/innerHeight).
此时, 需要调整相机的宽高比和渲染器的成像大小
// 监听window的resize事件, 在回调中重绘canvas
window.addEventListener('resize', () => {
// 设置相机宽高比
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
// 设置渲染器
renderer.setSize(window.innerWidth, window.innerHeight)
})
完整版视频教程,可以加小助手(whxzdjy)备注threejs