首页 > 解决方案 > 三个raycaster,为什么我必须使用索引零?

问题描述

我试图获取在使用 raycaster 时与鼠标光标交叉的粒子的索引。但是,当我记录相交时,即使我只遇到一个点,它也会返回数百万个对象。

只有当我使用 intersects 数组的索引零时,我才能访问完全匹配。

而且我必须通过 params.points.threshold 才能获得相交。为了测试,我将 0.1 作为实验。但我不太清楚它的含义。

有谁知道原因?

我的代码如下。

  1. 设置 raycaster 并传入阈值参数。

     const raycaster = new THREE.Raycaster();
     raycaster.params.Points.threshold = 0.01;
    
  2. 为我的几何体设置着色器

     const waterGeometry = new THREE.PlaneGeometry(2, 2, 128, 128)
    
     // Material
     const waterMaterial = new THREE.ShaderMaterial({
         // wireframe: true,
         vertexShader: waterVertex,
         fragmentShader: waterFragmentShader,
         uniforms: {
         uBigWavesElevation: { value: 0.2 },
         uBigWavesFrequency: { value: new THREE.Vector2(4, 1.5) },
         uTime: { value: 0 },
         uBigWavesSpeed: { value: 0.75 }
     }
     })
    
  3. 设置包含我的几何图形的点的大小

     let { count } = waterGeometry.attributes.position
    
     let scales = new Float32Array(count);
    
     for (let i = 0; i < count; i++) {
         scales[i] = 0.1;
     };
     waterGeometry.setAttribute('scale', new BufferAttribute(scales, 1))
     const water = new THREE.Points(waterGeometry, waterMaterial)
    
  4. 定义高亮功能

     function mouseHighlight() {
         raycaster.setFromCamera(mouse, camera)
     const intersects = raycaster.intersectObjects([water]);
     if (intersects[0] != undefined) {
    
         for (let i = 0; i < count; i++) {
             if (i != scales[intersects[0].index]) {
                 scales[i] = 0.1;
             }
         }
    
         console.log(intersects[0].index);
         scales[intersects[0].index] = 0.5;
         waterGeometry.attributes.scale.needsUpdate = true;
    
    
     }
    
     }
    
  5. 我真的不明白的部分

const intersects = raycaster.intersectObjects([水]);

为了明白这一点,我必须选择相交的第一个元素。这让我很困惑,因为对我来说,相交意味着相交的对象。所以没有必要选择相交对象的第一个元素。但我不得不这样做。为什么?

    console.log(intersects[0].index);
    scales[intersects[0].index] = 0.5;

标签: three.js

解决方案


APoint在 3D 空间中没有体积,即使它在渲染时看起来也一样。它实际上是空间中的一个点,没有维度。

交互式定义的射线击中空间中的单个点的机会非常小。因此,您需要一个阈值来说明Raycaster您希望交叉点对点的“模糊”程度。根据文档,此阈值以世界单位为单位

现在,基于此,您的阈值应该足够小以在您定义的空间内选择点,而不会返回大量它们。但是,如果这不起作用,那么我建议在您的问题中添加一个最小的可重现示例,其中的点数、标准材料等要少得多。


推荐阅读