接上篇:​​Vue集成three.js,并加载glb、gltf、FBX、json模型​

 上篇就是创建材质的时候转BSP时,引入ThreeBSP的问题,这篇来解决。

<script src="https://johnson2heng.github.io/three.js-demo/lib/threebsp.js"></script>

这个确实可以在线引,但有个前提是得引在three之后,但是咱们是Vue开发,three.js是通过npm装的,并且按需引入 ,这就有点难处理

现在有个替代方案:three-js-csg

安装:

npm i three-js-csg

组件中引入

import * as THREE from 'three'
const ThreeBSP = require('three-js-csg')(THREE)

开始使用的时候还是报了如下错误

Three.js引入ThreeBSP库_百度

百度找了一堆,应该是 three.js版本太高了,我当时装的是最新的,版本太高好像一些基类就没有了,才报了上述错误,我将版本降低到0.124.0就没有问题了

然后将上篇的完整代码 中的创建材质的方法修改如下:

// 创建材质
createMaterial() {
// 创建三维用到的材质
/**
*
* MeshBasicMaterial: 网格基础材质
* MeshDepthMaterial: 网格深度材质
* MeshNormalMaterial: 网格法向材质
* MeshLambertMaterial: 网格Lambert 材质
* MeshPhongMaterial: 网格 Phong式材质
* MeshStandardMaterial: 网格标准材质
* MeshPhysicalMaterial: 网格物理材质
* MeshToonMaterial: 网格卡通材质
* ShadowMaterial: 阴影材质
* ShaderMaterial: 着色器材质
* LineBasicMaterial: 直线基础材质
* LineDashMaterial: 虚线材质
*/
// 外墙
let wallMaterial = new THREE.MeshLambertMaterial({ color: 0x00ffff });
let wallGeo = new THREE.BoxGeometry(439 + 2 + 2, 120, 376.5 + 2 + 2); // 创建几何体
let wallMesh = new THREE.Mesh(wallGeo, wallMaterial);
wallMesh.position.set(0, 60, 0); //(0, 60, -14.95);
// this.scene.add(wallMesh)
// 内墙
let wallInnerMaterial = new THREE.MeshLambertMaterial({
color: 0x2d1bff,
});
let wallInnerGeo = new THREE.BoxGeometry(439, 120, 376.5); //(270, 120, 390);
let wallInnerMesh = new THREE.Mesh(wallInnerGeo, wallInnerMaterial);
wallInnerMesh.position.set(0, 60, 0); //(0, 60, -14.95);
// this.scene.add(wallInnerMesh)
// 门
let doorTexture = this.textureLoader.load(
require("../../../../assets/img/1.png") // 暂时注掉
);
let boxTextureMaterial = new THREE.MeshStandardMaterial({
map: doorTexture,
metalness: 0.2,
roughness: 0.07,
side: THREE.DoubleSide,
});
//let doorInnerMaterial = new THREE.MeshLambertMaterial({color: 0x2D1BFF});
let doorGeo = new THREE.BoxGeometry(2, 80, 74.5);
let doorMesh = new THREE.Mesh(doorGeo, boxTextureMaterial);
doorMesh.position.set(-220.5, 40, 0);
// this.scene.add(doorMesh);

//转BSP
let wallBSP = new ThreeBSP(wallMesh);
let wallInnerBSP = new ThreeBSP(wallInnerMesh);
let doorBSP = new ThreeBSP(doorMesh);
// let window1BSP = new ThreeBSP(this.createWindowRight());
//let window2BSP = new ThreeBSP(this.createWindowRight());// createWindowLeft
let wallResultBSP = wallBSP.subtract(wallInnerBSP);
wallResultBSP = wallResultBSP.subtract(doorBSP);
// wallResultBSP = wallResultBSP.subtract(window1BSP);
//wallResultBSP = wallResultBSP.subtract(window2BSP);
let wallResultMesh = wallResultBSP.toMesh();

//转换后的Mesh配置属性
let wallTexture = this.textureLoader.load(require("../../../../assets/img/3.jpg")); // 暂时注掉
let wallTextureMaterial = new THREE.MeshStandardMaterial({
map: wallTexture,
metalness: 0.2,
roughness: 0.07,
side: THREE.DoubleSide,
});
let wallInnerTexture = this.textureLoader.load(
require("../../../../assets/img/6.jpg") // 暂时注掉
);
let wallInnerTextureMaterial = new THREE.MeshStandardMaterial({
map: wallInnerTexture,
metalness: 0.2,
roughness: 0.07,
side: THREE.DoubleSide,
});
let wallResultMeshMaterial = [];
wallResultMeshMaterial.push(wallTextureMaterial);
wallResultMeshMaterial.push(wallInnerTextureMaterial);
//wallResultMeshMaterial.push(boxTextureMaterial);
wallResultMesh.material = wallResultMeshMaterial;

// console.log(wallResultMesh.geometry.faces, 112233);
wallResultMesh.geometry.faces.forEach((item, i) => {
if (i < 160) {
item.materialIndex = 0;
} else {
item.materialIndex = 1;
}
});

wallResultMesh.geometry.computeFaceNormals();
wallResultMesh.geometry.computeVertexNormals();
// console.log(wallResultMesh, '----->>>')
//添加结果到场景中
this.scene.add(wallResultMesh);
},

最终效果: 

Three.js引入ThreeBSP库_百度_02