I have 3 components, App, SpecialCamera, Mouselight.
In the Mouselight I calculate the mouse position in relation to the Camera and want to position the Spotlight where the mouse is.
function MouseLight({camRef}){
const [globalCoords, setGlobalCoords] = useState({x: 0, y: 0});
useEffect(() => {
// 👇️ get global mouse coordinates
const handleWindowMouseMove = event => {
setGlobalCoords({
x: event.screenX,
y: event.screenY,
});
};
window.addEventListener('mousemove', handleWindowMouseMove);
return () => {
window.removeEventListener('mousemove', handleWindowMouseMove);
};
}, []);
const ref = useRef();
useFrame(x=>{
ref.current.position.z +=0.01;
})
const [pos, setPos] = useState();
useEffect(() => {
console.log(camRef, ref)
var vector = new Vector3(globalCoords.x, globalCoords.y, 0.5);
vector.unproject( camRef.current );
var dir = vector.sub( camRef.current.position ).normalize();
var distance = - camRef.current.position.z / dir.z;
var pos = camRef.current.position.clone().add( dir.multiplyScalar( distance ) );
setPos(pos);
}, [globalCoords])
return (
<spotLight ref={ref}
color={[1, 0, 0]}
intensity={5}
angle={0.6}
penumbra={0.5}
position={pos}
castShadow
shadow-bias={-0.001}
/>)
}
function VerySpecialCamera({camRef}){
return <PerspectiveCamera ref={camRef} makeDefault fov={50} position={[3, 2, 5]} />
}
function App() {
return (
<Suspense fallback={null}>
<Canvas shadows>
<VerySpecialCamera camRef={camRef}></VerySpecialCamera>
<Ground/>
<MouseLight/>
</Canvas>
</Suspense>
);
}
Is this the right way to do such a thing? Currently the position of the light is somehow affected, but it is not really following the mouse over the surface ground.