使用three.js展示模型,实现鼠标移入模型高亮

1,783 阅读2分钟

使用three.js展示模型,实现鼠标移入模型高亮

先看效果图

自己模型.gif 参照官网例子webgl_interactive_cubes.html image.png 学习实现模型高亮分了三步:

  1. 修改代码展示的BoxGeometry替换成官方提供的的obj模型(因为我直接加载自己的模型不能实现高亮效果,猜测可能是模型格式不同)

官网模型.gif

var OBJLoaderA = new OBJLoader();
var MTLLoaderA = new MTLLoader();
MTLLoaderA.load("models/obj/male02/male02.mtl", function (materials) {
    OBJLoaderA.setMaterials(materials);
    OBJLoaderA.load("models/obj/male02/male02.obj", function (obj) {
        obj.translateY(-108);
        scene.add(obj);
    });
});

关闭模型自动旋转,调整模型大小后,可以实现鼠标移入高亮.

  1. 修改模型为自己的obj模型 模型引入代码同上,更换路径即可
function render() {// theta += 0.1;
camera.position.x = radius * Math.sin(THREE.MathUtils.degToRad(theta));
camera.position.y = radius * Math.sin(THREE.MathUtils.degToRad(theta));
camera.position.z = radius * Math.cos(THREE.MathUtils.degToRad(theta));
camera.lookAt(scene.position);
camera.updateMatrixWorld();
raycaster.setFromCamera(pointer, camera);
// 获取所有的子对象,计算物体和射线的焦点,第二个参数是用来判断是否获取所有的物体对象的,即开启检查所有后代
const intersects = raycaster.intersectObjects(scene.children, true);
if (intersects.length > 0) {
    if (INTERSECTED != intersects[0].object) {
        if (INTERSECTED) {
            for (let i = 0; i < INTERSECTED.material.length; i++) {
                INTERSECTED.material[i].emissive.setHex(INTERSECTED.currentHex);
            }}
            INTERSECTED = intersects[0].object;
            for (let i = 0; i < INTERSECTED.material.length; i++) {
                INTERSECTED.currentHex = INTERSECTED.material[i].emissive.getHex();
                INTERSECTED.material[i].emissive.setHex(0xff0000);
            }
        }
    }
    else {
        if (INTERSECTED) {
        for (let i = 0; i < INTERSECTED.material.length; i++){
            INTERSECTED.material[i].emissive.setHex(INTERSECTED.currentHex);
        }
    }
    INTERSECTED = null;
}
renderer.render(scene, camera);
}

修改render函数是因为发现我自己的obj模型和three.js官方提供模型在获取intersects[0].object.material时得到的结果不同,我获取的是个数组,官方获取的是个对象,并且会鼠标移入不同位置时候获取不同的材质对象,我分析是模型的问题,但是因为我对模型这里还不是很了解,只是暂时发现了这个问题,是什么导致出现这个问题的还没有搞清楚。 这是鼠标移入获取的intersects[0].object.material数据

image.png 图一为官方模型获取的数据

image.png 图二为我自己的obj模型获取的数据

  1. 移入项目中,更改坐标转换关系,因为在项目中模型不是在全屏展示的,是在一个占部分区域的dom内展示的,所以需要做坐标转换,把mousemove获取的坐标转化为vector2坐标
document.getElementById("showmodels")?.addEventListener("mousemove", onPointerMove);
width = document.getElementById("showmodels")?.clientWidth;
height = document.getElementById("showmodels")?.clientHeight;
function onPointerMove(event) {
    pointer.x = (event.offsetX / width) * 2 - 1;
    pointer.y = -(event.offsetY / height) * 2 + 1;
}