模型对象及材质

三维向量Vector3与模型位置

点模型Points、线模型Line、网格网格模型Mesh等模型对象的父类都是Object3D。

三维向量Vector3有xyz三个分量,Three.js中会用三维向量Vector3表示很多种数据。Vector3对象具有属性.x.y.zVector3对象还具有.set()等方法。位置属性.position使用Three.js三维向量对象Vector3表示,因此具有Vector3所有的属性和方法。

1
2
3
4
const v3 = new THREE.Vector3(0,0,0);
console.log('v3', v3);
v3.set(10,0,0);
v3.x = 100;

通过模型位置属性.position可以设置模型在场景Scene中的位置。模型位置.position的默认值是THREE.Vector3(0.0,0.0,0.0),表示坐标原点。

1
2
3
4
//设置网格模型y坐标
mesh.position.y = 80;
//设置模型xyz坐标
mesh.position.set(80,2,10);

执行.translateX().translateY().translateZ()等方法本质上改变的都是模型的位置属性.position

1
2
3
// 等价于mesh.position.x = mesh.position.x + 100;
//而不是mesh.position.x = 100;
mesh.translateX(100);

如果调用两次mesh.translateX(100);,第二次是在第一次的基础上进行累计变换。注意这些平移以及缩放函数与BufferGeometry平移以及缩放函数的区别。如下图mesh.position.set(50,50,0);mesh.translateZ(100);函数将局部坐标系的原点设置在世界坐标系x=50,y=50处,接着将局部坐标系的原点沿着世界坐标系的z轴平移100。geometry.rotateX(Math.PI/2);geometry.translate(50,0,0);函数将物体的中心点绕局部坐标系的x轴旋转90°并且平移50。

image-20230205225318979

沿着自定义的方向移动。

1
2
3
4
5
//向量Vector3对象表示方向
const axis = new THREE.Vector3(1, 1, 1);
axis.normalize(); //向量归一化
//沿着axis轴表示方向平移100
mesh.translateOnAxis(axis, 100);

.scale表示模型对象的xyz三个方向上的缩放比例,.scale的属性值是一个三维向量对象Vector3,默认值是THREE.Vector3(1.0,1.0,1.0)

1
2
3
4
//x轴方向放大2倍
mesh.scale.x = 2.0;
//网格模型xyz方向分别缩放0.5,1.5,2倍
mesh.scale.set(0.5, 1.5, 2)

如下图通过旋转使得局部坐标系的y轴与世界坐标系的z轴平行,使用geometry.scale(1,2,1);函数后图形沿着局部坐标系的y轴放大至原来的2倍。即在世界坐标系中沿z轴前后放大而不是沿y轴上下放大。但是如果是mesh.scale会将局部坐标系和物体按照局部坐标系的轴一起缩放。

image-20230205232310262

欧拉Euler与角度属性.rotation

模型的角度属性.rotation和四元数属性.quaternion都是表示模型的角度状态,只是表示方法不同,.rotation属性值是欧拉对象,.quaternion属性值是四元数对象。

创建一个欧拉对象,表示绕着xyz轴分别旋转45度,0度,90度。

1
const Euler = new THREE.Euler( Math.PI/4,0, Math.PI/2);

通过属性设置欧拉对象的三个分量值。

1
2
3
4
const Euler = new THREE.Euler();
Euler.x = Math.PI/4;
Euler.y = Math.PI/2;
Euler.z = Math.PI/4;

角度属性.rotation的值是欧拉对象Euler

1
2
3
4
5
6
//绕y轴的角度设置为60度
mesh.rotation.y = Math.PI/3;
//绕y轴的角度增加60度
mesh.rotation.y += Math.PI/3;
//绕y轴的角度减去60度
mesh.rotation.y -= Math.PI/3;

模型执行.rotateX().rotateY()等旋转方法,会发现改变了模型的角度属性.rotation。如下函数是对model.rotation.y的累计变化。注意如果是mesh下的rotate函数就会将局部坐标系和物体按照局部坐标系的轴一起旋转,如果是geometry下的rotate函数只将物体按照局部坐标系的轴旋转。

1
2
mesh.rotateX(Math.PI/4);
mesh.rotateY(Math.PI / 2);

旋转动画。

1
2
3
4
5
6
7
8
9
// 渲染循环
function render() {
model.rotation.y+=0.01;
//等价与model.rotateY(0.01);
requestAnimationFrame(render);
}
function render() {
model.rotateY(0.01);
}

如果是绕某个轴旋转,如下是网格模型绕(0,1,0)向量表示的轴旋转π/8

1
2
const axis = new THREE.Vector3(0,1,0);//向量axis
mesh.rotateOnAxis(axis,Math.PI/8);//绕axis轴旋转π/8

模型材质颜色(Color对象)

浏览器控制台查看材质颜色属性的属性值。

1
console.log('material.color',material.color);

颜色对象有三个属性,分别为.r.g.b,表示颜色RGB的三个分量。

1
2
3
4
5
6
7
8
// 创建一个颜色对象
const color = new THREE.Color();//默认是纯白色0xffffff。
console.log('查看颜色对象结构',color);//可以查看rgb的值
// 查看Color对象设置0x00ff00对应的的.r、.g、.b值
const color = new THREE.Color(0x00ff00);
//通过.r、.g、.b属性改变颜色值
color.r = 0.0;
color.b = 0.0;

Color提供了.setHex().setRGB().setStyle().set()等修改颜色值的方法。

1
2
3
color.setRGB(0,1,0);//RGB方式设置颜色
color.setHex(0x00ff00);//十六进制方式设置颜色
color.setStyle('#00ff00');//前端CSS颜色值设置颜色

.setHex().setStyle()风格的颜色值都可以作为.set()的参数。

1
2
color.set(0x00ff00);//十六进制方式设置颜色
color.set('#00ff00');//前端CSS颜色值设置颜色

重置模型材质颜色。

1
2
3
material.color.set(0x00ffff);
material.color.set('#00ff00');
material.color.set('rgb(0,255,0)');

模型材质父类Material

基础网格材质MeshBasicMaterial、漫反射网格材质MeshLambertMaterial、高光网格材质MeshPhongMaterial等网格材质都有一个共同的父类Material

材质半透明设置。

1
2
material.transparent = true;//开启透明
material.opacity = 0.5;//设置透明度

材质面属性。

1
2
3
material.side = THREE.BackSide;//背面可以看到
material.side = THREE.FrontSide;//正面面可以看到
material.side = THREE.DoubleSide;//双面可见

THREE.FrontSideTHREE.BackSideTHREE.DoubleSide其实在theeejs内部都表示一个数字,可以通过浏览器控制打印查看验证。

1
console.log('material.side',material.side);

模型材质和几何体属性

浏览器控制打印模型对象mesh,可以展开对象,查看对象的几何体.geometry和材质属性.material

1
2
const mesh = new THREE.Mesh(geometry, material);
console.log('mesh',mesh);

浏览器控制台打印模型的几何体属性.geometry和材质属性.material

1
2
console.log('mesh.geometry',mesh.geometry);
console.log('mesh.material',mesh.material);

访问改变模型材质属性。

1
2
// 访问模型材质,并设置材质的颜色属性
mesh.material.color.set(0xffff00);

访问改变模型几何体属性。

1
2
// 访问模型几何体,并平移几何体顶点数据
mesh.geometry.translate(0,100,0);

材质或几何体共享。

1
2
3
4
5
6
7
8
const mesh = new THREE.Mesh(geometry, material);
const mesh1 = new THREE.Mesh(geometry, material);
mesh1.position.set(50,50,0);
// 两个mesh共享一个材质,改变一个mesh的颜色,另一个mesh2的颜色也会跟着改变
// 三者等价:mesh.material、mesh2.material、material
mesh.material.color.set(0xffff00);
// 三者等价:mesh.geometry、mesh2.geometry、geometry
mesh.geometry.translate(0,100,0);
image-20230205233114699

克隆.clone()和复制.copy()

克隆.clone()、复制.copy()是Three.js很多对象都具有的方法,比如三维向量对象Vector3、网格模型、几何体、材质。

克隆.clone()

1
2
3
4
5
const v1 = new THREE.Vector3(1, 2, 3);
console.log('v1',v1);
//v2是一个新的Vector3对象,和v1的.x、.y、.z属性值一样
const v2 = v1.clone();
console.log('v2',v2);

复制.copy()

1
2
3
4
const v1 = new THREE.Vector3(1, 2, 3);
const v3 = new THREE.Vector3(4, 5, 6);
//读取v1.x、v1.y、v1.z的赋值给v3.x、v3.y、v3.z
v3.copy(v1);

通过mesh克隆.clone()一个和mesh一样的新模型对象mesh2。

1
2
const mesh2 = mesh.clone();
mesh2.position.x = 100;

通过克隆.clone()获得的新模型和原来的模型共享材质和几何体。

1
2
3
// 改变材质颜色,或者说改变mesh2颜色,mesh和mesh2颜色都会改变
//material.color.set(0xffff00);
mesh2.material.color.set(0xffff00);

image-20230205233443346

几何体和材质克隆.clone()

1
2
3
4
5
6
const mesh2 = mesh.clone();
// 克隆几何体和材质,重新设置mesh2的材质和几何体属性
mesh2.geometry = mesh.geometry.clone();
mesh2.material = mesh.material.clone();
// 改变mesh2颜色,不会改变mesh的颜色
mesh2.material.color.set(0xffff0000);
image-20230205233522340

改变mesh的位置,使之位于mesh2的正上方(y),距离100。

1
2
mesh.position.copy(mesh2.position);//1. 第1步位置重合
mesh.position.y += 100;//1. 第2步mesh在原来y的基础上增加100

两个模型的姿态角度始终保持一样。

1
2
3
4
5
6
7
8
9
// 渲染循环
function render() {
mesh.rotateY(0.01);// mesh旋转动画
// 同步mesh2和mesh的姿态角度一样,不管mesh姿态角度怎么变化,mesh2始终保持同步
mesh2.rotation.copy(mesh.rotation);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码

请我喝杯咖啡吧~

支付宝
微信