Three.js学习之路(二丶旋转动画/三维操作旋转缩放/几何体)

1.旋转动画、requestAnimationFrame周期性渲染

上节初篇就画了个正方体,看起来没什么感觉,所以下面我大概介绍一下这个模型怎么才能旋转起来,让事情变得有趣一些

function render() {
    renderer.render(scene,camera);//执行渲染操作
    mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
}
//间隔20ms周期性调用函数fun,20ms也就是刷新频率是50FPS(1s/20ms),每秒渲染50次
setInterval(render,20);

把上节的renderer.render(scene,camera),替换成上面的代码就可以实现模型自己旋转,这个大概还有第二种方式实现旋转吧,如下

function render() {
    renderer.render(scene,camera);//执行渲染操作
    mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
    requestAnimationFrame(render);//请求再次执行渲染函数render
}
render();

嗯,这个方法一般默认保持60FPS的频率,大约每16.7ms调用一次requestAnimationFrame()方法指定的函数,60FPS是理想的情况下,如果渲染的场景比较复杂或者说硬件性能有限可能会低于这个频率,所有下面的可以真正实现匀速旋转,嗯,是的,匀速!

let T0: any = new Date();//上次时间
function render() {
    let T1: any = new Date();//本次时间
    let t = T1-T0;//时间差
    T0 = T1;//把本次时间赋值给上次时间
    requestAnimationFrame(render);
    renderer.render(scene,camera);//执行渲染操作
    mesh.rotateY(0.001*t);//旋转角速度0.001弧度每毫秒
}
render();

2.鼠标操作三维场景(旋转/缩放)

上面介绍了怎么实现旋转,但是我们一般还要自己选角度,不是说模型自己旋转到哪就看哪,这就非常被动,所以我们需要主动一点,我们添加个鼠标操作,会不会更好一点呢。来吧!

function render() {
  renderer.render(scene,camera);//执行渲染操作
}
render();
var controls = new THREE.OrbitControls(camera,renderer.domElement);//创建控件对象
controls.addEventListener('change', render);//监听鼠标、键盘事件

这个是正常模式,但是呢,这里会报错TypeError: THREE.OrbitControls is not a constructor,为什么呢?这个是因为用npm 安装的three.js里面的确没有OrbitControls,所以这个需要手动安装一下

npm install three-orbitcontrols

安装完之后,需要在需要用到的页面/组件的头部引入一下

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

然后把THREE.OrbitControls(camera,renderer.domElement)改成OrbitControls(camera,renderer.domElement)就行了
再换成requestAnimationFrame写法把,不然感觉学了不用,有点扯呼。

function render() {
  renderer.render(scene,camera);//执行渲染操作
  // mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
  requestAnimationFrame(render);//请求再次执行渲染函数render
}
render();
var controls = new OrbitControls(camera,renderer.domElement);//创建控件对象
// 已经通过requestAnimationFrame(render);周期性执行render函数,没必要再通过监听鼠标事件执行render函数
// controls.addEventListener('change', render)

这大概就行了,咦,这里我想了想,光源会跟着模型旋转而旋转,如果我需要实现光源永远跟着相机不动,就像主角都会想一直在舞台灯光下那样,下面我们一起来实现模型的主角梦想:

function render() {
  // 复制相机的坐标
  var vector = camera.position.clone();
  point.position.set(vector.x, vector.y, vector.z); //重置点光源位置
  renderer.render(scene, camera);//执行渲染操作
  // mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
  requestAnimationFrame(render);//请求再次执行渲染函数render
}
render();
var controls = new OrbitControls(camera, renderer.domElement);//创建控件对象

这样鼠标无论转到哪,光源都会在相机那里,不会再跟着模型旋转了。
梦想是实现了,但是为什么我感觉没啥用呢

3.几何体类型

到这里就有人会问,这个是正方体的,我想加圆球或者其他的模型呢,接着,下面就给大家看看怎么添加其他类型的几何体

//长方体 参数:长,宽,高
let geometry = new THREE.BoxGeometry(100, 100, 100);
// 球体 参数:半径60  经纬度细分数40,40
let geometry = new THREE.SphereGeometry(60, 40, 40);
// 圆柱  参数:圆柱面顶部、底部直径50,50   高度100  圆周分段数
let geometry = new THREE.CylinderGeometry(50, 50, 100, 25);
// 正八面体
let geometry = new THREE.OctahedronGeometry(50);
// 正十二面体
let geometry = new THREE.DodecahedronGeometry(50);
// 正二十面体
let geometry = new THREE.IcosahedronGeometry(50);

几何体的其他类型
这里还会有人问,我怎么添加多个几何体组成其他形状呢?不要着急,下面就带大家看看

//立方体网格模型
let geometry1 = new THREE.BoxGeometry(100, 100, 100);
let material1 = new THREE.MeshLambertMaterial({
  color: 0x0000ff
}); //材质对象Material
let mesh1 = new THREE.Mesh(geometry1, material1); //网格模型对象Mesh
scene.add(mesh1); //网格模型添加到场景中

//球体网格模型
let geometry2 = new THREE.SphereGeometry(60, 40, 40);
let material2 = new THREE.MeshLambertMaterial({
  color: 0xff00ff
});
let mesh2 = new THREE.Mesh(geometry2, material2); //网格模型对象Mesh
mesh2.translateY(120); //球体网格模型沿Y轴正方向平移120
scene.add(mesh2);

// 圆柱网格模型
let geometry3 = new THREE.CylinderGeometry(50, 50, 100, 25);
let material3 = new THREE.MeshLambertMaterial({
  color: 0xffff00
});
let mesh3 = new THREE.Mesh(geometry3, material3); //网格模型对象Mesh
// mesh3.translateX(120); //球体网格模型沿Y轴正方向平移120
mesh3.position.set(120, 0, 0);//设置mesh3模型对象的xyz坐标为120,0,0
scene.add(mesh3); 

多个几何体
当然这里可以自己自由发挥,想要什么东西,自己可以慢慢研究,我就简单示范一下。
不知道有没有人发现我的图片有XYZ轴,这个东西不是默认有的,需要自己手动添加的,关键代码我给出来,需要的可以加上,不需要的了解一下也是可以的

// 辅助坐标系  参数250表示坐标系大小,可以根据场景大小去设置
let axisHelper = new THREE.AxisHelper(250);//换成THREE.AxesHelper(250)
scene.add(axisHelper);

这里也有个注意的就是AxisHelper是旧版的,新版的要用AxesHelper,如果用axisHelper没报错就不用管了

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值