Raycaster not working correctly with pointsGeometry

import React, { useLayoutEffect, useRef } from ‘react’
import * as THREE from ‘three’
import { OrbitControls } from ‘three/examples/jsm/controls/OrbitControls.js’
import * as dat from ‘dat.gui’;
import { GLTFLoader } from ‘three/addons/loaders/GLTFLoader.js’;
import { RGBELoader } from “three/examples/jsm/loaders/RGBELoader”;
import { MeshSurfaceSampler } from “three/examples/jsm/math/MeshSurfaceSampler”;
import * as CANNON from “cannon-es”
import “./App.css”
const App = () => {
useLayoutEffect(() => {
const gui = new dat.GUI()
const loader = new GLTFLoader();
const canvas = document.querySelector(‘canvas.webgl’)
const scene = new THREE.Scene()
// scene.background = new THREE.Color(0x000ff);
const textureLoader = new THREE.TextureLoader();
const envirnment = (“/env.hdr”)
const rotationSpeed = 0.005;
const movementSpeed = 0.0002;

let sampler
let pointsGeometry = new THREE.BufferGeometry()
const vertices = []
const tempPosition = new THREE.Vector3();
let pointPositions = [];
let points;
const pointer = new THREE.Vector2();
const raycaster = new THREE.Raycaster();
const intersectionThreshold = 0.1;

const cursor = new THREE.Vector2();
const floatingAmplitude = 1.5; // Adjust this to control the float height
const floatingSpeed = 1;

loader.load('/mesh3.glb', function (gltf) {
  const model = gltf.scene;
  gltf.scene.traverse((obj) => {
    if (obj.isMesh) {
      sampler = new MeshSurfaceSampler(obj).build()
    }
  })
  model.scale.set(0.1, 0.1, 0.1);

  for (let i = 0; i < 9; i++) {
    sampler.sample(tempPosition)
    vertices.push(tempPosition.x, tempPosition.y, tempPosition.z);
    pointPositions.push(tempPosition.clone());
  }

  pointsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3))

  const pointsMaterial = new THREE.PointsMaterial({
    color: 0xfff0f0f,
    size: 0.04,
    blending: THREE.AdditiveBlending,
    uniforms: {
      mousePosition: { type: "v2", value: new THREE.Vector2() },
    },
    transparent: true,
    opacity: 0.4,
  })

  points = new THREE.Points(pointsGeometry, pointsMaterial);
  points.name = 'myPoints';
  points.position.set(0, -1, -1);
  points.scale.set(0.01, 0.01, 0.01);
  scene.add(points)

  renderer.render(scene, camera)
  console.log("model Loaded");

}, undefined, function (error) {
  console.error(error);
});



function getPointPositions() {
  const positions = [];

  for (let i = 0; i < pointsGeometry.attributes.position.count; i++) {
    const vertex = new THREE.Vector3();
    vertex.fromBufferAttribute(pointsGeometry.attributes.position, i);
    positions.push({ x: vertex.x, y: vertex.y });
  }
  return positions;
}



function RaycasterOnMouseDown(event) {
  event.preventDefault();
  cursor.x = ((event.clientX + canvas.offsetLeft) / canvas.width) * 2 - 1;
  cursor.y = -((event.clientY - canvas.offsetTop) / canvas.height) * 2 + 1;
  // console.log("x : " + cursor.x + " y : " + cursor.y);
  raycaster.setFromCamera(cursor, camera);
  var intersects = raycaster.intersectObjects(scene.children, true);

  if (intersects.length > 0) {
      console.log(intersects);
  }
}


const boxGeometry = new THREE.BoxGeometry(0.1,0.1,0.1);
const boxMaterial = new THREE.MeshStandardMaterial();
const box = new THREE.Mesh(boxGeometry,boxMaterial);

scene.add(box);





function createParticleSystem(model) {
  const particles = new THREE.Group();
  const numParticles = 50;

  for (let i = 0; i < numParticles; i++) {
    const instance = model.clone();

    const scale = Math.random() * 0.1 + 0.01;
    instance.scale.set(scale, scale, scale);

    const rotationX = Math.random() * Math.PI * 2;
    const rotationY = Math.random() * Math.PI * 2;
    const rotationZ = Math.random() * Math.PI * 2;
    instance.rotation.set(rotationX, rotationY, rotationZ);

    const position = new THREE.Vector3(
      Math.random() * 15 - 7.5,
      Math.random() * 10 - 5,
      -3
    );
    instance.position.copy(position);

    particles.add(instance);
  }

  return particles;
}


loader.load('/cone-green.glb', function (gltf) {
  const model = gltf.scene;
  model.traverse((node) => {
    if (node.isMesh) {
      node.castShadow = true;
      node.name = 'cone-green';
    }
  });
  const particles = createParticleSystem(model);
  scene.add(particles);
}, undefined, function (error) {
  console.error(error);
});

loader.load('/cone-yellow.glb', function (gltf) {
  const model = gltf.scene;
  model.traverse((node) => {
    if (node.isMesh) {
      node.castShadow = true;
      node.name = 'cone-yellow'; // Set a name for identification
    }
  });
  const particles = createParticleSystem(model);
  scene.add(particles);
}, undefined, function (error) {
  console.error(error);
});

loader.load('/cone-violet1.glb', function (gltf) {
  const model = gltf.scene;
  model.traverse((node) => {
    if (node.isMesh) {
      node.castShadow = true;
      node.name = 'cone-violet'; // Set a name for identification
    }
  });
  const particles = createParticleSystem(model);
  scene.add(particles);
}, undefined, function (error) {
  console.error(error);
});




const sizes = {
  width: window.innerWidth,
  height: window.innerHeight
}


const blurPlaneGeometry = new THREE.PlaneGeometry(sizes.width, sizes.height);
const blurPlaneMaterial = new THREE.MeshStandardMaterial({
  transparent: true,
  opacity: 7,
  color: new THREE.Color(0, 0, 0),
  metalness: 0,
  clearcoat: 1,
  clearcoatRoughness: 0.1,
  transmission: 1,
});
const blurPlaneMesh = new THREE.Mesh(blurPlaneGeometry, blurPlaneMaterial);
blurPlaneMesh.position.z = -2.5
scene.add(blurPlaneMesh)


window.addEventListener('resize', () => {
  sizes.width = window.innerWidth
  sizes.height = window.innerHeight

  camera.aspect = sizes.width / sizes.height
  camera.updateProjectionMatrix()

  renderer.setSize(sizes.width, sizes.height)
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})


const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
camera.position.x = 0
camera.position.y = 0
camera.position.z = 1
scene.add(camera)


const controls = new OrbitControls(camera, canvas)


const renderer = new THREE.WebGLRenderer({
  canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))


renderer.outputEncoding = THREE.sRGBEncoding;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.8;


const rgbeLoader = new RGBELoader();
rgbeLoader.load(envirnment, function (texture) {
  texture.mapping = THREE.EquirectangularReflectionMapping
  // scene.background = texture;
  scene.environment = texture;
});

let mouseX = 0;
let mouseY = 0;

function onMouseMove(event) {
  mouseX = (event.clientX / window.innerWidth) * 2 - 1;
  mouseY = (event.clientY / window.innerHeight) * 2 - 1;
}


window.addEventListener('mousemove', onMouseMove, false);
canvas.addEventListener('click', RaycasterOnMouseDown, false);
// window.addEventListener('mousemove',()=>{
//   console.log(pointsGeometry.attributes);
// })


function updateCameraPosition() {
  const maxCameraOffset = 0.3;
  const targetX = mouseX * maxCameraOffset;
  const targetY = mouseY * (maxCameraOffset - 0.4);
  camera.position.x = targetX;
  camera.position.y = targetY;
}






const clock = new THREE.Clock()
let moveRight = true;





const tick = () => {
  const elapsedTime = clock.getElapsedTime();
  // updateCameraPosition();
  if (points) {
    const pointPositions = getPointPositions();
  }

  const time = performance.now() * 0.001;


  // if (points) {
  //   for (let i = 0; i < pointsGeometry.attributes.position.count; i++) {
  //     const vertex = new THREE.Vector3();
  //     vertex.fromBufferAttribute(pointsGeometry.attributes.position, i);
  //     vertex.y = pointPositions[i].y + Math.sin(time * floatingSpeed + i) * floatingAmplitude;
  //     pointsGeometry.attributes.position.setXYZ(i, vertex.x, vertex.y, vertex.z);
  //   }
  //   pointsGeometry.attributes.position.needsUpdate = true;
  // }

  scene.traverse((object) => {
    if (object.isMesh && object.name.includes('cone')) {
      object.rotation.x += rotationSpeed;
      object.rotation.y += rotationSpeed;
    }
  });

  scene.traverse((object) => {
    if (object.isMesh && object.name.includes('cone')) {
      if (moveRight) {
        object.position.x += Math.sin(elapsedTime * movementSpeed) * 0.05;
      } else {
        object.position.x -= Math.sin(elapsedTime * movementSpeed) * 0.05;
      }

      if (object.position.x >= 2) {
        moveRight = false;
      } else if (object.position.x <= -2) {
        moveRight = true;
      }
    }
  });
  renderer.render(scene, camera)
  window.requestAnimationFrame(tick)
}
tick()

}, )

return (




)
}

export default App

https://codesandbox.io/p/github/Unnikrishnan46/Three.js/main?file=%2Fsrc%2FApp.jsx%3A1%2C1&layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clmkl5msu000i356fyc86gt7s%2522%252C%2522sizes%2522%253A%255B100%252C0%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clmkl5mst000e356fbvq28sk2%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clmkl5mst000g356fjs76lq8i%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clmkl5msu000h356fcwb1s342%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clmkl5mst000e356fbvq28sk2%2522%253A%257B%2522id%2522%253A%2522clmkl5mst000e356fbvq28sk2%2522%252C%2522activeTabId%2522%253A%2522clmkl8nu000rp356fivixgvxv%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clmkl5mst000d356fxc6380be%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252FREADME.md%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%252C%257B%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252Fsrc%252FApp.jsx%2522%252C%2522id%2522%253A%2522clmkl8nu000rp356fivixgvxv%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%257D%252C%2522clmkl5msu000h356fcwb1s342%2522%253A%257B%2522id%2522%253A%2522clmkl5msu000h356fcwb1s342%2522%252C%2522activeTabId%2522%253A%2522clmkl5uhe00lh356fy4111hbf%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522TASK_PORT%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522port%2522%253A5173%252C%2522id%2522%253A%2522clmkl5uhe00lh356fy4111hbf%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522path%2522%253A%2522%252F%2522%257D%255D%257D%252C%2522clmkl5mst000g356fjs76lq8i%2522%253A%257B%2522id%2522%253A%2522clmkl5mst000g356fjs76lq8i%2522%252C%2522activeTabId%2522%253A%2522clmkl5mst000f356fdrvfl5zr%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clmkl5mst000f356fdrvfl5zr%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522TERMINAL%2522%252C%2522shellId%2522%253A%2522clmkl5myl001de7i2hr3a5anc%2522%257D%252C%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522id%2522%253A%2522clmkl5sf600fx356fcblvmwhj%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%255D%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Afalse%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D

Without a live debuggable example it is hard to guess.

My best guess is related to raycasting threshold:

  • in the code there is a constant intersectionThreshold, which is never used
  • raycasting expects threshold in params.Points.threshold, which is also not use in the code

As this is R3F and I do not work with it, there might some other problems too.

https://codesandbox.io/p/github/Unnikrishnan46/Three.js/main?file=%2Fsrc%2FApp.jsx%3A1%2C1&layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clmkl5msu000i356fyc86gt7s%2522%252C%2522sizes%2522%253A%255B100%252C0%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clmkl5mst000e356fbvq28sk2%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clmkl5mst000g356fjs76lq8i%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clmkl5msu000h356fcwb1s342%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clmkl5mst000e356fbvq28sk2%2522%253A%257B%2522id%2522%253A%2522clmkl5mst000e356fbvq28sk2%2522%252C%2522activeTabId%2522%253A%2522clmkl8nu000rp356fivixgvxv%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clmkl5mst000d356fxc6380be%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252FREADME.md%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%252C%257B%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252Fsrc%252FApp.jsx%2522%252C%2522id%2522%253A%2522clmkl8nu000rp356fivixgvxv%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%257D%252C%2522clmkl5msu000h356fcwb1s342%2522%253A%257B%2522id%2522%253A%2522clmkl5msu000h356fcwb1s342%2522%252C%2522activeTabId%2522%253A%2522clmkl5uhe00lh356fy4111hbf%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522TASK_PORT%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522port%2522%253A5173%252C%2522id%2522%253A%2522clmkl5uhe00lh356fy4111hbf%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522path%2522%253A%2522%252F%2522%257D%255D%257D%252C%2522clmkl5mst000g356fjs76lq8i%2522%253A%257B%2522id%2522%253A%2522clmkl5mst000g356fjs76lq8i%2522%252C%2522activeTabId%2522%253A%2522clmkl5mst000f356fdrvfl5zr%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clmkl5mst000f356fdrvfl5zr%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522TERMINAL%2522%252C%2522shellId%2522%253A%2522clmkl5myl001de7i2hr3a5anc%2522%257D%252C%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522id%2522%253A%2522clmkl5sf600fx356fcblvmwhj%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%255D%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Afalse%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D