Three.js中文网 Three.js中文网
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • Three.js基础课程(旧版本) (opens new window)
  • 文章
WebGPU教程
  • WebGL教程
  • WebGL教程(旧版本) (opens new window)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原英文官网文档 (opens new window)
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • Three.js基础课程(旧版本) (opens new window)
  • 文章
WebGPU教程
  • WebGL教程
  • WebGL教程(旧版本) (opens new window)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原英文官网文档 (opens new window)
Web3D系统课程视频
  • 0.学前说明

  • 1.Three.js快速入门

  • 2.几何体BufferGeometry

  • 3.模型对象、材质

  • 4.层级模型

  • 5.顶点UV坐标、纹理贴图

  • 6.加载外部三维模型(gltf)

  • 7.PBR材质与纹理贴图

  • 8.渲染器和前端UI界面

  • 9.生成曲线、几何体

  • 10.相机基础

  • 11.光源和阴影

  • 12.精灵模型Sprite

  • 13.后处理EffectComposer

  • 14.射线拾取模型

    • 1. 射线Ray
    • 2. Raycaster(射线拾取模型)
    • 3. 屏幕坐标转标准设备坐标
    • 4. Raycaster(鼠标点击选中模型)
    • 5. Canvas尺寸变化(射线坐标计算)
    • 6. 射线拾取层级模型(模型描边)
      • 7. 射线拾取Sprite控制场景
    • 15.场景标注标签信息

    • 16.关键帧动画

    • 17.动画库tween.js

    • Three.js教程
    • 14.射线拾取模型
    郭隆邦
    2023-03-10
    目录

    6. 射线拾取层级模型(模型描边)

    # 射线拾取层级模型(发光描边)

    前面几节课演示过,通过射线投射器Raycaster的.intersectObjects()方法可以拾取Mesh模型对象。

    如果一个层级模型包含多个网格网格模型Mesh,使用.intersectObjects()方法拾取的时候,返回的结果默认是层级模型的后代Mesh,没办法整体选中该层级模型。

    下面以案例:射线拾取工厂设备添加发光描边,给大家演示如何解决含多Mesh的层级模型如何拾取。

    # .intersectObjects()参数的元素是层级模型

    通过Blender查看工厂模型,你可以发现存储罐cunchu.children里面有两个子对象设备A、设备B,这些子对象本身都是由多个Mesh构成的父对象。

    执行.intersectObjects(cunchu.children)进行射线拾取计算,返回结果并不是设备A或设备B父对象,而是他们的某个子对象Mesh。

    const cunchu = model.getObjectByName('存储罐');
    // 射线拾取模型对象(包含多个Mesh)
    // 射线交叉计算拾取模型
    const intersects = raycaster.intersectObjects(cunchu.children);
    

    课件源码已经设置好后处理OutlinePass,为了方便测试查看,那个Mesh被选中了,你直接给射线选中模型添加发光描边即可。

    outlinePass.selectedObjects = [intersects[0].object];
    

    # .intersectObjects()拾取层级模型解决方法

    .intersectObjects([父对象A,父对象B...])

    给需要射线拾取父对象的所有子对象Mesh自定义一个属性.ancestors,然后让该属性指向需要射线拾取父对象。

    const cunchu = model.getObjectByName('存储罐');
    // 射线拾取模型对象(包含多个Mesh)
    // 可以给待选对象的所有子孙后代Mesh,设置一个祖先属性ancestors,值指向祖先(待选对象)    
    for (let i = 0; i < cunchu.children.length; i++) {
        const group = cunchu.children[i];
        //递归遍历chooseObj,并给chooseObj的所有子孙后代设置一个ancestors属性指向自己
        group.traverse(function (obj) {
            if (obj.isMesh) {
                obj.ancestors = group;
            }
        })
    }
    // 射线交叉计算拾取模型
    const intersects = raycaster.intersectObjects(cunchu.children);
    console.log('intersects', intersects);
    if (intersects.length > 0) {
        // 通过.ancestors属性判断那个模型对象被选中了
        outlinePass.selectedObjects = [intersects[0].object.ancestors];
    }
    

    # 完整代码

    鼠标单击选中工厂某个设备,并添加高亮发光描边后处理效果。

    addEventListener('click', function (event) {
        const px = event.offsetX;
        const py = event.offsetY;
        //屏幕坐标转标准设备坐标
        const x = (px / window.innerWidth) * 2 - 1;
        const y = -(py / window.innerHeight) * 2 + 1;
        const raycaster = new THREE.Raycaster();
        //.setFromCamera()在点击位置生成raycaster的射线ray
        raycaster.setFromCamera(new THREE.Vector2(x, y), camera);
        const cunchu = model.getObjectByName('存储罐');
        // 射线拾取模型对象(包含多个Mesh)
        // 可以给待选对象的所有子孙后代Mesh,设置一个祖先属性ancestors,值指向祖先(待选对象)    
        for (let i = 0; i < cunchu.children.length; i++) {
            const group = cunchu.children[i];
            //递归遍历chooseObj,并给chooseObj的所有子孙后代设置一个ancestors属性指向自己
            group.traverse(function (obj) {
                if (obj.isMesh) {
                    obj.ancestors = group;
                }
            })
        }
        // 射线交叉计算拾取模型
        const intersects = raycaster.intersectObjects(cunchu.children);
        console.log('intersects', intersects);
        if (intersects.length > 0) {
            // 通过.ancestors属性判断那个模型对象被选中了
            outlinePass.selectedObjects = [intersects[0].object.ancestors];
        }
    })
    
    5. Canvas尺寸变化(射线坐标计算)
    7. 射线拾取Sprite控制场景

    ← 5. Canvas尺寸变化(射线坐标计算) 7. 射线拾取Sprite控制场景→

    Theme by Vdoing | Copyright © 2016-2025 豫ICP备16004767号-2
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式