1,加载gltf,glb模型变黑
1,加载方法
1,导入所需的包,以angular为例:
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; //加载压缩模型需要 import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
2,使用时核心代码:
const loader = new GLTFLoader();
//Load a glTF resource
//设置解压库文件路径
var dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('assets/libs/draco/gltf/');
loader.setDRACOLoader(dracoLoader);
// this.pivot5 = new THREE.Object3D();
loader.load(
url,
//called when the resource is loader
function (gltf) {
gltf.scene.traverse(function (child: any) {
// console.log(9998, child);
if (child.isMesh) {
if(child.userData.name&&child.userData.name.indexOf('desk')>-1){
const label = createLabel(child.userData.name);
label.position.set( 0, 0, 0 );
child.add( label );
}
child.material.emissive = child.material.color;
child.material.emissiveMap = child.material.map;
// child.vertices.forEach(function (e, i, arr) {
// var length = glist[index].vertices.length;
}
})
scene.add(gltf.scene);
// this.pivot5.add(gltf);
let res = [];
let toArr = function (arr) {
// console.log(6, arr);
arr.forEach(function (item) {
item.children.length > 0 ? toArr(item.children) : res.push(item);
});
}
toArr(gltf.scene.children);
callback(res, camera, controls, gltf.scene, scene, renderer, labelRenderer);
},
//called while loading is progressing
function (xhr) {
this.loadProgress = (xhr.loaded / xhr.total * 100) + '% loaded';
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
//called when loading gas errors
function (error) {
console.log('An error happened');
}
);
注意事项:assets/libs/draco/gltf/存放这些文件,如下图所示:
2,模型加载中会变黑的问题解决
添加如下代码
if (child.isMesh) {
child.material.emissive = child.material.color;
child.material.emissiveMap = child.material.map;
}
3,添加环境贴图
scene = new THREE.Scene();
var textureCube = new THREE.CubeTextureLoader().setPath('assets/img/model/entv/').load(['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png', ]);
// //六张图片分别是朝前的(preview_f.jpg)、朝后的(preview_b.jpg)、朝上的(preview_u.jpg)、朝下的(preview_d.jpg)、朝右的(preview_r.jpg)和朝左的(preview_l.jpg)
scene.background = textureCube; //new THREE.Color(0x727272);
4,给模型添加标注
1,所用的包
import { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer';
2,使用
核心函数:样式可以自由修改
function createLabel(name){
const div = document.createElement( 'div' );
div.className = 'label';
div.textContent = name;
div.style.padding = '4px 10px';
div.style.color = '#fff';
div.style.fontSize = '16px';
div.style.position = 'absolute';
div.style.backgroundColor = 'rgba(25,25,25,0.5)';
div.style.borderRadius = '5px';
// earthDiv.style.marginTop = '-1em';
const Label = new CSS2DObject( div );
return Label;
}
最后别忘记渲染哦
5,模型交互
onDocumentMouseDown(e) {
e.preventDefault();
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
//将鼠标点击位置的屏幕坐标转成threejs中的标准坐标,具体解释见代码释义
mouse.x = (e.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;
//新建一个三维单位向量 假设z方向就是0.5
//根据照相机,把这个向量转换到视点坐标系
raycaster.setFromCamera(mouse, this.camera);
let INTERSECTED;
// calculate objects intersecting the picking ray
var intersects = raycaster.intersectObjects(this.scene.children, true);
// if (!intersects[0]) return
// console.log(9899, intersects);
if (intersects.length > 0) {
// console.log(9899, intersects);
if (INTERSECTED != intersects[0].object && intersects[0].object instanceof THREE.Mesh) {
if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
INTERSECTED = intersects[0].object;
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
INTERSECTED.material.emissive.setHex(0xffffff * Math.random());
// console.log(6, INTERSECTED);
}
} else {
if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
INTERSECTED = null;
}
}
今日分享就到这里了,欢迎点赞指正,奥利给