学习: Threejs (3)& Threejs (4)

一、三维向量Vector3与模型位置、缩放属性

位置属性.position

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

javascript 复制代码
// 位置属性.position使用threejs三维向量对象Vector3表示的
console.log("模型位置属性.position的值", mesh.position);

//new THREE.Vector3()实例化一个三维向量对象
const v3 = new THREE.Vector3(0, 0, 0);
console.log("v3", v3);
v3.set(10, 0, 0); //set方法设置向量的值
v3.x = 100; //访问x、y或z属性改变某个分量的值

// .position的值是Vector3,意味着你想改变.position,可以查询文档Vector3类
// 直接设置网格模型的位置
mesh.position.set(100, 100, 100);
mesh.position.x = 100; //设置模型的x坐标

// 网格模型沿着x轴方向平移100,
mesh.translateX(100);

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

javascript 复制代码
mesh.scale.y = 3; //y方向放大3倍
// 网格模型xyz方向分别缩放0.5,1.5,2倍
mesh.scale.set(0.5, 1.5, 2);

二、欧拉Euler与角度属性.rotation

javascript 复制代码
// 角度属性.rotation使用threejs欧拉对象Euler表示的
console.log('模型角度属性.rotation的值', mesh.rotation);

// 创建一个欧拉对象,表示绕着x、y、z轴分别旋转45度,0度,90度
// const Euler = new THREE.Euler( Math.PI/4,0, Math.PI/2);
const Euler = new THREE.Euler();
// 通过xyz分量属性定义和参数一样
Euler.x = Math.PI/4;
Euler.y = 0;
Euler.z = Math.PI/2;

角度属性.rotation的值是欧拉对象Euler,意味着你想改变属性.rotation

javascript 复制代码
//绕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

javascript 复制代码
// 通过模型的旋转方法,也可以改变角度属性.rotation
mesh.rotateY(Math.PI / 3);// 绕着Y轴旋转60度

三、模型材质颜色(Color对象)

javascript 复制代码
const material = new THREE.MeshLambertMaterial({
    color: 0xffff00,
});
const mesh = new THREE.Mesh(geometry, material);
// 浏览器控制台查看材质颜色属性的属性值
console.log('material.color',material.color);

颜色对象

javascript 复制代码
// 创建一个颜色对象
const color = new THREE.Color();//默认是纯白色0xffffff。
console.log('查看颜色对象结构',color);//可以查看rgb的值

通过.r.g.b属性改变颜色值

javascript 复制代码
color.r = 0.0;
color.b = 0.0;

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

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

重置模型材质的颜色

javascript 复制代码
// 十六进制颜色
material.color.set(0x00ff00);
// 前端CSS风格颜色值:'#00ff00'、'rgb(0,255,0)'等形式
// material.color.set('#00ff00');
// material.color.set('rgb(0,255,0)');

四、模型材质父类Material

javascript 复制代码
material.transparent = true;//开启透明
material.opacity = 0.5;//设置透明度
// material.side = THREE.BackSide;//背面可以看到
material.side = THREE.DoubleSide;//双面可见

五、模型材质和几何体属性

javascript 复制代码
console.log('mesh',mesh);
console.log('mesh.geometry',mesh.geometry);
console.log('mesh.material',mesh.material);
javascript 复制代码
// 访问模型材质,并设置材质的颜色属性
mesh.material.color.set(0xffff00);
// 访问模型几何体,并平移几何体顶点数据
mesh.geometry.translate(0,100,0);

mesh共享材质或几何体

javascript 复制代码
const mesh2 = new THREE.Mesh(geometry, material);
mesh2.position.x = 100;

// 两个mesh共享一个材质,改变一个mesh的颜色,另一个mesh2的颜色也会跟着改变
// mesh.material和mesh2.material都指向同一个material
// 三者等价:mesh.material、mesh2.material、material
mesh.material.color.set(0xffff00);


// 三者等价:mesh.geometry、mesh2.geometry、geometry
mesh.geometry.translate(0,100,0);
export {mesh,mesh2};

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

克隆.clone()简单说就是复制一个和原对象一样的新对象

javascript 复制代码
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()简单说就是把一个对象属性的属性值赋值给另一个对象

javascript 复制代码
const v3 = new THREE.Vector3(4, 5, 6);
//读取v1.x、v1.y、v1.z的赋值给v3.x、v3.y、v3.z
v3.copy(v1); 

Mesh克隆

javascript 复制代码
const material = new THREE.MeshLambertMaterial({
  color: 0xffffff,
});
const mesh = new THREE.Mesh(geometry, material);
// 通过mesh克隆.clone()一个和mesh一样的新模型对象mesh2
const mesh2 = mesh.clone();
mesh2.position.x = 100;

// 通过克隆.clone()获得的新模型和原来的模型共享材质和几何体
//改变材质颜色,或者说改变mesh2颜色,mesh和mesh2颜色都会改变
// material.color.set(0xffff00);
mesh2.material.color.set(0xffff00);

// 改变mesh的位置,使之位于mesh2的正上方(y),距离100。
mesh.position.copy(mesh2.position); //1. 第1步位置重合
mesh.position.y += 100; //1. 第2步mesh在原来y的基础上增加100
javascript 复制代码
// 克隆几何体和材质,重新设置mesh2的材质和几何体属性
mesh2.geometry = mesh.geometry.clone();
mesh2.material = mesh.material.clone();
// 改变mesh2颜色,不会改变mesh的颜色
mesh2.material.color.set(0xff0000);

Threejs (4)

一、组对象Group、层级模型

javascript 复制代码
//创建两个网格模型mesh1、mesh2
const geometry = new THREE.BoxGeometry(20, 20, 20);
const material = new THREE.MeshLambertMaterial({ color: 0xffffff });
// 创建一个组对象
const group = new THREE.Group();
const mesh1 = new THREE.Mesh(geometry, material);
const mesh2 = new THREE.Mesh(geometry, material);
mesh2.translateX(25);

插入到组中

javascript 复制代码
//把mesh1型插入到组group中,mesh1作为group的子对象
group.add(mesh1);
//把mesh2型插入到组group中,mesh2作为group的子对象
group.add(mesh2);

// group.add(mesh1, mesh2);

父对象旋转缩放平移变换,子对象跟着变化

javascript 复制代码
//沿着Y轴平移mesh1和mesh2的父对象,mesh1和mesh2跟着平移
group.translateY(100);
//父对象缩放,子对象跟着缩放
group.scale.set(4, 4, 4);
//父对象旋转,子对象跟着旋转
group.rotateY(Math.PI / 6);
javascript 复制代码
// group也会作为场景scene的子对象插入到场景中
export default group;

查看子对象.children

javascript 复制代码
console.log('查看group的子对象',group.children);

查看Scene的子对象

javascript 复制代码
console.log('查看Scene的子对象',scene.children);

Object3D作为Group来使用,Group更加语义化,Object3D本身就是表示模型节点的意思

mesh也能添加mesh子对象

javascript 复制代码
//threejs默认mesh也可以添加子对象,mesh基类也是Object3D
mesh1.add(mesh2);

高层楼、洋房

javascript 复制代码
// 引入three.js
import * as THREE from 'three';

// 创建一个层级模型对象

// 批量创建多个长方体表示高层楼
const group1 = new THREE.Group(); //所有高层楼的父对象
for (let i = 0; i < 5; i++) {
    const geometry = new THREE.BoxGeometry(20, 60, 10);
    const material = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.x = i * 30; // 网格模型mesh沿着x轴方向阵列
    group1.add(mesh); //添加到组对象group1
}
// 平移父对象group1,所有子对象跟着平移
group1.position.y = 30;
// 旋转父对象group1,所有子对象跟着旋转
// group1.rotateY(Math.PI/2);


const group2 = new THREE.Group();
// 批量创建多个长方体表示洋房
for (let i = 0; i < 5; i++) {
    const geometry = new THREE.BoxGeometry(20, 30, 10);
    const material = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.x = i * 30;
    group2.add(mesh); //添加到组对象group2
}
group2.position.z = 50;
group2.position.y = 15;

const model = new THREE.Group();
model.add(group1, group2);
// 整体平移model里面的所有模型对象
model.position.set(-50,0,-25);


export default model;

二、递归遍历模型树结构、查询模型节点

模型命名(.name属性)

javascript 复制代码
// 批量创建多个长方体表示高层楼
const group1 = new THREE.Group(); //所有高层楼的父对象
group1.name = "高层";
javascript 复制代码
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.x = i * 30;
  group2.add(mesh); //添加到组对象group2
  mesh.name = i + 6 + "号楼";
javascript 复制代码
// 批量创建多个长方体表示高层楼
const group1 = new THREE.Group(); //所有高层楼的父对象
group1.name = "高层";
for (let i = 0; i < 5; i++) {
  const geometry = new THREE.BoxGeometry(20, 60, 10);
  const material = new THREE.MeshLambertMaterial({
    color: 0xffffff,
  });
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.x = i * 30; // 网格模型mesh沿着x轴方向阵列
  group1.add(mesh); //添加到组对象group1
  mesh.name = i + 1 + "号楼";
  console.log('mesh.name',mesh.name);
}
group1.position.y = 30;

const group2 = new THREE.Group();
group2.name = "洋房";
// 批量创建多个长方体表示洋房
for (let i = 0; i < 5; i++) {
  const geometry = new THREE.BoxGeometry(20, 30, 10);
  const material = new THREE.MeshLambertMaterial({
    color: 0xffffff,
  });
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.x = i * 30;
  group2.add(mesh); //添加到组对象group2
  mesh.name = i + 6 + "号楼";
}
group2.position.z = 50;
group2.position.y = 15;

const model = new THREE.Group();
model.name = "小区房子";
model.add(group1, group2);
model.position.set(-50, 0, -25);

递归遍历方法.traverse()

javascript 复制代码
// 递归遍历model包含所有的模型节点
model.traverse(function (obj) {
  console.log("所有模型节点的名称", obj.name);
  // obj.isMesh:if判断模型对象obj是不是网格模型'Mesh'
  if (obj.isMesh) {
    //判断条件也可以是obj.type === 'Mesh'
    obj.material.color.set(0xffff00);
  }
});

查找某个具体的模型.getObjectByName()

javascript 复制代码
// .getObjectByName()根据名字选择模型节点
const mesh = model.getObjectByName("2号楼");
mesh.material.color.set(0xff0000);

三、本地坐标和世界坐标

javascript 复制代码
const mesh = new THREE.Mesh(geometry, material); 
mesh.position.set(50, 0, 0);
const group = new THREE.Group();
group.add(mesh); //网格模型添加到组中
group.position.set(50, 0, 0);

任何一个模型的本地坐标 (局部坐标 )就是模型的.position属性。

javascript 复制代码
// 声明一个三维向量用来表示某个坐标
const worldPosition = new THREE.Vector3();
// 获取mesh的世界坐标,你会发现mesh的世界坐标受到父对象group的.position影响
mesh.getWorldPosition(worldPosition)
console.log('世界坐标',worldPosition);
console.log('本地坐标',mesh.position);

.getWorldPosition()获取世界坐标

给模型添加一个可视化的局部坐标系

javascript 复制代码
//可视化mesh的局部坐标系
const meshAxesHelper = new THREE.AxesHelper(50);
mesh.add(meshAxesHelper);

四、改变模型相对局部坐标原点位置

javascript 复制代码
 model.rotateY(0.01);//旋转动画
javascript 复制代码
// 平移几何体的顶点坐标,改变几何体自身相对局部坐标原点的位置
geometry.translate(50/2,0,0,);
javascript 复制代码
// .rotateY()默认绕几何体中心旋转,经过上面几何体平移变化,你会发现.rotateY()是绕长方体面上一条线旋转
mesh.rotateY(Math.PI/3);

五、移除对象.remove()

javascript 复制代码
//把mesh1型插入到组group中,mesh1作为group的子对象
group.add(mesh1);
//把mesh2型插入到组group中,mesh2作为group的子对象
group.add(mesh2);

remove

javascript 复制代码
// 删除父对象group的子对象网格模型mesh1
group.remove(mesh1);
// 通过`.remove()`方法删除父对象的子对象之后,可以通过浏览器控制台查看`.children()`属性的变化。
console.log('查看group的子对象',group.children);
javascript 复制代码
group.remove(mesh1,mesh2);//一次移除多个子对象

六、模型隐藏或显示

模型属性.visible

javascript 复制代码
mesh.visible =false;// 隐藏一个网格模型,visible的默认值是true
javascript 复制代码
group.visible =false;// 隐藏一个包含多个模型的组对象group

材质属性.visible

material.visible可以控制是否隐藏该材质对应的模型对象。

如果多个模型引用了同一个材质,如果该材质`.visible`设置为false,意味着隐藏绑定该材质的所有模型。

javascript 复制代码
mesh1.material.visible =false;
相关推荐
IT=>小脑虎17 小时前
2026版 Python零基础小白学习知识点【基础版详解】
开发语言·python·学习
李泽辉_18 小时前
深度学习算法学习(五):手动实现梯度计算、反向传播、优化器Adam
深度学习·学习·算法
星火开发设计18 小时前
C++ set 全面解析与实战指南
开发语言·c++·学习·青少年编程·编程·set·知识
坚持就完事了18 小时前
Linux的学习03:时间没有更新怎么解决
学习
李泽辉_18 小时前
深度学习算法学习(一):梯度下降法和最简单的深度学习核心原理代码
深度学习·学习·算法
im_AMBER18 小时前
Leetcode 99 删除排序链表中的重复元素 | 合并两个链表
数据结构·笔记·学习·算法·leetcode·链表
YangYang9YangYan18 小时前
中专大数据技术专业学习数据分析的价值分析
大数据·学习·数据分析
testpassportcn19 小时前
Fortinet FCSS_SDW_AR-7.4 認證介紹|Fortinet Secure SD-WAN 高級路由專家考試
网络·学习·改行学it
光影少年19 小时前
vite为什么速度快?
前端·学习