当前位置:网站首页>用Three.js做一个简单的3D场景
用Three.js做一个简单的3D场景
2022-07-03 03:15:00 【抱紧北方】
Three.js是什么
Three.js 是一款运行在浏览器中的 3D 引擎,我们可以用它来创造我们所需要的一系列3D动画场景,简而言之就是建在网页上的3D模型。利用Three.js可以制作出很多酷炫的3D动画,并且Three.js还可以通过鼠标、键盘、拖拽等事件形成交互,在页面上增加一些3D动画和3D交互可以产生更好的用户体验。
Three.js程序结构
主要分为三大结构:场景Scene 相机Camera 渲染器Renderer
程序整个运行的过程就是:先加载场景—— 然后相机——最后渲染器
从实际生活中拍照角度理解,立方体网格模型和光照组成了一个虚拟的三维场景类似你要拍摄的物体,相机对象就像你生活中使用的相机一样可以拍照,只不过一个是拍摄真实的景物,一个是拍摄虚拟的景物,拍摄一个物体的时候相机的位置和角度需要调整,虚拟的相机还需要设置投影方式,当你创建好一个三维场景,相机也设置好,就差一个动作“咔”,通过渲染器就可以执行拍照动作了
简单理解了用Three.js做3D引擎的原理,那今天我们就来做一个简单的3D立方体吧
立方体
首先我们要在html文件中引入three.js,就像引入其它.js文件一样直接引入,它需要去官网下载
这里,我用的是相对路径
或者引用相对路径
<!--绝对路径远程加载-->
<script src="http://www.yanhuangxueyuan.com/3D/example/three.js"></script>
<!-- 压缩版本 -->
<script src="http://www.yanhuangxueyuan.com/3D/example/three.min.js"></script>
然后,在body里插入代码段就可以了,具体代码解释如下:
<body>
<script>
// 创建场景对象Scene
var scene = new THREE.Scene();
//创建网格模型
// var geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象
var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象
var material = new THREE.MeshLambertMaterial({ //创建材质对象Material
color: 0x008080 //立方体的颜色
});
var mesh = new THREE.Mesh(geometry, material); //创建网格模型对象Mesh
scene.add(mesh); //将网格mesh模型添加到场景中
// 光源设置
//点光源
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300); //点光源的位置
scene.add(point); //点光源添加到场景中
//环境光
var ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);
// console.log(scene)
// console.log(scene.children)
// 相机设置
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口宽高比
var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
// 创建渲染器对象
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);//设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
//执行渲染操作 指定场景、相机作为参数
renderer.render(scene, camera);
</script>
</body>
展示效果:
旋转动画
做到这里,只是在网页上呈现一个不动的3D立方体,为了增加趣味性和操作性,我们可以将渲染操作封装成一个函数,用setInterval让它间隔20ms周期性地调用render()渲染函数、不断地刷新
// 渲染函数
function render() {
renderer.render(scene,camera);//执行渲染操作
mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
}
//间隔20ms周期性调用渲染函数render()
setInterval("render()",20);
这里的时间单位是ms,20ms也就是刷新频率为50FPS(1s/20ms),即1s内屏幕刷新50次(相信打游戏的小伙伴都不陌生)
展示效果如下:
或者也可以通过requestAnimationFrame请求再次执行渲染函数render,渲染下一帧,这样也可以达到不断刷新,旋转的效果
// 渲染函数
let T0 = new Date();//上次时间
function render() {
let T1 = new Date();//本次时间
let t = T1-T0;//时间差
console.log(t);//两帧之间时间间隔 单位:ms
T0 = T1;//把本次时间赋值给上次时间
renderer.render(scene,camera);//执行渲染操作
mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧
}
render();
我们可以创建两个临时变量T1和T0去记录本次执行渲染和上次执行渲染所需时间,再将他们相减,就得到了两帧之间的时间间隔,发现稳定在17ms左右,58的fps,相较于我们自己设置的时间周期,它的fps更高,也没有局限性
展示效果如下:
鼠标操作三维场景旋转缩放
我们已经实现了让立方体机械性的动了起来,那可不可以通过鼠标来操控,让它可以转到任意我们想要的角度和位置呢
首先,我们还需要引入一个新的Threejs扩展控件——OrbitControls.js,它叫轨道控件,用它可以实现场景用鼠标交互,让场景动起来,控制场景的旋转、平移和缩放
<!-- 引入轨道控件OrbitControls.js -->
<!-- 相对路径 -->
<script src="./OrbitControls.js"></script>
<!-- 绝对路径 -->
<script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js"></script>
这里,轨道控件提供了一个构造函数,我们创建一个新的构造函数,再添加一个鼠标监听事件,鼠标有所动作,触发渲染函数,立方体会执行相应的效果
// 渲染函数
function render() {
renderer.render(scene, camera); //执行渲染操作
}
render();
//创建控件对象 相机对象camera作为参数 控件可以监听鼠标的变化,改变相机对象的属性
var controls = new THREE.OrbitControls(camera,renderer.domElement);
//监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
controls.addEventListener('change', render);
展示效果:
实际上轨道控件还有很多属性可以设置,但在本小例中没有应用到,详细的用法可参考官方文档:点击打开链接
边栏推荐
- Thunderbolt Chrome extension caused the data returned by the server JS parsing page data exception
- On the adjacency matrix and adjacency table of graph storage
- 模糊查詢時報錯Parameter index out of range (1 > number of parameters, which is 0)
- 你真的懂继电器吗?
- 函数栈帧的创建与销毁
- JS finds all the parent nodes or child nodes under a node according to the tree structure
- 【PyG】理解MessagePassing过程,GCN demo详解
- BigVision代码
- Do you really understand relays?
- Agile certification (professional scrum Master) simulation exercise-2
猜你喜欢
Vs 2019 configuration tensorrt
3D drawing example
敏捷认证(Professional Scrum Master)模拟练习题-2
I2C 子系统(三):I2C Driver
Vs 2019 installation and configuration opencv
vfork执行时出现Segmentation fault
Thunderbolt Chrome extension caused the data returned by the server JS parsing page data exception
Force deduction ----- the minimum path cost in the grid
Spark on yarn resource optimization ideas notes
Idea set method call ignore case
随机推荐
销毁Session和清空指定的属性
The idea cannot be loaded, and the market solution can be applied (pro test)
The idea setting code is in UTF-8 idea Properties configuration file Chinese garbled
LVGL使用心得
Find the storage address of the elements in the two-dimensional array
Can I use read-only to automatically implement properties- Is read-only auto-implemented property possible?
PHP constructor with parameters - PHP constructor with a parameter
Vs 2019 configuration du moteur de génération de tensorrt
一文带你了解 ZigBee
Thunderbolt Chrome extension caused the data returned by the server JS parsing page data exception
Three. JS local environment setup
Use of check boxes: select all, deselect all, and select some
I2C subsystem (IV): I2C debug
Update and return document in mongodb - update and return document in mongodb
Spark on yarn资源优化思路笔记
Docker install MySQL
About HTTP cache control
QT based tensorrt accelerated yolov5
Converts a timestamp to a time in the specified format
labelimg生成的xml文件转换为voc格式