三、Three.js模型对象、材质
一、三维向量Vector3与模型位置
点模型Points
、线模型Line
、网格网格模型Mesh
等模型对象的父类都是Object3D,如果想对这些模型进行旋转、缩放、平移等操作,如何实现,可以查询Threejs文档Object3D对相关属性和方法的介绍
1、三维向量Vector3
三维向量Vector3
有xyz三个分量,threejs中会用三维向量Vector3
表示很多种数据,本节课提到的比较简单,就是位置.position
和缩放.scale
属性。
查看three.js文档你可以知道Vector3
对象具有属性.x
、.y
、.z
,Vector3
对象还具有.set()
等方法。
const v3 = new THREE.Vector3(100,100,100);
v3.set(50,50,50)
console.log('sad',v3);
2、位置属性.position
// 位置属性.position使用threejs三维向量对象Vector3表示的
console.log('模型位置属性.position的值', mesh.position);
模型位置.position
属性用一个三维向量表示,那意味着,以后你想改变位置属性,就应该查询文档Vector3。
这里之所以强调这一点,课程目的不单单是给你介绍具体的知识点,也是在引导你学会查文档,降低记忆压力。
3、改变位置属性
通过模型位置属性.position
可以设置模型在场景Scene中的位置。模型位置.position
的默认值是THREE.Vector3(0.0,0.0,0.0)
,表示坐标原点。
设置网格模型y坐标
mesh.position.y = 80;
设置模型xyz坐标
mesh.position.set(80,2,10);
4、缩放
属性.scale
表示模型对象的xyz三个方向上的缩放比例,.scale
的属性值是一个三维向量对象Vector3
,默认值是THREE.Vector3(1.0,1.0,1.0)
。
轴方向放大2倍
mesh.scale.x = 2.0;
网格模型xyz方向分别缩放0.5,1.5,2倍
mesh.scale.set(2, 1.5, 2)
5、平移
执行.translateX()
、.translateY()
等方法本质上改变的都是模型的位置属性.position
。
网格模型沿着x轴正方向平移100,可以多次执行该语句,每次执行都是相对上一次的位置进行平移变换。
// 等价于mesh.position = mesh.position + 100;
mesh.translateX(100);//沿着x轴正方向平移距离100
沿着Z轴负方向平移距离50。
mesh.translateZ(-50);
二、欧拉Euler与角度属性.rotation
模型的角度属性.rotation
和四元数属性.quaternion
都是表示模型的角度状态,只是表示方法不同,.rotation
属性值是欧拉对象Euler,.quaternion
属性值是是四元数对象Quaternion
大家刚入门,就先给大家介绍比较容易理解的角度属性.rotation
和对应属性值欧拉对象Euler
1、欧拉对象Euler
// 创建一个欧拉对象,表示绕着xyz轴分别旋转45度,0度,90度
const Euler = new THREE.Euler( Math.PI/4,0, Math.PI/2);
通过属性设置欧拉对象的三个分量值。
const Euler = new THREE.Euler();
Euler.x = Math.PI/4;
Euler.y = Math.PI/2;
Euler.z = Math.PI/4;
2、改变角度属性.rotation
角度属性.rotation
的值是欧拉对象Euler
,意味着你想改变属性.rotation
,可以查询文档关于Euler
类的介绍。
//绕y轴的角度设置为60度
mesh.rotation.y += Math.PI/4;
//绕y轴的角度增加60度
mesh.rotation.y += Math.PI/4;
//绕y轴的角度减去60度
mesh.rotation.y -= Math.PI/4;
3、旋转方法.rotateX()
、.rotateY()
、.rotateZ()
模型执行.rotateX()
、.rotateY()
等旋转方法,你会发现改变了模型的角度属性.rotation
。
mesh.rotateX(Math.PI/4);//绕x轴旋转π/4
// 绕着Y轴旋转90度
mesh.rotateY(Math.PI / 2);
//控制台查看:旋转方法,改变了rotation属性
console.log(mesh.rotation);
cube.rotateX(0.5)
cube.rotateY(0.5)
cube.rotateZ(0.5)
4、旋转动画
function render() {cube.rotation.y += 0.01renderer.render(scene, camera)requestAnimationFrame(render)
}render()
function render() {cube.rotateY(0.01)renderer.render(scene, camera)requestAnimationFrame(render)
}render()
5、绕某个轴旋转
网格模型绕(0,1,0)
向量表示的轴旋转π/8
。
const axis = new THREE.Vector3(0,1,0);//向量axis
mesh.rotateOnAxis(axis,Math.PI/8);//绕axis轴旋转π/8
三、模型材质颜色(Color对象)
你去文档搜索MeshBasicMaterial、MeshLambertMaterial、MeshPhongMaterial等网格材质,可以看到他们都有一个颜色属性.color
。
下面结合threejs文档,带领大家探索一下,如何通过查询文档来修改模型材质的颜色值.color
。
1、材质颜色属性.color
如果你想修改材质的颜色属性.color
,那么你就需要了解该属性对应属性值的形式。
-
查文档,找到
.color
属性,可以发现threejs材质对象颜色属性.color
是threejs的颜色对象Color
。 -
console.log()
打印:浏览器控制台查看材质颜色属性的属性值
console.log('material.color',material.color);
2、颜色对象Color
查看颜色对象Color
文档,可以看到颜色对象有三个属性,分别为.r
、.g
、.b
,表示颜色RGB的三个分量。
// 创建一个颜色对象
const color = new THREE.Color();//默认是纯白色0xffffff。
console.log('查看颜色对象结构',color);//可以查看rgb的值
3、通过.r
、.g
、.b
属性改变颜色值
const color = new THREE.Color();
color.r = 0.5;
console.log('颜色',color);
4、改变颜色的方法
查看Color
文档,可以看到Color
提供了.setHex()
、.setRGB()
、.setStyle()
、.set()
等修改颜色值的方法。
color.setRGB(0,1,0);//RGB方式设置颜色
color.setHex(0x00ff00);//十六进制方式设置颜色
color.setStyle('#00ff00');//前端CSS颜色值设置颜色
.setHex()
、.setStyle()
风格的颜色值都可以作为.set()
的参数
color.set(0x00ff00);//十六进制方式设置颜色
color.set('#00ff00');//前端CSS颜色值设置颜色
5、重置模型材质的颜色
十六进制颜色
material.color.set(0x00ffff);
前端CSS风格颜色值:'#00ff00'、'rgb(0,255,0)'等形式
material.color.set('#00ff00');
material.color.set('rgb(0,255,0)');
四、 模型材质父类Material
1、材质父类Material
查询threejs文档,你可以看到基础网格材质MeshBasicMaterial
、漫反射网格材质MeshLambertMaterial
、高光网格材质MeshPhongMaterial
等网格材质都有一个共同的父类Material
。
2、网格材质继承父类属性
从JavaScript语法角度看子类都会继承父类的属性和方法,threejs的材质同样道理。
MeshBasicMaterial、MeshLambertMaterial、MeshPhongMaterial等子类网格材质会从父类Material
继承一些属性和方法,比如透明度属性.opacity
、面属性.side
、是否透明属性.transparent
等等。
3、材质半透明设置
material.transparent = true;//开启透明
material.opacity = 0.5;//设置透明度
4、材质面属性.side
你可以用矩形平面PlaneGeometry
来测试材质的面属性.side
。
查看文档,可以知道材质面属性.side
默认值是THREE.FrontSide
,表示网格模型正面可以看到,THREE.BackSide
表示背面可以看到,THREE.DoubleSide
表示双面可以看到。
material.side = THREE.BackSide;//背面可以看到
material.side = THREE.DoubleSide;//双面可见
THREE.FrontSide
、THREE.BackSide
、THREE.DoubleSide
其实在theeejs内部都表示一个数字,你可以通过浏览器控制log打印查看验证,具体可以查看src目录下constants.js的源码文件。
console.log('material.side',material.side);