solid-three ships custom raycasters that decide how a pointer becomes a ray. They all extend THREE.Raycaster and implement EventRaycaster, which adds one method:
| Method | Description |
|---|---|
cast(registry, context) | Aim the ray for the current pointer, then return its hits against registry and its descendants (honoring raycastable !== false), nearest-first. |
The pointer system calls cast() on every event. How the ray is aimed is the raycaster's own business — from the camera and a cursor position for screen pointers, or from an object's world transform for an XR controller.
Screen-pointer raycasters also implement ScreenRaycaster, which adds setCursor(ndc). The pointer system calls it with the cursor in normalized device coordinates before each cast().
Exact types
interface EventRaycaster extends THREE.Raycaster { cast(registry: Object3D[], context: Context): Intersection[]}
interface ScreenRaycaster extends EventRaycaster { setCursor(ndc: Vector2): void}CursorRaycaster
The default. Tracks the cursor and casts from the active camera.
import { Canvas, CursorRaycaster } from "solid-three"
const App = () => { // CursorRaycaster is the default; pass it explicitly only to swap or configure. return <Canvas raycaster={new CursorRaycaster()}>{/* Your scene */}</Canvas>}CenterRaycaster
Ignores the cursor and always casts from the centre of the screen — useful for gaze or crosshair interaction.
import { Canvas, CenterRaycaster } from "solid-three"
const App = () => <Canvas raycaster={new CenterRaycaster()}>{/* Your scene */}</Canvas>ControllerRaycaster
Casts from an Object3D's world transform — origin at its world position, direction along its local −Z. This is the ray strategy for an XR controller; see createXR.
import { ControllerRaycaster } from "solid-three"
const raycaster = new ControllerRaycaster(controllerSpace)Creating your own
For a screen pointer, the simplest path is to subclass CursorRaycaster and reshape the cursor — cast() is inherited:
import { Vector2 } from "three"import { Canvas, CursorRaycaster } from "solid-three"
// Damp pointer movement to half speed.class DampedRaycaster extends CursorRaycaster { setCursor(ndc: Vector2) { super.setCursor(new Vector2(ndc.x * 0.5, ndc.y * 0.5)) }}
const App = () => <Canvas raycaster={new DampedRaycaster()}>{/* Your scene */}</Canvas>For a non-screen ray — a custom origin and direction — implement cast() directly: aim this.ray from whatever transform you like, then return this.intersectObjects(registry, true). ControllerRaycaster is the reference implementation.
See also
- Events overview — how and when
cast()is called. useThree—raycaster/setRaycasterfor swapping the active raycaster at runtime.
Last updated: 6/8/26, 11:20 AM