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-03
    目录

    2. Raycaster(射线拾取模型)

    # Raycaster(射线拾取模型)

    上节课给大家介绍过射线Ray,下面给大家介绍另一个和射线相关的API射线投射器Raycaster。

    # 准备三个mesh用于射线拾取

    const geometry = new THREE.SphereGeometry(25, 50, 50);
    const material = new THREE.MeshLambertMaterial({
        color: 0x009999,
    });
    const mesh1 = new THREE.Mesh(geometry, material);
    const mesh2 = mesh1.clone();
    mesh2.position.y = 100;
    const mesh3 = mesh1.clone();
    mesh3.position.x = 100;
    const model = new THREE.Group();
    // 三个网格模型mesh1,mesh2,mesh3用于射线拾取测试
    model.add(mesh1, mesh2, mesh3);
    model.updateMatrixWorld(true);
    

    # 射线投射器Raycaster

    射线投射器Raycaster具有一个射线属性.ray,该属性的值就是上节课讲解的射线对象Ray。

    const raycaster = new THREE.Raycaster();
    console.log('射线属性',raycaster.ray);
    
    // 设置射线起点
    raycaster.ray.origin = new THREE.Vector3(-100, 0, 0);
    // 设置射线方向射线方向沿着x轴
    raycaster.ray.direction = new THREE.Vector3(1, 0, 0);
    

    # 射线交叉计算(.intersectObjects()方法)

    射线投射器Raycaster通过.intersectObjects()方法可以计算出来与自身射线.ray相交的网格模型。

    .intersectObjects([mesh1, mesh2, mesh3])对参数中的网格模型对象进行射线交叉计算,未选中对象返回空数组[],选中一个对象,数组1个元素,选中多个对象,数组多个元素,如果选中多个对象,对象在数组中按照先后排序。

    const raycaster = new THREE.Raycaster();
    raycaster.ray.origin = new THREE.Vector3(-100, 0, 0);
    raycaster.ray.direction = new THREE.Vector3(1, 0, 0);
    // 射线发射拾取模型对象
    const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh3]);
    console.log("射线器返回的对象", intersects);
    

    # .intersectObjects()射线拾取返回信息

    射线拾取返回的intersects里面的元素包含多种信息,你可以通过threejs文档查看,或者在浏览器控制台打印查看。

    .intersectObjects()和.intersectObject()功能相同,只是具体语法不同,.intersectObjects()返回数组元素包含的信息,可以参考文档关于.intersectObject()的介绍。

    console.log("射线器返回的对象", intersects);
    // intersects.length大于0说明,说明选中了模型
    if (intersects.length > 0) {
        console.log("交叉点坐标", intersects[0].point);
        console.log("交叉对象",intersects[0].object);
        console.log("射线原点和交叉点距离",intersects[0].distance);
    }
    

    # 射线选中的模型对象改变材质颜色

    const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh3]);
    if (intersects.length > 0) {
        // 选中模型的第一个模型,设置为红色
        intersects[0].object.material.color.set(0xff0000);
    }
    

    # 提醒

    注意射线拾取的时候,mesh1, mesh2, mesh3位置要确保更新的情况下,执行射线计算,threejs一般是渲染器执行一次.render()之后,你设置的mesh.position或者mesh父对象的position才会真实生效。

    ...
    // 注意更新下模型的世界矩阵,你设置的mesh.position生效,再进行射线拾取计算
    model.updateMatrixWorld(true);
    ...
    const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh3]);
    
    mesh2.position.y = 100;
    mesh3.position.x = 100;
    const model = new THREE.Group();
    // 三个网格模型mesh1,mesh2,mesh3用于射线拾取测试
    model.add(mesh1, mesh2, mesh3);
    
    //注意更新下模型的世界矩阵,你设置的position生效,再进行射线拾取计算
    model.updateMatrixWorld(true);
    
    const raycaster = new THREE.Raycaster();
    raycaster.ray.origin = new THREE.Vector3(-100, 0, 0);
    raycaster.ray.direction = new THREE.Vector3(1, 0, 0);
    const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh3]);
    
    1. 射线Ray
    3. 屏幕坐标转标准设备坐标

    ← 1. 射线Ray 3. 屏幕坐标转标准设备坐标→

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