Raycaster光线投射
Raycaster光线投射
3D虚拟工厂在线体验
描述
光线投射Raycaster,用于进行raycasting(光线投射)。 光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。
构造器
Raycaster( origin : Vector3, direction : Vector3, near : Float, far : Float )
参数 | 描述 |
---|---|
origin | 光线投射的原点向量 |
direction | 向射线提供方向的方向向量,应当被标准化 |
near | 返回的所有结果比near远。near不能为负值,其默认值为0 |
far | 返回的所有结果都比far近。far不能小于near,其默认值为Infinity(正无穷) |
这将创建一个新的raycaster对象。
属性
属性 | 类型 | 描述 |
---|---|---|
.far | Float | raycaster的远距离因数(投射远点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。这个值不应当为负,并且应当比near属性大 |
.near | Float | raycaster的近距离因数(投射近点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。这个值不应当为负,并且应当比far属性小 |
.camera | Camera | 当对依赖于视图的对象(如Sprites等广告牌对象)进行光线投射时使用的相机。可以手动设置,或在调用"setFromCamera"时设置。默认为null |
.layers | Layers | 用于在执行相交测试时有选择地忽略3D对象。raycaster.layers.set( 1 );object.layers.enable( 1 ); |
.params | Object | 具有以下属性的对象:{ Mesh: {}, Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} } 。其中threshold是光线投射与对象相交时的精度,以世界单位为单位 |
.ray | Ray | 用于进行光线投射的Ray(射线) |
方法
函数名 | 参数 | 描述 | 返回值 | 说明 |
---|---|---|---|---|
.set | origin : Vector3 | 光线投射的原点向量 | undefined | 使用新的原点和方向更新射线 |
direction : Vector3 | 标准化方向向量 | |||
.setFromCamera | coords : Vector2 | 标准化设备坐标中的鼠标二维坐标(X/Y应在-1到1之间) | undefined | 根据相机和屏幕坐标更新射线 |
camera : Camera | 射线来源的摄像机 | |||
.setFromXRController | controller : WebXRController | 要复制位置和方向的WebXR控制器 | this | 从XR控制器更新射线 |
.intersectObject | object : Object3D | 要检测相交的3D对象 | Array<Intersection> | 检测射线与单个对象的相交情况 |
recursive : Boolean | 是否检测所有后代(默认true) | 返回相交结果数组,按距离排序 | ||
optionalTarget : Array | (可选)目标数组容器 | |||
.intersectObjects | objects : Array<Object3D> | 要检测的3D对象数组 | Array<Intersection> | 检测射线与多个对象的相交情况 |
recursive : Boolean | 是否检测所有后代(默认true) | 返回相交结果数组,按距离排序 | ||
optionalTarget : Array | (可选)目标数组容器 |
Intersection 类型定义:
interface Intersection {distance: number; // 射线起点到交点的距离point: Vector3; // 交点世界坐标face: Face3 | null; // 相交的三角面对象(可能为null)faceIndex: number; // 相交面的索引号object: Object3D; // 被相交的3D对象uv: Vector2; // 交点的UV纹理坐标uv1?: Vector2; // (可选)交点的第二套UV坐标normal: Vector3; // 交点处的插值法向量instanceId?: number; // (可选)InstancedMesh实例的ID
}
I说明:
- Three.js 通过多态机制(不同对象实现自己的 raycast)实现灵活的相交检测。Raycaster 不会直接计算相交,而是调用每个物体自己的 raycast 方法。不同几何体类型(Mesh/Line/Points)有各自不同的相交检测实现。Mesh 会检测三角面相交,Line 会检测线段邻近点,Points 会检测点云中的点,它们的相交计算逻辑和阈值判断都不同。
- 默认情况下,Three.js 只检测射线从正面(法线朝向射线原点的一面)穿过网格面的情况。如果射线从背面(法线背向的一面)穿过,在材质中设置 side: THREE.DoubleSide 可启用双面检测。
代码
const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();
function onPointerMove( event ) {// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1;pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
function render() {// 通过摄像机和鼠标位置更新射线raycaster.setFromCamera( pointer, camera );// 计算物体和射线的焦点const intersects = raycaster.intersectObjects( scene.children );for ( let i = 0; i < intersects.length; i ++ ) {intersects[ i ].object.material.color.set( 0xff0000 );}renderer.render( scene, camera );
}
window.addEventListener( 'pointermove', onPointerMove );
window.requestAnimationFrame(render);