threejs-css2dObject操作之物体遮挡标签后应该隐藏,而不是出现透视效果

发布时间 2023-06-09 17:47:16作者: 努力不搬砖的iori

先看coding之前的效果:

 这些在背面的标签的,转到一定角度,被模型遮挡后,理论上就不应该被看到。这才是比较符合实际的

coding之后(另一侧对称点就被隐藏):

 具体代码(j借助于光线投影):

// 绑定鼠标事件,当用户移动视角后触发()
function bindRayShotEvent() {
    document.addEventListener('mouseup', () => {
        if (clusterOf2D.value.length > 0) {
            clusterOf2D.value.forEach((c: any) => {
                raycasterCollsionDetect(c)
            })
        }
    })
}
function raycasterCollsionDetect(wavesLabel: CSS2DObject) {
    const labelPosition = wavesLabel.position.clone()
    //计算出标签和相机之前的距离(需要看备份一下坐标,不然执行下面转换NDC坐标后,计算会不准)
    const labelDistance = labelPosition.distanceTo(camera.value.position)
    //转换 向量到从世界空间投影到相机的标准化坐标(NDC)
    labelPosition.project(camera.value)
    raycaster.setFromCamera(labelPosition, camera.value)
    let model = scene!.children.filter(v => {
        return v instanceof THREE.Group
    })
    //过滤出模型
    if (model.length == 1) {
        const intersects = raycaster.intersectObjects(model[0].children)
        if (intersects.length == 0) {
            // 如果标签没有被model遮挡,应该全部显示
            wavesLabel.element.classList.add('visible')
        } else {
            const minDistance = intersects[0].distance
            if (minDistance < labelDistance) {
                // 如果模型到相机的距离小于标签到相机的距离,说明光线射线先经过模型
                // 表面此时标签其实在模型的后面,应该被遮挡而看不见
                wavesLabel.element.classList.remove('visible')
                wavesLabel.element.classList.add('hidden')
            } else {
                wavesLabel.element.classList.add('visible')
                wavesLabel.element.classList.remove('hidden')
            }
        }
    }

}