前言
上一章已经通过GLTFLoader
把模型数据加载到场景,接下来我们对这些数据进行进一步处理。首先是把模型分类,整个模型可以分为三类,建筑(CITY_UNTRIANGULATED
),道路(ROADS
),地面(other
),对不同的数据分别添加不同的材质。
模型的线框添加
模型材质分为两个部分,第一部分是模型的线框材质,第二部分是模型的面材质,首先来说线框材质
- 线框材质:通过
Three
的EdgesGeometry
可以把生成模型的线框数据,用LineBasicMaterial生成线框的模型材质,然后用LineSegments
把这两个数据组合到一起,即可生产线框模型对象。
// 拿到模型线框的Geometry,其中child.geometry是模型子对象的节点数据
const edges = new THREE.EdgesGeometry(child.geometry, 1);
//设置模型的材质
const lineMaterial = new THREE.LineBasicMaterial({
// 线的颜色
color: "rgba(38,133,254)",
});
//把数据组合起来
const lineS = new THREE.LineSegments(edges, lineMaterial);
//设置数据的位置
lineS.position.set(
child.position.x,
child.position.y,
child.position.z
);
//添加到场景
scene.add(lineS);
效果图:
2. 模型面材质:这里模型面材质选择的是
Three
的物理材质MeshPhysicalMaterial
类,这个类可以模拟玻璃的质感.
// 模型面材质
const material = new THREE.MeshPhysicalMaterial({
//颜色为
color: "rgb(50,170,255)",
//金属度
metalness: 0.5,
//粗糙度
roughness: 0.1,
//透明度
transmission: 0.9,
//模型是否透明
transparent: true,
});
//生成模型对象
const mesh = new THREE.Mesh(child.geometry, material);
//添加到场景
scene.add(mesh);
效果图:
地面和道路材质设置
道路和地面选择的是基本材质类MeshBasicMaterial
//道路
const material = new THREE.MeshBasicMaterial({
color: "rgb(41,46,76)",
});
const mesh = new THREE.Mesh(child.geometry, material);
scene.add(mesh);
//地面
const material = new THREE.MeshBasicMaterial({
color: "#040912",
});
const mesh = new THREE.Mesh(child.geometry, material);
scene.add(mesh);
效果图:
完整代码
addGLTF() {
const loader = new GLTFLoader();
loader.load("shanghai.gltf", (gltf) => {
gltf.scene.traverse((child) => {
// 设置线框材质
if (child.isMesh) {
//这个判断模型是楼房还是其他 加载不同的材质
if (["CITY_UNTRIANGULATED"].includes(child.name)) {
// 拿到模型线框的Geometry
const edges = new THREE.EdgesGeometry(child.geometry, 1);
//设置模型的材质
const lineMaterial = new THREE.LineBasicMaterial({
// 线的颜色
color: "rgba(38,133,254)",
});
//把数据组合起来
const lineS = new THREE.LineSegments(edges, lineMaterial);
//设置数据的位置
lineS.position.set(
child.position.x,
child.position.y,
child.position.z
);
//添加到场景
scene.add(lineS);
lineS.rotateX(-Math.PI / 2);
// 模型面材质
const material = new THREE.MeshPhysicalMaterial({
//颜色为
color: "rgb(50,170,255)",
//金属度
metalness: 0.5,
//粗糙度
roughness: 0.1,
//透明度
transmission: 0.9,
//模型是否透明
transparent: true,
});
//生成模型对象
const mesh = new THREE.Mesh(child.geometry, material);
//添加到场景
scene.add(mesh);
mesh.position.set(
child.position.x,
child.position.y,
child.position.z
);
mesh.rotateX(-Math.PI / 2);
} else if (["ROADS"].includes(child.name)) {
//道路
const material = new THREE.MeshBasicMaterial({
color: "rgb(41,46,76)",
});
const mesh = new THREE.Mesh(child.geometry, material);
mesh.rotateX(-Math.PI / 2);
mesh.position.set(
child.position.x,
child.position.y,
child.position.z
);
scene.add(mesh);
} else {
//地面
const material = new THREE.MeshBasicMaterial({
color: "#040912",
});
const mesh = new THREE.Mesh(child.geometry, material);
scene.add(mesh);
mesh.rotateX(-Math.PI / 2);
mesh.position.set(
child.position.x,
child.position.y,
child.position.z
);
}
}
// 设置线框材质
});
});
},
项目地址: github.com/lixiaochjaj…