前言
许久未着手写代码,手已有些许生疏,近期开始可能会需要投入较多的时间。无意间发现一个有趣的技术——three.js,主要用于实现在Web应用中的3D场景绘制。下定决心好好学习一下,也许以后用得上(可以是静态的html页面,也可以是vue应用中使用),将从基础篇开始,根据three.js官方说明文档,结合相关博客进行学习。
相关链接:
three.js官方说明文档
含上百个three.js案例的大佬博客
正文
基础介绍和实现
本篇基于静态HTML页面进行讲述,使用vue的相关步骤将在之后有时间进行梳理。
使用three.js进行3D页面的绘制主要包括以下几个步骤:
1.准备好three.js
到官网或three.js的GitHub仓库下载压缩包后找到名为three.js的文件,存放至即将存放HTML文件的位置即可。
2.创建HTML文件,其内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
// Our Javascript will go here.
</script>
</body>
</html>
我们将在注释下方完成后续内容
3.创建场景、相机和渲染器
代码及注释说明如下:
//场景
const scene = new THREE.Scene()
/*相机-使用的是透视摄像机
--参数1:视野角度——任何时候你能看到的场景的范围
--参数2:长宽比——宽÷高
--参数3:近截面,比近截面近的部分不会被渲染
--参数4:远截面,比远截面远的部分不会被渲染
*/
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
//渲染器
const renderer = new THREE.WebGLRenderer();
//设置渲染器尺寸,一般使用所渲染区域的宽高
renderer.setSize(window.innerWidth, window.innerHeight)
//将渲染器的dom元素添加到HTML文档中
document.body.appendChild(renderer.domElement)
4.添加立方体
这里添加的是立方体,实际上以及在后面的实例中将会才用更复杂的模型如平面模型结合视角变换、立体模型等。相关代码及注释如下:
// Add box
//创建立方体对象
const geometry = new THREE.BoxGeometry(1, 1, 1)
//设定材质
const material = new THREE.MeshBasicMaterial({color: 0x00ff00})
//设定网格,存放几何体和材质
const mesh = new THREE.Mesh(geometry, material)
//将网格添加至场景中
scene.add(mesh)
//调整相机位置
camera.position.z = 5
需要注意的是,当我们调用scene.add()时,添加的物体坐标将会是(0,0,0),使得摄像机和立方体贴合在一起,因此我们需要调整相机位置。
5.渲染场景并使立方体动起来
在这部分,我们将编写一个函数实现动画循环(渲染循环),相关代码和注释如下:
//动画渲染函数
function animate() {
//创建一个循环 使得渲染器能够在每次屏幕刷新时绘制场景
//Why not use setInterval?For the function we use can stop when we change to other page
requestAnimationFrame(animate)
mesh.rotation.x += 0.01
mesh.rotation.y += 0.01
renderer.render(scene,camera)
}
animate()
正如其中的英文注释提到,为何不使用setInterval来实现刷新功能?其实也能用,但相对于setInterval,我们这里使用的requestAnimationFrame当用户切换到其他的页面时,它会暂停刷新,从而节省相关资源。
最后,别忘了调用动画渲染函数~完成后在Visual Studio Code的Live Server或其他运行环境中打开即可观察效果。
思考
在跟着官方文档编写和运行过程中有一些思考,或者说是可优化的地方:
1.如果在关闭上次打开的浏览器时,是在缩放浏览器的情况下关闭,那么第二次打开时将会以上次的大小打开,从而整个渲染的页面大小只有上次的那么大,导致我们再全屏浏览器页面时,只会有一部分是我们的图形如:
对应地,如果上次关闭是全屏,我们再缩放,也会只显示一部分:
个人认为这是比例的问题,应该在相关的配置上做修改可以改进
2.前文中提到的模型问题。其实在此之前个人有直接尝试复杂模型的绘制和渲染,但是基于vue2的,没有成功,而后才决定从头开始学习一下three.js。如何将本例中的立方体改为其他的模型甚至更复杂的模型,以及实现视角变换等,将是之后的一个重点。